@@ -99,74 +99,87 @@ namespace boost { namespace network { namespace http { namespace impl {
99
99
}
100
100
101
101
template <class Socket >
102
- void read_body (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
103
- typename ostringstream<Tag>::type body_stream;
104
-
102
+ void read_body_normal (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer,typename ostringstream<Tag>::type & body_stream) {
105
103
boost::system::error_code error;
106
- // TODO tag dispatch based on whether it's HTTP 1.0 or HTTP 1.1
107
- if (version_major ==1 && version_minor ==0 ) {
108
- if (response_buffer.size () >0 )
109
- body_stream << &response_buffer;
104
+ if (response_buffer.size () >0 )
105
+ body_stream << &response_buffer;
110
106
111
- while (boost::asio::read (socket_, response_buffer,boost::asio::transfer_at_least (1 ), error)) {
107
+ while (boost::asio::read (socket_, response_buffer,boost::asio::transfer_at_least (1 ), error)) {
108
+ body_stream << &response_buffer;
109
+ }
110
+ }
111
+
112
+ template <class Socket >
113
+ void read_body_transfer_chunk_encoding (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer,typename ostringstream<Tag>::type & body_stream) {
114
+ boost::system::error_code error;
115
+ // look for the content-length header
116
+ typename headers_range<basic_response<Tag> >::type content_length_range =
117
+ headers (response_)[" Content-Length" ];
118
+ if (empty (content_length_range)) {
119
+ typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
120
+ headers (response_)[" Transfer-Encoding" ];
121
+ if (empty (transfer_encoding_range))throw std::runtime_error (" Missing Transfer-Encoding Header from response." );
122
+ if (boost::iequals (begin (transfer_encoding_range)->second ," chunked" )) {
123
+ bool stopping =false ;
124
+ do {
125
+ std::size_t chunk_size_line =read_until (socket_, response_buffer," \r\n " , error);
126
+ if ((chunk_size_line ==0 ) && (error != boost::asio::error::eof))throw boost::system::system_error (error);
127
+ std::size_t chunk_size =0 ;
128
+ string_type data;
129
+ {
130
+ std::istreamchunk_stream (&response_buffer);
131
+ std::getline (chunk_stream, data);
132
+ typename istringstream<Tag>::typechunk_size_stream (data);
133
+ chunk_size_stream >> std::hex >> chunk_size;
134
+ }
135
+ if (chunk_size ==0 ) {
136
+ stopping =true ;
137
+ if (!read_until (socket_, response_buffer," \r\n " , error) && (error != boost::asio::error::eof))
138
+ throw boost::system::system_error (error);
139
+ }else {
140
+ bool stopping_inner =false ;
141
+ do {
142
+ std::size_t chunk_bytes_read =read (socket_, response_buffer,boost::asio::transfer_at_least (chunk_size +2 ), error);
143
+ if (chunk_bytes_read ==0 ) {
144
+ if (error != boost::asio::error::eof)throw boost::system::system_error (error);
145
+ stopping_inner =true ;
146
+ }
147
+
148
+ std::istreambuf_iterator<char > eos;
149
+ std::istreambuf_iterator<char >stream_iterator (&response_buffer);
150
+ for (; chunk_size >0 && stream_iterator != eos; --chunk_size)
151
+ body_stream << *stream_iterator++;
152
+ response_buffer.consume (2 );
153
+ }while (!stopping_inner && chunk_size !=0 );
154
+
155
+ if (chunk_size !=0 )
156
+ throw std::runtime_error (" Size mismatch between tranfer encoding chunk data size and declared chunk size." );
157
+ }
158
+ }while (!stopping);
159
+ }else throw std::runtime_error (" Unsupported Transfer-Encoding." );
160
+ }else {
161
+ size_t length = lexical_cast<size_t >(begin (content_length_range)->second );
162
+ size_t bytes_read =0 ;
163
+ while ((bytes_read =boost::asio::read (socket_, response_buffer,boost::asio::transfer_at_least (1 ), error))) {
112
164
body_stream << &response_buffer;
165
+ length -= bytes_read;
166
+ if ((length <=0 )or error)
167
+ break ;
113
168
}
169
+ }
170
+ }
171
+
172
+ template <class Socket >
173
+ void read_body (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
174
+ typename ostringstream<Tag>::type body_stream;
175
+ // TODO tag dispatch based on whether it's HTTP 1.0 or HTTP 1.1
176
+ if (version_major ==1 && version_minor ==0 ) {
177
+ read_body_normal (socket_, response_, response_buffer, body_stream);
114
178
}else if (version_major ==1 && version_minor ==1 ) {
115
- // look for the content-length header
116
- typename headers_range<basic_response<Tag> >::type content_length_range =
117
- headers (response_)[" Content-Length" ];
118
- if (empty (content_length_range)) {
119
- typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
120
- headers (response_)[" Transfer-Encoding" ];
121
- if (empty (transfer_encoding_range))throw std::runtime_error (" Missing Transfer-Encoding Header from response." );
122
- if (boost::iequals (begin (transfer_encoding_range)->second ," chunked" )) {
123
- bool stopping =false ;
124
- do {
125
- std::size_t chunk_size_line =read_until (socket_, response_buffer," \r\n " , error);
126
- if ((chunk_size_line ==0 ) && (error != boost::asio::error::eof))throw boost::system::system_error (error);
127
- std::size_t chunk_size =0 ;
128
- string_type data;
129
- {
130
- std::istreamchunk_stream (&response_buffer);
131
- std::getline (chunk_stream, data);
132
- typename istringstream<Tag>::typechunk_size_stream (data);
133
- chunk_size_stream >> std::hex >> chunk_size;
134
- }
135
- if (chunk_size ==0 ) {
136
- stopping =true ;
137
- if (!read_until (socket_, response_buffer," \r\n " , error) && (error != boost::asio::error::eof))
138
- throw boost::system::system_error (error);
139
- }else {
140
- bool stopping_inner =false ;
141
- do {
142
- std::size_t chunk_bytes_read =read (socket_, response_buffer,boost::asio::transfer_at_least (chunk_size +2 ), error);
143
- if (chunk_bytes_read ==0 ) {
144
- if (error != boost::asio::error::eof)throw boost::system::system_error (error);
145
- stopping_inner =true ;
146
- }
147
-
148
- std::istreambuf_iterator<char > eos;
149
- std::istreambuf_iterator<char >stream_iterator (&response_buffer);
150
- for (; chunk_size >0 && stream_iterator != eos; --chunk_size)
151
- body_stream << *stream_iterator++;
152
- response_buffer.consume (2 );
153
- }while (!stopping_inner && chunk_size !=0 );
154
-
155
- if (chunk_size !=0 )
156
- throw std::runtime_error (" Size mismatch between tranfer encoding chunk data size and declared chunk size." );
157
- }
158
- }while (!stopping);
159
- }else throw std::runtime_error (" Unsupported Transfer-Encoding." );
160
- }else {
161
- size_t length = lexical_cast<size_t >(begin (content_length_range)->second );
162
- size_t bytes_read =0 ;
163
- while ((bytes_read =boost::asio::read (socket_, response_buffer,boost::asio::transfer_at_least (1 ), error))) {
164
- body_stream << &response_buffer;
165
- length -= bytes_read;
166
- if ((length <=0 )or error)
167
- break ;
168
- }
169
- }
179
+ if (response_.version () ==" HTTP/1.0" )
180
+ read_body_normal (socket_, response_, response_buffer, body_stream);
181
+ else
182
+ read_body_transfer_chunk_encoding (socket_, response_, response_buffer, body_stream);
170
183
}else {
171
184
throw std::runtime_error (" Unsupported HTTP version number." );
172
185
}