@@ -40,7 +40,7 @@ namespace boost { namespace network { namespace http {
4040 , get_connection_(get_connection) {}
4141
4242 basic_response<Tag>send_request (string_typeconst & 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);
4444 }
4545
4646~connection_impl () {
@@ -49,50 +49,67 @@ namespace boost { namespace network { namespace http {
4949
5050private:
5151
52- basic_response<Tag>send_request_recursive (string_typeconst & 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- &¬ (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_typeconst & 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+ &¬ (response_.status () >=100 && response_.status () <=199 )
87+ ) {
88+ pimpl->read_body (response_, response_buffer);
8789 }
88- }
8990
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+ }
94110
95- return response_;
111+ return response_;
112+ }while (true );
96113 }
97114
98115 shared_ptr<http::impl::sync_connection_base<Tag,version_major,version_minor> > pimpl;