77
88
99[section:http HTTP]
10- The __cnl__ provides direct support for HTTP. As a motivating
11- example, here is the code again from the __quick_start__.
1210
13- #include <boost/network/protocol/http.hpp>
11+ [section:http_server_example HTTP Server]
12+
13+ Here is the server code again from the __quick_start__.
14+
15+ ``
16+ #include <boost/network/protocol/http/server.hpp>
1417 #include <iostream>
18+
19+
20+ namespace http = boost::network::http;
21+
22+
23+ struct hello_world;
24+ typedef http::server<hello_world> server;
25+
26+ struct hello_world {
27+ void operator() (server::request const &request,
28+ server::response &response) {
29+ response = server::response::stock_reply(
30+ server::response::ok, "Hello, World!");
31+ }
32+ void log(...) {
33+ // do nothing
34+ }
35+ };
36+
37+
38+ int main(int argc, char * argv[]) {
39+
40+ if (argc != 3) {
41+ std::cerr << "Usage: " << argv[0] << " address port" << std::endl;
42+ return 1;
43+ }
44+
45+ try {
46+ hello_world handler;
47+ http::server<hello_world> server_(argv[1], argv[2], handler);
48+ server_.run();
49+ }
50+ catch (std::exception &e) {
51+ std::cerr << e.what() << std::endl;
52+ return 1;
53+ }
54+
55+ return 0;
56+ }
57+ ``
58+
59+ [heading HTTP Server]
60+
61+ namespace boost { namespace network { namespace http {
62+ template <class Tag, class Handler> class basic_server;
63+ }}}
64+
65+ The `server` encapsulates the server side connections, manages the
66+ incoming data and can be configured to handle incoming requests.
67+
68+ [heading HTTP Request Handler]
69+
70+ struct hello_world {
71+ void operator() (server::request const &request,
72+ server::response &response) {
73+ response = server::response::stock_reply(
74+ server::response::ok, "Hello, World!");
75+ }
76+ void log(...) {
77+ // do nothing
78+ }
79+ };
1580
81+ The request handler is a functor class that accepts as an argument an
82+ incoming request and an outgoing response. An additional `log` member
83+ function is also required to be defined.
84+
85+ [heading Running the Server]
86+
87+ hello_world handler;
88+ http::server<hello_world> server_(argv[1], argv[2], handler);
89+ server_.run();
90+
91+ The `hello_world` request handler is given as a template argument to
92+ `http::server`. The first two constructor arguments are the address
93+ and port, and the `hello_world` handler object is passed as the third
94+ argument.
95+
96+ [endsect] [/ http_server_example]
97+
98+ [section:http_client_example HTTP Client]
99+
100+ Here is the client code again from the __quick_start__.
101+
102+ ``
103+ #include <boost/network/protocol/http/client.hpp>
104+ #include <iostream>
105+
106+
107+ namespace http = boost::network::http;
108+
109+
16110 int
17111 main(int argc, char *argv[]) {
18- using boost::network;
19-
20- http::request request("http://www.boost.org/");
21- http::client client;
22- http::response response = client.get(request);
23-
24- // print response headers
25- headers_range<http::response>::type hdrs = headers(response);
26- boost::range_iterator<headers_range<http::response>::type>::type
27- it = boost::begin(hdrs), end = boost::end(hdrs);
28- for (; it != end; ++it) {
29- std::cout << it->first << ": " << it->second << std::endl;
112+ if (argc != 2) {
113+ std::cerr << "Usage: " << argv[0] << " url" << std::endl;
114+ return 1;
30115 }
31-
32- // print response body
33- std::cout << body(response) << std::endl;
116+
117+ try {
118+ http::client client;
119+ http::client::request request(argv[1]);
120+ http::client::response response = client.get(request);
121+ std::cout << boost::network::body(response) << std::endl;
122+ }
123+ catch (std::exception &e) {
124+ std::cerr << e.what() << std::endl;
125+ return 1;
126+ }
127+
34128 return 0;
35129 }
130+ ``
36131
37132Before walking through exactly what is happening in this example, the
38- principle components are described below:
133+ principal components are described below:
39134
40135[heading HTTP Request]
41136
@@ -44,7 +139,7 @@ principle components are described below:
44139 typedef basic_request<tags::default_> request;
45140 }}}
46141
47- The[^ request] encapsulates information about the request and the
142+ The` request` encapsulates information about the request and the
48143resource. It models the Message concept.
49144
50145[heading HTTP Client]
@@ -54,9 +149,9 @@ resource. It models the Message concept.
54149 typedef basic_client<tags::default_> client;
55150 }}}
56151
57- The[^ client] encapsulates the connection-mapping logic between the
152+ The` client` encapsulates the connection-mapping logic between the
58153domain and the underlying socket. Access to a resource is managed
59- through the[^ client] object.
154+ through the` client` object.
60155
61156[heading HTTP Response]
62157
@@ -65,75 +160,69 @@ through the [^client] object.
65160 typedef basic_response<tags::default_> response;
66161 }}}
67162
68- The[^ response] encapsulates the data received from the server. It
163+ The` response` encapsulates the data received from the server. It
69164also models the Message concept.
70165
71- [heading Walkthrough]
72-
73- http::request request("http://www.boost.org/");
74-
75- This line frames the request for the resource __boost_org__.
166+ [heading HTTP Client Walkthrough]
76167
77168 http::client client;
78169
79170Then a client object is created that handles all HTTP requests and
80171responses.
81172
173+ http::request request(argv[1]);
174+
175+ This line frames the request for the resource given as a command line
176+ argument.
177+
82178 http::response response = client.get(request);
83179
84180The client simply performs the requests. The interface is trivially
85181easy. All HTTP methods are supported (HEAD, GET, POST, PUT, DELETE).
86182
87183There are several advantages to this design:
88184
89- # A[^ client] object manages the connection, unencumbering the
185+ # A` client` object manages the connection, unencumbering the
90186 developer with this task;
91- # A[^ request] can be used with any instance of the[^ client] without
92- binding the[^ client] to any destination;
93- # By decoupling the method from the[^ request] object it allows
187+ # A` request` can be used with any instance of the` client` without
188+ binding the` client` to any destination;
189+ # By decoupling the method from the` request` object it allows
94190 developers to create requests that may be re-used (e.g. perform a
95191 HEAD first; if the the headers don't fulfil a certain criteria,
96192 perform a GET using the same resource).
97193
98- // print response headers
99- headers_range<http::response>::type hdrs = headers(response);
100- boost::range_iterator<headers_range<http::response>::type>::type
101- it = boost::begin(hdrs), end = boost::end(hdrs);
102- for (; it != end; ++it)
103- std::cout << it->first << ": " << it->second << std::endl;
104- }
105-
106- // print response body
107194 std::cout << body(response) << std::endl;
108195
109- Once the request has been made, and the[^ client] returns a
110- [^ response] object, the rest is simple. This example outputs all the
111- responseheaders and body, in this case just the Boost homepage .
196+ Once the request has been made, and the` client` returns a
197+ ` response` object, the rest is simple. This example outputs the
198+ response body.
112199
113- [heading Using[^ http::client] ]
200+ [heading Using` http::client` ]
114201
115- The[^ http::client] supports the following operations:
202+ The` http::client` supports the following operations:
116203
117- *[^ http::client::head]
118- *[^ http::client::get]
119- *[^ http::client::post]
120- *[^ http::client::put]
121- *[^ http::client::delete_]
204+ *` http::client::head`
205+ *` http::client::get`
206+ *` http::client::post`
207+ *` http::client::put`
208+ *` http::client::delete_`
122209
123210HTTP features can be enabled by using constructor arguments:
124211
125- *[^ http::client(http::client::cache_resolved)]
126- *[^ http::client(http::client::follow_redirect)]
212+ *` http::client(http::client::cache_resolved)`
213+ *` http::client(http::client::follow_redirect)`
127214
128- [h5[^ http::client::cache_resolved] ]
215+ [h5` http::client::cache_resolved` ]
129216This argument enables the caching of resolved endpoints and prevents
130217the client from resolving IP addresses of previously resolved
131218hostnames.
132219
133- [h5[^ http::client::follow_redirect(s)] ]
134- [^ http::client::follow_redirects] /[^ http::client::follow_redirect]
220+ [h5` http::client::follow_redirect(s)` ]
221+ ` http::client::follow_redirects` /` http::client::follow_redirect`
135222follow HTTP redirect(s) (300..307) by looking at the "Location" header
136223provided by the response(s); headers present in the original request
137224are preserved in the subsequent request(s).
138225
139- [endsect] [/http]
226+ [endsect] [/ http_client_example]
227+
228+ [endsect] [/ http]