Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7e42af9

Browse files
committed
Adding support for HTTP 1.0 responses when using an HTTP 1.1 client.
1 parent9da4cad commit7e42af9

File tree

4 files changed

+88
-76
lines changed

4 files changed

+88
-76
lines changed

‎boost/network/protocol/http/client.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,11 @@ namespace boost { namespace network { namespace http {
9191
returnsync_request_skeleton(request_,"POST",true);
9292
};
9393

94-
responseconstpost (requestconst & request_, string_typeconst & content_type, string_typeconst & body_) {
95-
request request_copy = request_;
96-
request_copy <<body(body_)
94+
responseconstpost (request request_, string_typeconst & content_type, string_typeconst & body_) {
95+
request_ <<body(body_)
9796
<<header("Content-Type", content_type)
9897
<<header("Content-Length", boost::lexical_cast<string_type>(body_.size()));
99-
returnpost(request_copy);
98+
returnpost(request_);
10099
};
101100

102101
responseconstpost (requestconst & request_, string_typeconst & body_) {
@@ -111,12 +110,11 @@ namespace boost { namespace network { namespace http {
111110
returnput(request_,"x-application/octet-stream", body_);
112111
};
113112

114-
responseconstput (requestconst & request_, string_typeconst & content_type, string_typeconst & body_) {
115-
request request_copy = request_;
116-
request_copy <<body(body_)
113+
responseconstput (request request_, string_typeconst & content_type, string_typeconst & body_) {
114+
request_ <<body(body_)
117115
<<header("Content-Type", content_type)
118116
<<header("Content-Length", boost::lexical_cast<string_type>(body_.size()));
119-
returnput(request_copy);
117+
returnput(request_);
120118
};
121119

122120
responseconstdelete_ (requestconst & request_) {
@@ -137,7 +135,7 @@ namespace boost { namespace network { namespace http {
137135

138136
};
139137

140-
typedef basic_client<tags::http_default_8bit_tcp_resolve,1,0> client;
138+
typedef basic_client<tags::http_default_8bit_udp_resolve,1,0> client;
141139

142140
}// namespace http
143141

‎boost/network/protocol/http/impl/sync_connection_base.hpp

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -99,74 +99,87 @@ namespace boost { namespace network { namespace http { namespace impl {
9999
}
100100

101101
template<classSocket>
102-
voidread_body(Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
103-
typename ostringstream<Tag>::type body_stream;
104-
102+
voidread_body_normal(Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer,typename ostringstream<Tag>::type & body_stream) {
105103
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;
110106

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<classSocket>
113+
voidread_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))throwstd::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))throwboost::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+
throwboost::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)throwboost::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+
throwstd::runtime_error("Size mismatch between tranfer encoding chunk data size and declared chunk size.");
157+
}
158+
}while (!stopping);
159+
}elsethrowstd::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))) {
112164
body_stream << &response_buffer;
165+
length -= bytes_read;
166+
if ((length <=0)or error)
167+
break;
113168
}
169+
}
170+
}
171+
172+
template<classSocket>
173+
voidread_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);
114178
}elseif (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))throwstd::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))throwboost::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-
throwboost::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)throwboost::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-
throwstd::runtime_error("Size mismatch between tranfer encoding chunk data size and declared chunk size.");
157-
}
158-
}while (!stopping);
159-
}elsethrowstd::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);
170183
}else {
171184
throwstd::runtime_error("Unsupported HTTP version number.");
172185
}

‎libs/network/test/http_1_1_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(http_get_test, T, tag_types) {
1919
http::basic_request<T>request("http://www.boost.org/");
2020
http::basic_client<T,1,1> client_;
2121
http::basic_response<T> response_;
22-
response_ = client_.get(request);
22+
BOOST_CHECK_NO_THROW (response_ = client_.get(request));
2323
typename headers_range<typename http::basic_response<T> >::type range =headers(response_)["Content-Type"];
2424
BOOST_CHECK (begin(range) !=end(range) );
2525
BOOST_CHECK (body(response_).size() !=0 );
@@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(http_get_test_different_port, T, tag_types) {
2929
http::basic_request<T>request("http://www.boost.org:80/");
3030
http::basic_client<T,1,1> client_;
3131
http::basic_response<T> response_;
32-
response_ = client_.get(request);
32+
BOOST_CHECK_NO_THROW (response_ = client_.get(request));
3333
typename headers_range<typename http::basic_response<T> >::type range =headers(response_)["Content-Type"];
3434
BOOST_CHECK (begin(range) !=end(range) );
3535
BOOST_CHECK (body(response_).size() !=0 );

‎libs/network/test/http_localhost_tests.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include<boost/config.hpp>
1414
#include<boost/test/unit_test.hpp>
1515
#include<boost/network/include/http/client.hpp>
16+
#include<boost/range.hpp>
1617
#include<boost/cast.hpp>
1718
#include<string>
1819
#include<fstream>
@@ -209,7 +210,7 @@ BOOST_AUTO_TEST_CASE(cgi_query) {
209210
http::client::response r;
210211
BOOST_REQUIRE_NO_THROW(r = c.get(req));
211212
BOOST_CHECK(body(r).length() !=0);
212-
BOOST_CHECK(headers(r)["Content-Type"].begin() !=headers(r)["Content-Type"].end());
213+
BOOST_CHECK(boost::empty(headers(r)["Content-Length"]));
213214
}
214215

215216
BOOST_AUTO_TEST_CASE(cgi_multi_line_headers) {
@@ -220,7 +221,7 @@ BOOST_AUTO_TEST_CASE(cgi_multi_line_headers) {
220221
http::client::response r;
221222
BOOST_REQUIRE_NO_THROW(r = c.get(req));
222223
BOOST_CHECK(body(r).length() !=0);
223-
BOOST_CHECK(headers(r)["Content-Type"].begin() !=headers(r)["Content-Type"].end());
224+
BOOST_CHECK(boost::empty(headers(r)["Content-Type"]));
224225
headers_range<http::client::response>::type range=headers(r)["X-CppNetlib-Test"];
225226
BOOST_REQUIRE(begin(range) !=end(range));
226227
BOOST_REQUIRE(distance(range) ==2);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp