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

Commitb4dc8ce

Browse files
committed
Allow overriding defaulted headers.
This change fixes the linearization of HTTP requests so that two thingshappen:- empty headers are ignored- explicitly defining the defaulted headers will suppress defaultsFixes#263
1 parent79f6727 commitb4dc8ce

File tree

3 files changed

+145
-38
lines changed

3 files changed

+145
-38
lines changed

‎boost/network/protocol/http/algorithms/linearize.hpp

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// (See accompanying file LICENSE_1_0.txt or copy at
77
// http://www.boost.org/LICENSE_1_0.txt)
88

9+
#include<algorithm>
10+
#include<bitset>
911
#include<boost/network/traits/string.hpp>
1012
#include<boost/network/protocol/http/message/header/name.hpp>
1113
#include<boost/network/protocol/http/message/header/value.hpp>
@@ -15,6 +17,7 @@
1517
#include<boost/concept/requires.hpp>
1618
#include<boost/optional.hpp>
1719
#include<boost/range/algorithm/copy.hpp>
20+
#include<boost/algorithm/string/compare.hpp>
1821

1922
namespaceboost {namespacenetwork {namespacehttp {
2023

@@ -92,48 +95,86 @@ namespace boost { namespace network { namespace http {
9295
*oi =consts::dot_char();
9396
boost::copy(version_minor_str, oi);
9497
boost::copy(crlf, oi);
95-
boost::copy(host, oi);
96-
*oi =consts::colon_char();
97-
*oi =consts::space_char();
98-
boost::copy(request.host(), oi);
99-
boost::optional<boost::uint16_t> port_ =port(request);
100-
if (port_) {
101-
string_type port_str = boost::lexical_cast<string_type>(*port_);
102-
*oi =consts::colon_char();
103-
boost::copy(port_str, oi);
104-
}
105-
boost::copy(crlf, oi);
106-
boost::copy(accept, oi);
107-
*oi =consts::colon_char();
108-
*oi =consts::space_char();
109-
boost::copy(accept_mime, oi);
110-
boost::copy(crlf, oi);
111-
if (version_major ==1u && version_minor ==1u) {
112-
boost::copy(accept_encoding, oi);
113-
*oi =consts::colon_char();
114-
*oi =consts::space_char();
115-
boost::copy(default_accept_encoding, oi);
116-
boost::copy(crlf, oi);
117-
}
98+
99+
// We need to determine whether we've seen any of the following headers
100+
// before setting the defaults. We use a bitset to keep track of the
101+
// defaulted headers.
102+
enum { ACCEPT, ACCEPT_ENCODING, HOST, MAX };
103+
std::bitset<MAX> found_headers;
104+
staticcharconst* defaulted_headers[][2] = {
105+
{consts::accept(),
106+
consts::accept() +std::strlen(consts::accept())},
107+
{consts::accept_encoding(),
108+
consts::accept_encoding() +std::strlen(consts::accept_encoding())},
109+
{consts::host(),consts::host() +std::strlen(consts::host())}
110+
};
111+
118112
typedeftypename headers_range<Request>::type headers_range;
119113
typedeftypename range_value<headers_range>::type headers_value;
120-
BOOST_FOREACH(const headers_value &header,headers(request))
121-
{
122-
string_type header_name =name(header),
123-
header_value =value(header);
124-
boost::copy(header_name, oi);
125-
*oi =consts::colon_char();
126-
*oi =consts::space_char();
127-
boost::copy(header_value, oi);
128-
boost::copy(crlf, oi);
114+
BOOST_FOREACH(const headers_value & header,headers(request)) {
115+
string_type header_name =name(header), header_value =value(header);
116+
// Here we check that we have not seen an override to the defaulted
117+
// headers.
118+
for (int header_index =0; header_index < MAX; ++header_index)
119+
if (std::distance(header_name.begin(), header_name.end()) ==
120+
std::distance(defaulted_headers[header_index][0],
121+
defaulted_headers[header_index][1]) &&
122+
std::equal(header_name.begin(),
123+
header_name.end(),
124+
defaulted_headers[header_index][0],
125+
algorithm::is_iequal()))
126+
found_headers.set(header_index,true);
127+
128+
// We ignore empty headers.
129+
if (header_value.empty())continue;
130+
boost::copy(header_name, oi);
131+
*oi =consts::colon_char();
132+
*oi =consts::space_char();
133+
boost::copy(header_value, oi);
134+
boost::copy(crlf, oi);
135+
136+
}
137+
138+
if (!found_headers[HOST]) {
139+
boost::copy(host, oi);
140+
*oi =consts::colon_char();
141+
*oi =consts::space_char();
142+
boost::copy(request.host(), oi);
143+
boost::optional<boost::uint16_t> port_ =port(request);
144+
if (port_) {
145+
string_type port_str = boost::lexical_cast<string_type>(*port_);
146+
*oi =consts::colon_char();
147+
boost::copy(port_str, oi);
148+
}
149+
boost::copy(crlf, oi);
150+
}
151+
152+
if (!found_headers[ACCEPT]) {
153+
boost::copy(accept, oi);
154+
*oi =consts::colon_char();
155+
*oi =consts::space_char();
156+
boost::copy(accept_mime, oi);
157+
boost::copy(crlf, oi);
158+
}
159+
160+
if (version_major ==1u &&
161+
version_minor ==1u &&
162+
!found_headers[ACCEPT_ENCODING]) {
163+
boost::copy(accept_encoding, oi);
164+
*oi =consts::colon_char();
165+
*oi =consts::space_char();
166+
boost::copy(default_accept_encoding, oi);
167+
boost::copy(crlf, oi);
129168
}
169+
130170
if (!connection_keepalive<Tag>::value) {
131-
boost::copy(connection, oi);
132-
*oi =consts::colon_char();
133-
*oi =consts::space_char();
171+
boost::copy(connection, oi);
172+
*oi =consts::colon_char();
173+
*oi =consts::space_char();
134174
boost::copy(close, oi);
135175
boost::copy(crlf, oi);
136176
}
177+
137178
boost::copy(crlf, oi);
138179
typename body_range<Request>::type body_data =body(request).range();
139180
returnboost::copy(body_data, oi);

‎libs/network/test/http/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ if (OPENSSL_FOUND)
1212
endif()
1313

1414
if (Boost_FOUND)
15+
set (TESTS
16+
request_incremental_parser_test
17+
request_linearize_test
18+
)
19+
foreach (test${TESTS} )
20+
if (${CMAKE_CXX_COMPILER_ID}MATCHESGNU)
21+
set_source_files_properties(${test}.cpp
22+
PROPERTIESCOMPILE_FLAGS"-Wall")
23+
endif()
24+
add_executable(cpp-netlib-http-${test}${test}.cpp)
25+
add_dependencies(cpp-netlib-http-${test}
26+
cppnetlib-uri)
27+
target_link_libraries(cpp-netlib-http-${test}
28+
${Boost_LIBRARIES}${CMAKE_THREAD_LIBS_INIT}
29+
cppnetlib-uri)
30+
if (${CMAKE_SYSTEM_NAME}MATCHES"Linux")
31+
target_link_libraries(cpp-netlib-http-${test}rt)
32+
endif()
33+
set_target_properties(cpp-netlib-http-${test}
34+
PROPERTIESRUNTIME_OUTPUT_DIRECTORY${CPP-NETLIB_BINARY_DIR}/tests)
35+
add_test(cpp-netlib-http-${test}
36+
${CPP-NETLIB_BINARY_DIR}/tests/cpp-netlib-http-${test})
37+
endforeach (test)
1538
set (TESTS
1639
client_constructor_test
1740
client_get_test

‎libs/network/test/http/request_linearize_test.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include<boost/test/unit_test.hpp>
1111
#include<boost/mpl/list.hpp>
1212
#include<iostream>
13+
#include<iterator>
1314

1415
namespacehttp= boost::network::http;
1516
namespacetags= boost::network::http::tags;
@@ -24,8 +25,50 @@ typedef mpl::list<
2425
> tag_types;
2526

2627
BOOST_AUTO_TEST_CASE_TEMPLATE(linearize_request, T, tag_types) {
27-
http::basic_request<T>request("http://www.boost.org");
28-
linearize(request,"GET",1,0, std::ostream_iterator<typename net::char_<T>::type>(std::cout));
29-
linearize(request,"GET",1,1, std::ostream_iterator<typename net::char_<T>::type>(std::cout));
28+
http::basic_request<T>request("http://www.boost.org");
29+
staticchar http_1_0_output[] =
30+
"GET / HTTP/1.0\r\n"
31+
"Host: www.boost.org\r\n"
32+
"Accept: */*\r\n"
33+
"Connection: Close\r\n"
34+
"\r\n";
35+
staticchar http_1_1_output[] =
36+
"GET / HTTP/1.1\r\n"
37+
"Host: www.boost.org\r\n"
38+
"Accept: */*\r\n"
39+
"Accept-Encoding: identity;q=1.0, *;q=0\r\n"
40+
"Connection: Close\r\n"
41+
"\r\n";
42+
typename http::basic_request<T>::string_type output_1_0;
43+
linearize(request,"GET",1,0,std::back_inserter(output_1_0));
44+
BOOST_CHECK_EQUAL(output_1_0, http_1_0_output);
45+
typename http::basic_request<T>::string_type output_1_1;
46+
linearize(request,"GET",1,1,std::back_inserter(output_1_1));
47+
BOOST_CHECK_EQUAL(output_1_1, http_1_1_output);
48+
}
49+
50+
BOOST_AUTO_TEST_CASE_TEMPLATE(linearize_request_override_headers,
51+
T,
52+
tag_types) {
53+
http::basic_request<T>request("http://www.boost.org");
54+
// We can override the defaulted headers and test that here.
55+
request <<net::header("Accept","");
56+
staticchar http_1_0_no_accept_output[] =
57+
"GET / HTTP/1.0\r\n"
58+
"Host: www.boost.org\r\n"
59+
"Connection: Close\r\n"
60+
"\r\n";
61+
staticchar http_1_1_no_accept_output[] =
62+
"GET / HTTP/1.1\r\n"
63+
"Host: www.boost.org\r\n"
64+
"Accept-Encoding: identity;q=1.0, *;q=0\r\n"
65+
"Connection: Close\r\n"
66+
"\r\n";
67+
typename http::basic_request<T>::string_type output_1_0;
68+
linearize(request,"GET",1,0,std::back_inserter(output_1_0));
69+
BOOST_CHECK_EQUAL(output_1_0, http_1_0_no_accept_output);
70+
typename http::basic_request<T>::string_type output_1_1;
71+
linearize(request,"GET",1,1,std::back_inserter(output_1_1));
72+
BOOST_CHECK_EQUAL(output_1_1, http_1_1_no_accept_output);
3073
}
3174

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp