@@ -4,49 +4,128 @@ HTTP implementation
44HTTP client
55```````````
66
7- The cpp-netlib HTTP client is composed of three template classes:
7+ At the heart of the HTTP client implementation is a single class aptly named
8+ ``basic_client ``, which is also a template. The template ``basic_client `` takes
9+ three template parameters:
810
911..code-block ::c++
1012
11- namespace http {
12- template <class Tag> basic_request;
13- template <class Tag> basic_response;
14- template <class Tag> basic_client;
15- typedef basic_request<default _> request;
16- typedef basic_response<default _> response;
17- typedef basic_client<default _> client;
18- }
13+ namespace boost { namespace http {
14+
15+ template <class Tag, unsigned version_major, unsigned version_minor>
16+ struct basic_client;
17+
18+ } // namespace http
19+
20+ } // namespace boost
21+
22+ The ``Tag `` template parameter follows the same tag-dispatch mechanism to
23+ determine the behavior of the ``basic_client ``. The interface of
24+ ``basic_client `` may change depending on certain properties defined for the tag
25+ you provide. Below is a table of predefined supported tags you can use in your
26+ overload of the ``basic_client ``:
27+
28+
29+ +---------------------------------+---------------------------------------------+
30+ | Tag| Description|
31+ +=================================+=============================================+
32+ | http_default_8bit_tcp_resolve| This is the default HTTP implementation tag|
33+ | | that resolves addresses with a TCP resolver|
34+ | | and provides a synchronous/blocking HTTP|
35+ | | client interface.|
36+ +---------------------------------+---------------------------------------------+
37+ | http_default_8bit_udp_resolve| This is similar to the above tag except that|
38+ | | it specifies the HTTP client to use a UDP|
39+ | | resolver. It also provides a synchronous/|
40+ | | blocking HTTP client interface.|
41+ +---------------------------------+---------------------------------------------+
42+ | http_keepalive_8bit_tcp_resolve| This tag specifies that the HTTP client by|
43+ | | default will keep connections to the server|
44+ | | alive. It only makes sense if the|
45+ | | ``version_major `` and ``version_minor `` are|
46+ | | both ``1 ``, to indicate HTTP 1.1. This tag|
47+ | | causes the HTTP client to resolve using a|
48+ | | TCP resolver and provides a synchronous/|
49+ | | blocking HTTP client interface.|
50+ +---------------------------------+---------------------------------------------+
51+ | http_keepalive_8bit_udp_resolve| This is similar to the above tag except that|
52+ | | it specifies the HTTP client to use a UDP|
53+ | | resolver. It also provides a synchronous/|
54+ | | blocking HTTP client interface.|
55+ +---------------------------------+---------------------------------------------+
56+ | http_async_8bit_tcp_resolve| This tag provides an active HTTP client|
57+ | | object implementation that uses a TCP|
58+ | | resolver. Response objects returned will|
59+ | | encapsulate a number ofBoost.Thread _|
60+ | | shared futures to hold values. Users don't|
61+ | | have to see this as they are implementation|
62+ | | details.|
63+ +---------------------------------+---------------------------------------------+
64+ | http_async_8bit_udp_resolve| This is similar to the above tag except that|
65+ | | specifies the HTTP client to use a UDP|
66+ | | resolver.|
67+ +---------------------------------+---------------------------------------------+
68+
69+ .. _Boost.Thread :http://www.boost.org/libs/thread
70+
71+
72+ The default typedef for the HTTP client that is provided uses the
73+ ``http_default_8bit_udp_resolve `` tag, and implements HTTP 1.0. The exact
74+ typedef is in the ``boost::network::http `` namespace as the following:
75+
76+ ..code-block ::c++
77+
78+ namespace boost { namespace network { namespace http {
79+
80+ typedef basic_client<tags::http_default_8bit_udp_resolve, 1, 0>
81+ client;
82+
83+ }}}
84+
85+
86+ This type has nested typedefs for the correct types for the ``basic_request ``
87+ and ``basic_response `` templates. To use the correct types for ``basic_request ``
88+ or ``basic_response `` you can use these nested typedefs like so:
89+
90+
91+ ..code-block ::c++
92+
93+ boost::network::http::client: :request request;
94+ boost::network::http::client: :response response;
95+
96+ // or...
97+ using namespace boost::network;
98+ http::client: :request request;
99+ http::client: :response response;
100+
19101
102+ Typical use cases for the HTTP client would look something like the following:
20103
21- Each of these use again the tag-based static polymorphism that was
22- described in previous sections. A default, human-readable typedef is
23- provided for each one of the ``basic_request ``, ``basic_response `` and
24- ``basic_client ``. ``basic_request `` and ``basic_response `` each model
25- the message concept. They make use of directives to set and get HTTP
26- headers, body etc. The code snippet below shows how to set the HTTP
27- header field "Connection" with the option "close" using the DSEL
28- described in the directives section:
29104
30105..code-block ::c++
31106
32107 using namespace boost::network;
33108 http::request request("http://www.boost.org/");
34109 request << header("Connection", "close");
35110
111+
36112The ``basic_client `` implements all HTTP methods as member functions
37113(HEAD, GET, POST, PUT, DELETE). Therefore, the code to make an HTTP
38114request looks trivially simple:
39115
116+
40117..code-block ::c++
41118
42119 using namespace boost::network;
43120 http::client client;
44121 http::client: :request request("http://www.boost.org/");
45122 http::client: :response response = client.get(request);
46123
47- Accessing data from ``http::response `` is also done using directives.
48- To get the response headers, we use the ``headers `` directive which
49- returns, in the default case, a map of strings to strings:
124+
125+ Accessing data from ``http::response `` is done using wrappers.
126+ To get the response headers, we use the ``headers `` wrapper which
127+ returns, in the default case, a multimap of strings to strings:
128+
50129
51130..code-block ::c++
52131
@@ -60,18 +139,23 @@ returns, in the default case, a map of strings to strings:
60139 }
61140 std::cout << std::endl;
62141
142+
63143HTTP server
64144```````````
65145
66146As with the HTTP client, the HTTP server that is provided with
67147cpp-netlib is extensible through the tag mechanism and is embeddable.
68148The template class declaration of ``basic_server `` is given below:
69149
150+
70151..code-block ::c++
71152
72- namespace http {
73- template <class Tag, class RequestHandler> basic_server;
74- }
153+ namespace boost { namespace network { namespace http {
154+
155+ template <class Tag, class RequestHandler> basic_server;
156+
157+ }}}
158+
75159
76160The second template argument is used to specify the request handler
77161type. The request handler type is a functor type which should overload
@@ -95,18 +179,19 @@ implementation while the user-visible implementation is the
95179
96180..code-block ::c++
97181
98- namespace http {
99- template <
100- class RequestHandler
101- >
102- class server
103- : public basic_server< default _, RequestHandler> {};
104- }
182+ namespaceboost { namespace network { namespace http {
183+
184+ template < class RequestHandler>
185+ class server :
186+ public basic_server< default _, RequestHandler> {};
187+
188+ }}}
105189
106190To use the forwarding server type you just supply the request handler
107191implementation as the parameter. For example, an "echo" server example
108192might look something like this:
109193
194+
110195..code-block ::c++
111196
112197 using namespace boost::network;
@@ -116,15 +201,20 @@ might look something like this:
116201 struct echo {
117202 void operator () (const echo_server::request &request,
118203 echo_server::response &response) const {
204+ std::string ip = source(request);
119205 response = echo_server::response: :stock_reply(
120206 echo_server::response: :ok,
121207body(request));
208+ std::cerr << "[" << ip << "]: " << request.uri <<
209+ " status = " << echo_server::response: :ok << '\n ';
122210 }
123211 };
124212
125213
126214Here, all we're doing is returning the original request body with an
127- HTTP OK response (200).
215+ HTTP OK response (200). We are also printing the IP address from where the
216+ request came from. Notice that we are using a wrapper to access the source of
217+ the request.
128218
129219HTTP URI
130220````````