Skip to content

Commit 382d80f

Browse files
committed
Fleshing out more of the asynchronous HTTP connection implementation.
1 parent 5b47593 commit 382d80f

File tree

1 file changed

+68
-9
lines changed

1 file changed

+68
-9
lines changed

boost/network/protocol/http/impl/http_async_connection.hpp

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <boost/range/algorithm/transform.hpp>
1515
#include <boost/network/constants.hpp>
1616
#include <boost/network/traits/ostream_iterator.hpp>
17+
#include <boost/regex.hpp>
1718
#include <iterator>
1819

1920
namespace boost { namespace network { namespace http { namespace impl {
@@ -71,7 +72,7 @@ namespace boost { namespace network { namespace http { namespace impl {
7172
body(temp, body_future);
7273
boost::shared_future<string_type> version_future = version_promise.get_future();
7374
version(temp, version_future);
74-
boost::shared_future<uint16_t> status_future = status_promise.get_future();
75+
boost::shared_future<boost::uint16_t> status_future = status_promise.get_future();
7576
status(temp, status_future);
7677
boost::shared_future<string_type> status_message_future = status_message_promise.get_future();
7778
status_message(temp, status_message_future);
@@ -145,7 +146,7 @@ namespace boost { namespace network { namespace http { namespace impl {
145146
boost::bind(
146147
&http_async_connection<Tag,version_major,version_minor>::handle_connected,
147148
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
148-
method, std::make_pair(++iter, resolver_iterator()),
149+
method, port, std::make_pair(++iter, resolver_iterator()),
149150
boost::asio::placeholders::error
150151
)));
151152
} else {
@@ -162,21 +163,79 @@ namespace boost { namespace network { namespace http { namespace impl {
162163
}
163164
}
164165

165-
void handle_connected(string_type method, resolver_iterator_pair endpoint_range, boost::system::error_code const & ec) {
166+
void handle_connected(string_type method, boost::uint16_t port, resolver_iterator_pair endpoint_range, boost::system::error_code const & ec) {
166167
if (!ec) {
167-
168+
boost::asio::async_write(*socket_, boost::asio::buffer(command_string_.data(), command_string_.size()),
169+
request_strand_->wrap(
170+
boost::bind(
171+
&http_async_connection<Tag,version_major,version_minor>::handle_sent_request,
172+
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
173+
method,
174+
boost::asio::placeholders::error,
175+
boost::asio::placeholders::bytes_transferred
176+
)));
177+
} else {
178+
if (!boost::empty(endpoint_range)) {
179+
resolver_iterator iter = boost::begin(endpoint_range);
180+
boost::asio::ip::tcp::endpoint endpoint(
181+
iter->endpoint().address(),
182+
port
183+
);
184+
socket_.reset(new boost::asio::ip::tcp::socket(
185+
resolver_->get_io_service()));
186+
socket_->async_connect(
187+
endpoint,
188+
request_strand_->wrap(
189+
boost::bind(
190+
&http_async_connection<Tag,version_major,version_minor>::handle_connected,
191+
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
192+
method, port, std::make_pair(++iter, resolver_iterator()),
193+
boost::asio::placeholders::error
194+
)));
195+
} else {
196+
boost::system::system_error error(
197+
ec ? ec : boost::asio::error::host_not_found
198+
);
199+
version_promise.set_exception(boost::copy_exception(error));
200+
status_promise.set_exception(boost::copy_exception(error));
201+
status_message_promise.set_exception(boost::copy_exception(error));
202+
headers_promise.set_exception(boost::copy_exception(error));
203+
source_promise.set_exception(boost::copy_exception(error));
204+
destination_promise.set_exception(boost::copy_exception(error));
205+
body_promise.set_exception(boost::copy_exception(error));
206+
}
168207
}
169208
}
170209

171-
void handle_sent_request() {
210+
void handle_sent_request(string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
172211
if (!ec) {
173-
async_read(); //FIXME -- wire the correct parameters
212+
static boost::regex const version_pattern("HTTP/\\d+\\.\\d+\\s\\d{3}\\s[\\w\\s\\d]+\\r\\n");
213+
boost::asio::async_read_until(
214+
*socket_,
215+
response_buffer_,
216+
version_pattern,
217+
request_strand_->wrap(
218+
boost::bind(
219+
&http_async_connection<Tag,version_major,version_minor>::handle_received_status,
220+
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
221+
method, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
222+
} else {
223+
boost::system::system_error error(
224+
ec ? ec : boost::asio::error::host_not_found
225+
);
226+
version_promise.set_exception(boost::copy_exception(error));
227+
status_promise.set_exception(boost::copy_exception(error));
228+
status_message_promise.set_exception(boost::copy_exception(error));
229+
headers_promise.set_exception(boost::copy_exception(error));
230+
source_promise.set_exception(boost::copy_exception(error));
231+
destination_promise.set_exception(boost::copy_exception(error));
232+
body_promise.set_exception(boost::copy_exception(error));
174233
}
175234
}
176235

177-
void handle_received_status() {
236+
void handle_received_status(string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
178237
if (!ec) {
179-
async_read(); //FIXME -- wire the correct parameters
238+
180239
}
181240
}
182241

@@ -205,7 +264,7 @@ namespace boost { namespace network { namespace http { namespace impl {
205264
boost::promise<string_type> destination_promise;
206265
boost::promise<string_type> body_promise;
207266
string_type command_string_;
208-
267+
boost::asio::streambuf response_buffer_;
209268
};
210269

211270
} // namespace impl

0 commit comments

Comments
 (0)