Skip to content

Commit fb1ad5b

Browse files
committed
Merge branch '0.9-devel' of git://github.com/cpp-netlib/cpp-netlib into 0.9-devel
2 parents ebb1795 + 62e2ad7 commit fb1ad5b

File tree

7 files changed

+119
-11
lines changed

7 files changed

+119
-11
lines changed

boost/network/protocol/http/client/connection/async_normal.hpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,10 @@ namespace boost { namespace network { namespace http { namespace impl {
354354
this->part.begin()
355355
, bytes_transferred
356356
);
357-
this->body_promise.set_value(body_string);
357+
if (this->is_chunk_encoding)
358+
this->body_promise.set_value(parse_chunk_encoding(body_string));
359+
else
360+
this->body_promise.set_value(body_string);
358361
}
359362
// TODO set the destination value somewhere!
360363
this->destination_promise.set_value("");
@@ -428,6 +431,34 @@ namespace boost { namespace network { namespace http { namespace impl {
428431
}
429432
}
430433
}
434+
435+
string_type parse_chunk_encoding( string_type & body_string ) {
436+
string_type body;
437+
string_type crlf = "\r\n";
438+
439+
typename string_type::iterator begin = body_string.begin();
440+
for (typename string_type::iterator iter =
441+
std::search(begin, body_string.end(), crlf.begin(), crlf.end());
442+
iter != body_string.end();
443+
iter = std::search(begin, body_string.end(), crlf.begin(), crlf.end())) {
444+
string_type line(begin, iter);
445+
if (line.empty())
446+
break;
447+
std::stringstream stream(line);
448+
int len;
449+
stream >> std::hex >> len;
450+
std::advance(iter, 2);
451+
if (!len)
452+
break;
453+
if (len <= body_string.end() - iter) {
454+
body.insert(body.end(), iter, iter + len);
455+
std::advance(iter, len);
456+
}
457+
begin = iter;
458+
}
459+
460+
return body;
461+
}
431462

432463
bool follow_redirect_;
433464
resolver_type & resolver_;

boost/network/protocol/http/client/connection/async_protocol_handler.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ namespace boost { namespace network { namespace http { namespace impl {
286286
trim(header_pair.second);
287287
headers.insert(header_pair);
288288
}
289+
// determine if the body parser will need to handle chunked encoding
290+
typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
291+
headers.equal_range("Transfer-Encoding");
292+
is_chunk_encoding = !empty(transfer_encoding_range)
293+
&& boost::iequals(boost::begin(transfer_encoding_range)->second, "chunked");
289294
headers_promise.set_value(headers);
290295
}
291296

@@ -373,6 +378,7 @@ namespace boost { namespace network { namespace http { namespace impl {
373378
buffer_type part;
374379
typename buffer_type::const_iterator part_begin;
375380
string_type partial_parsed;
381+
bool is_chunk_encoding;
376382
};
377383

378384

boost/network/protocol/http/client/facade.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ namespace boost { namespace network { namespace http {
6363
return pimpl->request_skeleton(request, "POST", true, body_handler);
6464
}
6565

66-
response const post(request const &request, body_callback_function callback) {
66+
response const post(request const &request, body_callback_function_type callback) {
6767
return post(request, string_type(), string_type(), callback);
6868
}
6969

70-
response const post(request const &request, string_type const &body, body_callback_function callback) {
70+
response const post(request const &request, string_type const &body, body_callback_function_type callback) {
7171
return post(request, body, string_type(), callback);
7272
}
7373

boost/network/protocol/http/impl/response.ipp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace boost { namespace network { namespace http {
3535
created = 201,
3636
accepted = 202,
3737
no_content = 204,
38+
partial_content = 206,
3839
multiple_choices = 300,
3940
moved_permanently = 301,
4041
moved_temporarily = 302,
@@ -45,10 +46,14 @@ namespace boost { namespace network { namespace http {
4546
not_found = 404,
4647
not_supported = 405,
4748
not_acceptable = 406,
49+
request_timeout = 408,
50+
precondition_failed = 412,
51+
unsatisfiable_range = 416,
4852
internal_server_error = 500,
4953
not_implemented = 501,
5054
bad_gateway = 502,
51-
service_unavailable = 503
55+
service_unavailable = 503,
56+
space_unavailable = 507
5257
} status;
5358

5459
/// The headers to be included in the reply.
@@ -196,6 +201,27 @@ namespace boost { namespace network { namespace http {
196201
"<head><title>Service Unavailable</title></head>"
197202
"<body><h1>503 Service Unavailable</h1></body>"
198203
"</html>";
204+
static const char space_unavailable[] =
205+
"<html>"
206+
"<head><title>Space Unavailable</title></head>"
207+
"<body><h1>HTTP/1.0 507 Insufficient Space to Store Resource</h1></body>"
208+
"</html>";
209+
static const char partial_content[] = "<html>"
210+
"<head><title>Partial Content</title></head>"
211+
"<body><h1>HTTP/1.1 206 Partial Content</h1></body>"
212+
"</html>";
213+
static const char request_timeout[] = "<html>"
214+
"<head><title>Request Timeout</title></head>"
215+
"<body><h1>HTTP/1.1 408 Request Timeout</h1></body>"
216+
"</html>";
217+
static const char precondition_failed[] = "<html>"
218+
"<head><title>Precondition Failed</title></head>"
219+
"<body><h1>HTTP/1.1 412 Precondition Failed</h1></body>"
220+
"</html>";
221+
static const char unsatisfiable_range[] = "<html>"
222+
"<head><title>Unsatisfiable Range</title></head>"
223+
"<body><h1>HTTP/1.1 416 Requested Range Not Satisfiable</h1></body>"
224+
"</html>";
199225

200226
switch (status)
201227
{
@@ -235,6 +261,16 @@ namespace boost { namespace network { namespace http {
235261
return bad_gateway;
236262
case basic_response<tags::http_server>::service_unavailable:
237263
return service_unavailable;
264+
case basic_response<tags::http_server>::space_unavailable:
265+
return space_unavailable;
266+
case basic_response<tags::http_server>::partial_content:
267+
return partial_content;
268+
case basic_response<tags::http_server>::request_timeout:
269+
return request_timeout;
270+
case basic_response<tags::http_server>::unsatisfiable_range:
271+
return unsatisfiable_range;
272+
case basic_response<tags::http_server>::precondition_failed:
273+
return precondition_failed;
238274
default:
239275
return internal_server_error;
240276
}
@@ -278,6 +314,16 @@ namespace boost { namespace network { namespace http {
278314
"HTTP/1.0 502 Bad Gateway\r\n";
279315
static const string_type service_unavailable =
280316
"HTTP/1.0 503 Service Unavailable\r\n";
317+
static const string_type space_unavailable =
318+
"HTTP/1.0 507 Insufficient Space to Store Resource\r\n";
319+
static const string_type partial_content =
320+
"HTTP/1.1 206 Partial Content\r\n";
321+
static const string_type request_timeout =
322+
"HTTP/1.1 408 Request Timeout\r\n";
323+
static const string_type precondition_failed =
324+
"HTTP/1.1 412 Precondition Failed\r\n";
325+
static const string_type unsatisfiable_range =
326+
"HTTP/1.1 416 Requested Range Not Satisfiable\r\n";
281327

282328
switch (status) {
283329
case basic_response<tags::http_server>::ok:
@@ -316,6 +362,16 @@ namespace boost { namespace network { namespace http {
316362
return buffer(bad_gateway);
317363
case basic_response<tags::http_server>::service_unavailable:
318364
return buffer(service_unavailable);
365+
case basic_response<tags::http_server>::space_unavailable:
366+
return buffer(space_unavailable);
367+
case basic_response<tags::http_server>::partial_content:
368+
return buffer(partial_content);
369+
case basic_response<tags::http_server>::request_timeout:
370+
return buffer(request_timeout);
371+
case basic_response<tags::http_server>::unsatisfiable_range:
372+
return buffer(unsatisfiable_range);
373+
case basic_response<tags::http_server>::precondition_failed:
374+
return buffer(precondition_failed);
319375
default:
320376
return buffer(internal_server_error);
321377
}

boost/network/protocol/http/server/async_connection.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace boost { namespace network { namespace http {
6262
, created = 201
6363
, accepted = 202
6464
, no_content = 204
65+
, partial_content = 206
6566
, multiple_choices = 300
6667
, moved_permanently = 301
6768
, moved_temporarily = 302
@@ -72,10 +73,14 @@ namespace boost { namespace network { namespace http {
7273
, not_found = 404
7374
, not_supported = 405
7475
, not_acceptable = 406
76+
, request_timeout = 408
77+
, precondition_failed = 412
78+
, unsatisfiable_range = 416
7579
, internal_server_error = 500
7680
, not_implemented = 501
7781
, bad_gateway = 502
7882
, service_unavailable = 503
83+
, space_unavailable = 507
7984
};
8085

8186
typedef typename string<Tag>::type string_type;
@@ -104,6 +109,11 @@ namespace boost { namespace network { namespace http {
104109
, bad_gateway_[] = "Bad Gateway"
105110
, service_unavailable_[] = "Service Unavailable"
106111
, unknown_[] = "Unknown"
112+
, partial_content_[] = "Partial Content"
113+
, request_timeout_[] = "Request Timeout"
114+
, precondition_failed_[] = "Precondition Failed"
115+
, unsatisfiable_range_[] = "Requested Range Not Satisfiable"
116+
, space_unavailable_[] = "Insufficient Space to Store Resource"
107117
;
108118
switch(status) {
109119
case ok: return ok_;
@@ -124,6 +134,11 @@ namespace boost { namespace network { namespace http {
124134
case not_implemented: return not_implemented_;
125135
case bad_gateway: return bad_gateway_;
126136
case service_unavailable: return service_unavailable_;
137+
case partial_content: return partial_content_;
138+
case request_timeout: return request_timeout_;
139+
case precondition_failed: return precondition_failed_;
140+
case unsatisfiable_range: return unsatisfiable_range_;
141+
case space_unavailable: return space_unavailable_;
127142
default: return unknown_;
128143
}
129144
}

boost/network/protocol/http/server/options.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ struct server_options {
107107

108108
private:
109109
boost::shared_ptr<boost::asio::io_service> io_service_;
110+
Handler &handler_;
110111
string_type address_;
111112
string_type port_;
112-
Handler &handler_;
113113
bool reuse_address_;
114114
bool report_aborted_;
115115
bool non_blocking_io_;

libs/network/doc/whats_new.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010
v0.9.5
1111
~~~~~~
12-
* Removing dependency on Boost.Parameter from HTTP client and server.
13-
* Fix for Clang error on Twitter example.
14-
* Adding source port to the request (HTTP server).
15-
* Updates to CMake config for MSVC 2010/2012.
16-
* Support chunked content encoding in client response parsing.
17-
* Fix bug with client not invoking callback when a request fails.
12+
* Removed dependency on Boost.Parameter from HTTP client and server.
13+
* Fixed for Clang error on Twitter example.
14+
* Added source port to the request (HTTP server).
15+
* Updated CMake config for MSVC 2010/2012.
16+
* Now support chunked content encoding in client response parsing.
17+
* Fixed bug with client not invoking callback when a request fails.
1818

1919
v0.9.4
2020
~~~~~~

0 commit comments

Comments
 (0)