MACE
1.0.0
|
00001 // 00002 // request.hpp 00003 // ~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 00011 #ifndef MACE_RPC_HTTP_REQUEST_HPP 00012 #define MACE_RPC_HTTP_REQUEST_HPP 00013 00014 #include <string> 00015 #include <vector> 00016 #include <mace/rpc/http/header.hpp> 00017 #include <utility> 00018 #include <boost/utility.hpp> 00019 #include <boost/lexical_cast.hpp> 00020 00021 namespace mace { namespace rpc { namespace http { 00022 00023 class content : boost::noncopyable { 00024 public: 00025 template<typename String> 00026 content( String s ):m_value( std::forward<String>(s) ){} 00027 content(); 00028 00029 content( content&& c ):m_value(std::move(c.m_value)){} 00030 00031 size_t size()const { return m_value.size(); } 00032 const std::string& value()const { return m_value; } 00033 operator std::string()const { return m_value; } 00034 00035 std::string take() { return std::move(m_value); } 00036 00037 private: 00038 std::string m_value; 00039 }; 00040 00042 struct request : boost::noncopyable{ 00043 request() 00044 :keep_alive(true),http_version_major(1),http_version_minor(1){} 00045 00046 request( request&& m ) 00047 :method(std::move(m.method)), 00048 keep_alive(m.keep_alive), 00049 uri( std::move(m.uri) ), 00050 http_version_major(m.http_version_major), 00051 http_version_minor(m.http_version_minor), 00052 headers( std::move(m.headers) ), 00053 content( std::move(m.content) ) {} 00054 00056 std::string method; 00057 00058 bool keep_alive; 00059 00061 std::string uri; 00062 00064 int http_version_major; 00065 00067 int http_version_minor; 00068 00070 std::vector<header> headers; 00071 00073 std::string content; 00074 00075 friend request& operator << ( request& r, const header& h ) { 00076 r.headers.push_back(h); 00077 return r; 00078 } 00079 friend request& operator << ( request& r, header&& h ) { 00080 r.headers.push_back(std::move(h)); 00081 return r; 00082 } 00083 friend request operator << ( request&& r, header&& h ) { 00084 r.headers.push_back(std::move(h)); 00085 return std::move(r); 00086 } 00087 friend request& operator << ( request& r, http::content&& h ) { 00088 r.content += h.take(); 00089 return r; 00090 } 00091 friend request operator << ( request&& r, http::content&& h ) { 00092 r.content += h.take(); 00093 return std::move(r); 00094 } 00095 00096 00097 template<typename Stream> 00098 friend Stream& operator << (Stream& s, const request& r ) { 00099 std::string request_line = r.method + " " + r.uri + " HTTP/"; 00100 request_line += char('0' + r.http_version_major); 00101 request_line += '.'; 00102 request_line += char('0' + r.http_version_minor); 00103 request_line += "\r\n"; 00104 00105 s.write(request_line.c_str(),request_line.size() ); 00106 for( uint32_t i = 0; i < r.headers.size(); ++i ) { 00107 if( r.headers[i].name != "content-length" ){ 00108 s.write(r.headers[i].name.c_str(),r.headers[i].name.size()); 00109 s.write(": ",2); 00110 s.write(r.headers[i].value.c_str(),r.headers[i].value.size()); 00111 s.write("\r\n",2); 00112 } 00113 } 00114 std::string cl; 00115 if( r.content.size() ) 00116 cl = "content-length: " + boost::lexical_cast<std::string>(r.content.size()) + "\r\n"; 00117 cl += "\r\n"; 00118 s.write(cl.c_str(),cl.size()); 00119 s.write(r.content.c_str(), r.content.size() ); 00120 return s; 00121 } 00122 }; 00123 00124 inline request get( const std::string& uri ) { 00125 request r; 00126 r.method = "GET"; 00127 r.uri = uri; 00128 return r; 00129 } 00130 00131 } } } // mace::rpc::http 00132 00133 #endif // MACE_RPC_HTTP_REQUEST_HPP