@@ -40,7 +40,7 @@ namespace boost { namespace network { namespace http {
40
40
, get_connection_(get_connection) {}
41
41
42
42
basic_response<Tag> send_request (string_type const & method, basic_request<Tag> request_, bool get_body) {
43
- return send_request_recursive (method, request_, get_body, 0 );
43
+ return send_request_impl (method, request_, get_body);
44
44
}
45
45
46
46
~connection_impl () {
@@ -49,50 +49,67 @@ namespace boost { namespace network { namespace http {
49
49
50
50
private:
51
51
52
- basic_response<Tag> send_request_recursive (string_type const & method, basic_request<Tag> request_, bool get_body, int count) {
53
- if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT)
54
- throw std::runtime_error (" Redirection exceeds maximum redirect count." );
55
-
56
- basic_response<Tag> response_;
57
- // check if the socket is open first
58
- if (!pimpl->is_open ()) {
59
- pimpl->init_socket (request_.host (), lexical_cast<string_type>(request_.port ()));
60
- }
61
- pimpl->send_request_impl (method, request_);
62
- response_ = basic_response<Tag>();
63
- response_ << source (request_.host ());
64
-
65
- boost::asio::streambuf response_buffer;
66
- pimpl->read_status (response_, response_buffer);
67
- pimpl->read_headers (response_, response_buffer);
68
- if (
69
- get_body && response_.status () != 304
70
- && (response_.status () != 204 )
71
- && not (response_.status () >= 100 && response_.status () <= 199 )
72
- ) {
73
- pimpl->read_body (response_, response_buffer);
74
- }
75
-
76
- if (connection_follow_redirect_) {
77
- boost::uint16_t status = response_.status ();
78
- if (status >= 300 && status <= 307 ) {
79
- typename headers_range<basic_response<Tag> >::type location_range = headers (response_)[" Location" ];
80
- typename range_iterator<typename headers_range<basic_request<Tag> >::type>::type location_header = begin (location_range);
81
- if (location_header != end (location_range)) {
82
- request_.uri (location_header->second );
83
- connection_ptr connection_;
84
- connection_ = get_connection_ (resolver_, request_);
85
- return connection_->send_request_recursive (method, request_, get_body, ++count);
86
- } else throw std::runtime_error (" Location header not defined in redirect response." );
52
+ basic_response<Tag> send_request_impl (string_type const & method, basic_request<Tag> request_, bool get_body) {
53
+ boost::uint8_t count = 0 ;
54
+ bool retry = false ;
55
+ do {
56
+ if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT)
57
+ throw std::runtime_error (" Redirection exceeds maximum redirect count." );
58
+
59
+ basic_response<Tag> response_;
60
+ // check if the socket is open first
61
+ if (!pimpl->is_open ()) {
62
+ pimpl->init_socket (request_.host (), lexical_cast<string_type>(request_.port ()));
63
+ }
64
+ response_ = basic_response<Tag>();
65
+ response_ << source (request_.host ());
66
+
67
+ pimpl->send_request_impl (method, request_);
68
+ boost::asio::streambuf response_buffer;
69
+
70
+ try {
71
+ pimpl->read_status (response_, response_buffer);
72
+ } catch (boost::system ::system_error & e) {
73
+ if (!retry && e.code () == boost::asio::error::eof) {
74
+ retry = true ;
75
+ pimpl->init_socket (request_.host (), lexical_cast<string_type>(request_.port ()));
76
+ continue ;
77
+ }
78
+ throw ; // it's a retry, and there's something wrong.
79
+ }
80
+
81
+ pimpl->read_headers (response_, response_buffer);
82
+
83
+ if (
84
+ get_body && response_.status () != 304
85
+ && (response_.status () != 204 )
86
+ && not (response_.status () >= 100 && response_.status () <= 199 )
87
+ ) {
88
+ pimpl->read_body (response_, response_buffer);
87
89
}
88
- }
89
90
90
- typename headers_range<basic_response<Tag> >::type connection_range = headers (response_)[" Connection" ];
91
- if (!empty (connection_range) && begin (connection_range)->second == string_type (" close" )) {
92
- pimpl->close_socket ();
93
- }
91
+ if (connection_follow_redirect_) {
92
+ boost::uint16_t status = response_.status ();
93
+ if (status >= 300 && status <= 307 ) {
94
+ typename headers_range<basic_response<Tag> >::type location_range = headers (response_)[" Location" ];
95
+ typename range_iterator<typename headers_range<basic_request<Tag> >::type>::type location_header = begin (location_range);
96
+ if (location_header != end (location_range)) {
97
+ request_.uri (location_header->second );
98
+ connection_ptr connection_;
99
+ connection_ = get_connection_ (resolver_, request_);
100
+ ++count;
101
+ continue ;
102
+ } else throw std::runtime_error (" Location header not defined in redirect response." );
103
+ }
104
+ }
105
+
106
+ typename headers_range<basic_response<Tag> >::type connection_range = headers (response_)[" Connection" ];
107
+ if (!empty (connection_range) && begin (connection_range)->second == string_type (" close" )) {
108
+ pimpl->close_socket ();
109
+ }
94
110
95
- return response_;
111
+ return response_;
112
+ } while (true );
96
113
}
97
114
98
115
shared_ptr<http::impl::sync_connection_base<Tag,version_major,version_minor> > pimpl;
0 commit comments