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

Commit6add11d

Browse files
author
Dean Michael Berris
committed
Refactoring implementation (incomplete) to support SSL; lots broken still more work to do -- this is a checkpoint commit, please bear with me.
1 parentdc151fc commit6add11d

File tree

11 files changed

+441
-160
lines changed

11 files changed

+441
-160
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_DETAIL_CONNECTION_HELPER_20091217
2+
#defineBOOST_NETWORK_PROTOCOL_HTTP_DETAIL_CONNECTION_HELPER_20091217
3+
4+
// Copyright Dean Michael Berris 2009.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include<boost/network/version.hpp>
10+
#include<boost/foreach.hpp>
11+
12+
namespaceboost {namespacenetwork {namespacehttp {namespacedetail {
13+
14+
template<classTag,unsigned version_major,unsigned version_minor>
15+
structconnection_helper {
16+
protected:
17+
18+
typedeftypename string<Tag>::type string_type;
19+
20+
voidcreate_request(boost::asio::streambuf & request_buffer, string_typeconst & method, basic_request<Tag> request_)const {
21+
// TODO make this use Boost.Karma instead of an ad-hoc implementation
22+
std::ostreamrequest_stream(&request_buffer);
23+
24+
request_stream
25+
<< method <<"";
26+
27+
if (request_.path().empty() || request_.path()[0] !='/')
28+
request_stream <<'/';
29+
30+
request_stream
31+
<< request_.path()
32+
;
33+
34+
if (!request_.query().empty())
35+
request_stream
36+
<<'?'
37+
<< request_.query()
38+
;
39+
40+
if (!request_.anchor().empty())
41+
request_stream
42+
<<'#'
43+
<< request_.anchor()
44+
;
45+
46+
request_stream <<" HTTP/" << version_major <<'.' << version_minor <<"\r\n"
47+
<<"Host:" << request_.host() <<"\r\n"
48+
<<"Accept: */*\r\n";
49+
50+
typename headers_range<http::basic_request<Tag> >::type range =headers(request_);
51+
BOOST_FOREACH(typename headers_range<http::basic_request<Tag> >::type::value_typeconst & header, range) {
52+
request_stream << header.first <<":" << header.second <<"\r\n";
53+
};
54+
55+
range =headers(request_)["user-agent"];
56+
if (empty(range)) request_stream <<"User-Agent: cpp-netlib/" << BOOST_NETLIB_VERSION <<"\r\n";
57+
58+
request_stream
59+
<<"Connection: close\r\n\r\n";
60+
61+
string_type body_ =body(request_);
62+
if (!body_.empty())
63+
request_stream << body_;
64+
}
65+
66+
};
67+
68+
}// namespace detail
69+
70+
}// namespace http
71+
72+
}// namespace network
73+
74+
}// namespace boost
75+
76+
#endif// BOOST_NETWORK_PROTOCOL_HTTP_DETAIL_CONNECTION_HELPER_20091217
77+

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ namespace boost { namespace network { namespace http {
8484
string_typeconstanchor()const {
8585
return uri_.fragment();
8686
}
87+
88+
string_typeconstprotocol()const {
89+
return uri_.protocol();
90+
}
91+
8792
};
8893

8994
template<classTag>
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217
2+
#defineBOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217
3+
4+
// Copyright Dean Michael Berris 2009.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include<boost/network/protocol/http/traits/resolver_policy.hpp>
10+
#include<boost/network/protocol/http/detail/connection_helper.hpp>
11+
#include<boost/asio/ssl.hpp>
12+
#include<boost/tuple/tuple.hpp>
13+
14+
namespaceboost {namespacenetwork {namespacehttp {namespaceimpl {
15+
template<classTag,unsigned version_major,unsigned version_minor>
16+
structsync_connection_base;
17+
18+
template<classTag,unsigned version_major,unsigned version_minor>
19+
structhttps_sync_connection :publicvirtual sync_connection_base<Tag,version_major,version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
20+
typedeftypename resolver_policy<Tag>::type resolver_base;
21+
typedeftypename resolver_base::resolver_type resolver_type;
22+
typedeftypename string<Tag>::type string_type;
23+
typedef function<typenameresolver_base::resolver_iterator_pair(resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
24+
25+
https_sync_connection(resolver_type & resolver, resolver_function_type resolve)
26+
: resolver_(resolver), resolve_(resolve), context_(resolver.io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.io_service(), context_) { }
27+
28+
voidinit_socket(string_typeconst & hostname, string_typeconst & port) {}
29+
voidsend_request_impl(string_typeconst & method, basic_request<Tag>const & request_) {}
30+
voidread_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
31+
voidread_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
32+
voidread_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
33+
~https_sync_connection() {}
34+
private:
35+
resolver_type & resolver_;
36+
resolver_function_type resolve_;
37+
boost::asio::ssl::context context_;
38+
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
39+
40+
};
41+
42+
template<classTag,unsigned version_major,unsigned version_minor>
43+
structhttp_sync_connection :publicvirtual sync_connection_base<Tag, version_major, version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
44+
typedeftypename resolver_policy<Tag>::type resolver_base;
45+
typedeftypename resolver_base::resolver_type resolver_type;
46+
typedeftypename string<Tag>::type string_type;
47+
typedef function<typenameresolver_base::resolver_iterator_pair(resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
48+
49+
http_sync_connection(resolver_type & resolver, resolver_function_type resolve)
50+
: resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { }
51+
52+
~http_sync_connection() {}
53+
54+
voidinit_socket(string_typeconst & hostname, string_typeconst & port) {
55+
using boost::asio::ip::tcp;
56+
boost::system::error_code error = boost::asio::error::host_not_found;
57+
typename resolver_type::iterator endpoint_iterator, end;
58+
boost::tie(endpoint_iterator, end) =resolve_(resolver_, hostname, port);
59+
while (error && endpoint_iterator != end) {
60+
socket_.close();
61+
socket_.connect(
62+
tcp::endpoint(
63+
endpoint_iterator->endpoint().address()
64+
, endpoint_iterator->endpoint().port()
65+
)
66+
, error
67+
);
68+
++endpoint_iterator;
69+
}
70+
71+
if (error)
72+
throwboost::system::system_error(error);
73+
}
74+
75+
voidsend_request_impl(string_typeconst & method, basic_request<Tag>const & request_) {
76+
boost::asio::streambuf request_buffer;
77+
create_request(request_buffer, method, request_);
78+
write(socket_, request_buffer);
79+
}
80+
81+
voidread_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
82+
boost::asio::read_until(socket_, response_buffer,"\r\n");
83+
std::istreamresponse_stream(&response_buffer);
84+
string_type http_version;
85+
unsignedint status_code;
86+
string_type status_message;
87+
response_stream >> http_version
88+
>> status_code;
89+
std::getline(response_stream, status_message);
90+
trim_left(status_message);
91+
trim_right_if(status_message,boost::is_space() ||boost::is_any_of("\r"));
92+
93+
if (!response_stream || http_version.substr(0,5) !="HTTP/")
94+
throwstd::runtime_error("Invalid response");
95+
96+
response_.version() = http_version;
97+
response_.status() = status_code;
98+
response_.status_message() = status_message;
99+
}
100+
101+
voidread_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
102+
boost::asio::read_until(socket_, response_buffer,"\r\n\r\n");
103+
std::istreamresponse_stream(&response_buffer);
104+
string_type header_line, name;
105+
while (std::getline(response_stream, header_line) && header_line !="\r") {
106+
trim_right_if(header_line,boost::is_space() ||boost::is_any_of("\r"));
107+
typename string_type::size_type colon_offset;
108+
if (header_line.size() && header_line[0] =='') {
109+
assert(!name.empty());
110+
if (name.empty())
111+
throwstd::runtime_error(
112+
std::string("Malformed header:")
113+
+ header_line
114+
);
115+
response_
116+
<<header(name,trim_left_copy(header_line));
117+
}elseif ((colon_offset = header_line.find_first_of(':')) != string_type::npos) {
118+
name = header_line.substr(0, colon_offset);
119+
response_
120+
<<header(name, header_line.substr(colon_offset+2));
121+
};
122+
};
123+
}
124+
125+
voidread_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
126+
typename ostringstream<Tag>::type body_stream;
127+
128+
if (response_buffer.size() >0)
129+
body_stream << &response_buffer;
130+
131+
boost::system::error_code error;
132+
while (boost::asio::read(socket_, response_buffer,boost::asio::transfer_at_least(1), error))
133+
body_stream << &response_buffer;
134+
135+
if (error != boost::asio::error::eof)
136+
throwboost::system::system_error(error);
137+
138+
response_ <<body(body_stream.str());
139+
}
140+
141+
private:
142+
143+
resolver_type & resolver_;
144+
resolver_function_type resolve_;
145+
boost::asio::ip::tcp::socket socket_;
146+
147+
};
148+
149+
template<classTag,unsigned version_major,unsigned version_minor>
150+
structsync_connection_base {
151+
typedeftypename resolver_policy<Tag>::type resolver_base;
152+
typedeftypename resolver_base::resolver_type resolver_type;
153+
typedeftypename string<Tag>::type string_type;
154+
typedef function<typenameresolver_base::resolver_iterator_pair(resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
155+
156+
static sync_connection_base<Tag,version_major,version_minor> *new_connection(resolver_type & resolver, resolver_function_type resolve,bool https) {
157+
if (https) {
158+
returndynamic_cast<sync_connection_base<Tag,version_major,version_minor>*>(new https_sync_connection<Tag,version_major,version_minor>(resolver, resolve));
159+
}
160+
returndynamic_cast<sync_connection_base<Tag,version_major,version_minor>*>(new http_sync_connection<Tag,version_major,version_minor>(resolver, resolve));
161+
}
162+
163+
virtualvoidinit_socket(string_typeconst & hostname, string_typeconst & port) = 0;
164+
virtualvoidsend_request_impl(string_typeconst & method, basic_request<Tag>const & request_) = 0;
165+
virtualvoidread_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) = 0;
166+
virtualvoidread_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) = 0;
167+
virtualvoidread_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) = 0;
168+
virtual~sync_connection_base() {}
169+
protected:
170+
sync_connection_base() {}
171+
};
172+
173+
}// namespace impl
174+
175+
}// namespace http
176+
177+
}// namespace network
178+
179+
}// namespace boost
180+
181+
#endif// BOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217
182+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp