1212#include < iterator>
1313#include < cstdint>
1414#include < boost/algorithm/string/trim.hpp>
15- #include < boost/array.hpp>
1615#include < boost/asio/deadline_timer.hpp>
1716#include < boost/asio/placeholders.hpp>
1817#include < boost/asio/strand.hpp>
1918#include < boost/asio/streambuf.hpp>
2019#include < boost/assert.hpp>
21- #include < boost/bind/protect.hpp>
2220#include < boost/logic/tribool.hpp>
2321#include < boost/network/constants.hpp>
2422#include < boost/network/detail/debug.hpp>
@@ -102,16 +100,19 @@ struct http_async_connection
102100 string_type host_ =host (request);
103101 std::uint16_t source_port = request.source_port ();
104102
103+ auto self =this ->shared_from_this ();
105104resolve_ (resolver_, host_, port_,
106- request_strand_.wrap (boost::bind (
107- &this_type::handle_resolved,this_type::shared_from_this (),
108- host_, port_, source_port, get_body, callback, generator,
109- boost::arg<1 >(), boost::arg<2 >())));
105+ request_strand_.wrap (
106+ [=] (boost::system::error_codeconst &ec,
107+ resolver_iterator_pair endpoint_range) {
108+ self->handle_resolved (host_, port_, source_port, get_body,
109+ callback, generator, ec, endpoint_range);
110+ }));
110111if (timeout_ >0 ) {
111112 timer_.expires_from_now (boost::posix_time::seconds (timeout_));
112- timer_.async_wait (request_strand_.wrap (
113- boost::bind (&this_type::handle_timeout, this_type::shared_from_this (),
114- boost::arg< 1 >()) ));
113+ timer_.async_wait (request_strand_.wrap ([=] (boost::system::error_code const &ec) {
114+ self-> handle_timeout (ec);
115+ } ));
115116 }
116117return response_;
117118 }
@@ -145,13 +146,14 @@ struct http_async_connection
145146// that there's still more endpoints to try connecting to.
146147 resolver_iterator iter =boost::begin (endpoint_range);
147148 asio::ip::tcp::endpointendpoint (iter->endpoint ().address (), port);
149+ auto self =this ->shared_from_this ();
148150 delegate_->connect (
149151 endpoint, host, source_port,
150- request_strand_.wrap (boost::bind (
151- &this_type::handle_connected, this_type::shared_from_this (), host,
152- port, source_port, get_body, callback, generator ,
153- std::make_pair (++iter ,resolver_iterator ()),
154- placeholders::error) ));
152+ request_strand_.wrap ([=] ( boost::system::error_code const &ec) {
153+ auto iter_copy = iter;
154+ self-> handle_connected (host, port, source_port, get_body, callback,
155+ generator, std::make_pair (++iter_copy ,resolver_iterator ()), ec);
156+ } ));
155157 }else {
156158set_errors (ec ? ec : boost::asio::error::host_not_found);
157159 boost::iterator_range<const char *> range;
@@ -169,23 +171,27 @@ struct http_async_connection
169171set_errors (asio::error::timed_out);
170172 }else if (!ec) {
171173BOOST_ASSERT (delegate_.get () !=0 );
174+ auto self =this ->shared_from_this ();
172175 delegate_->write (
173176 command_streambuf,
174- request_strand_.wrap (boost::bind (
175- &this_type::handle_sent_request,this_type::shared_from_this (),
176- get_body, callback, generator, placeholders::error,
177- placeholders::bytes_transferred)));
177+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
178+ std::size_t bytes_transferred) {
179+ self->handle_sent_request (get_body, callback, generator,
180+ ec, bytes_transferred);
181+ }));
178182 }else {
179183if (!boost::empty (endpoint_range)) {
180184 resolver_iterator iter =boost::begin (endpoint_range);
181185 asio::ip::tcp::endpointendpoint (iter->endpoint ().address (), port);
186+ auto self =this ->shared_from_this ();
182187 delegate_->connect (
183188 endpoint, host, source_port,
184- request_strand_.wrap (boost::bind (
185- &this_type::handle_connected,this_type::shared_from_this (),
186- host, port, source_port, get_body, callback, generator,
187- std::make_pair (++iter,resolver_iterator ()),
188- placeholders::error)));
189+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec) {
190+ auto iter_copy = iter;
191+ self->handle_connected (host, port, source_port, get_body, callback,
192+ generator,std::make_pair (++iter_copy,resolver_iterator ()),
193+ ec);
194+ }));
189195 }else {
190196set_errors (ec ? ec : boost::asio::error::host_not_found);
191197 boost::iterator_range<const char *> range;
@@ -211,22 +217,27 @@ struct http_async_connection
211217std::copy (chunk.begin (), chunk.end (),
212218 std::ostreambuf_iterator<typename char_<Tag>::type>(
213219 &command_streambuf));
220+ auto self =this ->shared_from_this ();
214221 delegate_->write (
215222 command_streambuf,
216- request_strand_.wrap (boost::bind (
217- &this_type::handle_sent_request,
218- this_type::shared_from_this (), get_body, callback, generator,
219- placeholders::error, placeholders::bytes_transferred)));
223+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
224+ std::size_t bytes_transferred) {
225+ self->handle_sent_request (get_body, callback, generator,
226+ ec, bytes_transferred);
227+ }));
220228return ;
221229 }
222230 }
231+
232+ auto self =this ->shared_from_this ();
223233 delegate_->read_some (
224234boost::asio::mutable_buffers_1 (this ->part .data (),
225235this ->part .size ()),
226- request_strand_.wrap (boost::bind (
227- &this_type::handle_received_data,this_type::shared_from_this (),
228- version, get_body, callback, placeholders::error,
229- placeholders::bytes_transferred)));
236+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
237+ std::size_t bytes_transferred) {
238+ self->handle_received_data (version, get_body, callback,
239+ ec, bytes_transferred);
240+ }));
230241 }else {
231242set_errors (is_timedout_ ? asio::error::timed_out : ec);
232243 }
@@ -248,15 +259,17 @@ struct http_async_connection
248259 (!ec || ec == boost::asio::error::eof || is_ssl_short_read_error)) {
249260 logic::tribool parsed_ok;
250261size_t remainder;
262+ auto self =this ->shared_from_this ();
251263switch (state) {
252264case version:
253265if (ec == boost::asio::error::eof)return ;
254266 parsed_ok =this ->parse_version (
255267 delegate_,
256- request_strand_.wrap (boost::bind (
257- &this_type::handle_received_data,
258- this_type::shared_from_this (), version, get_body, callback,
259- placeholders::error, placeholders::bytes_transferred)),
268+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
269+ std::size_t bytes_transferred) {
270+ self->handle_received_data (version, get_body, callback,
271+ ec, bytes_transferred);
272+ }),
260273 bytes_transferred);
261274if (!parsed_ok ||indeterminate (parsed_ok)) {
262275return ;
@@ -265,22 +278,23 @@ struct http_async_connection
265278if (ec == boost::asio::error::eof)return ;
266279 parsed_ok =this ->parse_status (
267280 delegate_,
268- request_strand_.wrap (boost::bind (
269- &this_type::handle_received_data,
270- this_type::shared_from_this (), status, get_body, callback,
271- placeholders::error, placeholders::bytes_transferred)),
281+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
282+ std::size_t bytes_transferred) {
283+ self->handle_received_data (status, get_body, callback,
284+ ec, bytes_transferred);
285+ }),
272286 bytes_transferred);
273287if (!parsed_ok ||indeterminate (parsed_ok)) {
274288return ;
275289 }
276290case status_message:
277291if (ec == boost::asio::error::eof)return ;
278292 parsed_ok =this ->parse_status_message (
279- delegate_, request_strand_.wrap (boost::bind (
280- &this_type::handle_received_data,
281- this_type::shared_from_this (), status_message ,
282- get_body, callback, placeholders::error,
283- placeholders::bytes_transferred) ),
293+ delegate_, request_strand_.wrap ([=] ( boost::system::error_code const &,
294+ std:: size_t bytes_transferred) {
295+ self-> handle_received_data (status_message, get_body, callback ,
296+ ec, bytes_transferred);
297+ } ),
284298 bytes_transferred);
285299if (!parsed_ok ||indeterminate (parsed_ok)) {
286300return ;
@@ -293,10 +307,11 @@ struct http_async_connection
293307// to get more data for the body is scheduled.
294308fusion::tie (parsed_ok, remainder) =this ->parse_headers (
295309 delegate_,
296- request_strand_.wrap (boost::bind (
297- &this_type::handle_received_data,
298- this_type::shared_from_this (), headers, get_body, callback,
299- placeholders::error, placeholders::bytes_transferred)),
310+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
311+ std::size_t bytes_transferred) {
312+ self->handle_received_data (headers, get_body, callback,
313+ ec, bytes_transferred);
314+ }),
300315 bytes_transferred);
301316
302317if (!parsed_ok ||indeterminate (parsed_ok)) {
@@ -335,22 +350,26 @@ struct http_async_connection
335350// wait before scheduling another read.
336351callback (make_iterator_range (begin, end), ec);
337352
353+ auto self =this ->shared_from_this ();
338354 delegate_->read_some (
339355boost::asio::mutable_buffers_1 (this ->part .data (),
340356this ->part .size ()),
341- request_strand_.wrap (boost::bind (
342- &this_type::handle_received_data,
343- this_type::shared_from_this (), body, get_body, callback,
344- placeholders::error, placeholders::bytes_transferred)));
357+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
358+ std::size_t bytes_transferred) {
359+ self->handle_received_data (body, get_body, callback,
360+ ec, bytes_transferred);
361+ }));
345362 }else {
346363// Here we handle the body data ourself and append to an
347364// ever-growing string buffer.
365+ auto self =this ->shared_from_this ();
348366this ->parse_body (
349367 delegate_,
350- request_strand_.wrap (boost::bind (
351- &this_type::handle_received_data,
352- this_type::shared_from_this (), body, get_body, callback,
353- placeholders::error, placeholders::bytes_transferred)),
368+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
369+ std::size_t bytes_transferred) {
370+ self->handle_received_data (body, get_body, callback,
371+ ec, bytes_transferred);
372+ }),
354373 remainder);
355374 }
356375return ;
@@ -399,23 +418,26 @@ struct http_async_connection
399418typename protocol_base::buffer_type::const_iterator end = begin;
400419std::advance (end, bytes_transferred);
401420callback (make_iterator_range (begin, end), ec);
421+ auto self =this ->shared_from_this ();
402422 delegate_->read_some (
403423boost::asio::mutable_buffers_1 (this ->part .data (),
404424this ->part .size ()),
405- request_strand_.wrap (boost::bind (
406- &this_type::handle_received_data,
407- this_type::shared_from_this (), body, get_body, callback,
408- placeholders::error, placeholders::bytes_transferred)));
425+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
426+ std::size_t bytes_transferred) {
427+ self->handle_received_data (body, get_body, callback,
428+ ec, bytes_transferred);
429+ }));
409430 }else {
410431// Here we don't have a body callback. Let's make sure that we
411432// deal with the remainder from the headers part in case we do
412433// have data that's still in the buffer.
413434this ->parse_body (
414435 delegate_,
415- request_strand_.wrap (boost::bind (
416- &this_type::handle_received_data,
417- this_type::shared_from_this (), body, get_body, callback,
418- placeholders::error, placeholders::bytes_transferred)),
436+ request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
437+ std::size_t bytes_transferred) {
438+ self->handle_received_data (body, get_body, callback,
439+ ec, bytes_transferred);
440+ }),
419441 bytes_transferred);
420442 }
421443 }