7
7
8
8
9
9
[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__.
12
10
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>
14
17
#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
+ };
15
80
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
+
16
110
int
17
111
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;
30
115
}
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
+
34
128
return 0;
35
129
}
130
+ ``
36
131
37
132
Before walking through exactly what is happening in this example, the
38
- principle components are described below:
133
+ principal components are described below:
39
134
40
135
[heading HTTP Request]
41
136
@@ -44,7 +139,7 @@ principle components are described below:
44
139
typedef basic_request<tags::default_> request;
45
140
}}}
46
141
47
- The [^ request] encapsulates information about the request and the
142
+ The ` request` encapsulates information about the request and the
48
143
resource. It models the Message concept.
49
144
50
145
[heading HTTP Client]
@@ -54,9 +149,9 @@ resource. It models the Message concept.
54
149
typedef basic_client<tags::default_> client;
55
150
}}}
56
151
57
- The [^ client] encapsulates the connection-mapping logic between the
152
+ The ` client` encapsulates the connection-mapping logic between the
58
153
domain and the underlying socket. Access to a resource is managed
59
- through the [^ client] object.
154
+ through the ` client` object.
60
155
61
156
[heading HTTP Response]
62
157
@@ -65,75 +160,69 @@ through the [^client] object.
65
160
typedef basic_response<tags::default_> response;
66
161
}}}
67
162
68
- The [^ response] encapsulates the data received from the server. It
163
+ The ` response` encapsulates the data received from the server. It
69
164
also models the Message concept.
70
165
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]
76
167
77
168
http::client client;
78
169
79
170
Then a client object is created that handles all HTTP requests and
80
171
responses.
81
172
173
+ http::request request(argv[1]);
174
+
175
+ This line frames the request for the resource given as a command line
176
+ argument.
177
+
82
178
http::response response = client.get(request);
83
179
84
180
The client simply performs the requests. The interface is trivially
85
181
easy. All HTTP methods are supported (HEAD, GET, POST, PUT, DELETE).
86
182
87
183
There are several advantages to this design:
88
184
89
- # A [^ client] object manages the connection, unencumbering the
185
+ # A ` client` object manages the connection, unencumbering the
90
186
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
94
190
developers to create requests that may be re-used (e.g. perform a
95
191
HEAD first; if the the headers don't fulfil a certain criteria,
96
192
perform a GET using the same resource).
97
193
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
107
194
std::cout << body(response) << std::endl;
108
195
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
- response headers 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.
112
199
113
- [heading Using [^ http::client] ]
200
+ [heading Using ` http::client` ]
114
201
115
- The [^ http::client] supports the following operations:
202
+ The ` http::client` supports the following operations:
116
203
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_`
122
209
123
210
HTTP features can be enabled by using constructor arguments:
124
211
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)`
127
214
128
- [h5 [^ http::client::cache_resolved] ]
215
+ [h5 ` http::client::cache_resolved` ]
129
216
This argument enables the caching of resolved endpoints and prevents
130
217
the client from resolving IP addresses of previously resolved
131
218
hostnames.
132
219
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`
135
222
follow HTTP redirect(s) (300..307) by looking at the "Location" header
136
223
provided by the response(s); headers present in the original request
137
224
are preserved in the subsequent request(s).
138
225
139
- [endsect] [/http]
226
+ [endsect] [/ http_client_example]
227
+
228
+ [endsect] [/ http]
0 commit comments