MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/http/request.hpp
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