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

Commit6540a84

Browse files
committed
Added async_resolver.
1 parentb700bcc commit6540a84

File tree

7 files changed

+238
-36
lines changed

7 files changed

+238
-36
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright (C) 2013 by Glyn Matthews
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#ifndef __NETWORK_HTTP_V2_CLIENT_CONNECTION_ASYNC_RESOLVER_INC__
7+
#define__NETWORK_HTTP_V2_CLIENT_CONNECTION_ASYNC_RESOLVER_INC__
8+
9+
#include<boost/asio/io_service.hpp>
10+
#include<boost/asio/strand.hpp>
11+
#include<boost/asio/ip/tcp.hpp>
12+
#include<boost/range/iterator_range.hpp>
13+
#include<boost/algorithm/string/case_conv.hpp>
14+
#include<boost/exception/all.hpp>
15+
#include<stdexcept>
16+
#include<cstdint>
17+
#include<string>
18+
#include<unordered_map>
19+
20+
namespacenetwork {
21+
namespacehttp {
22+
namespacev2 {
23+
24+
classresolver_error : std::runtime_error {
25+
26+
public:
27+
28+
resolver_error(const std::string &msg)
29+
: std::runtime_error(msg) {
30+
31+
}
32+
33+
virtual~resolver_error()noexcept {
34+
35+
}
36+
37+
};
38+
39+
classasync_resolver {
40+
41+
async_resolver(const async_resolver &) =delete;
42+
async_resolver &operator = (const async_resolver &) =delete;
43+
44+
public:
45+
46+
typedef boost::asio::ip::tcp::resolver resolver;
47+
typedef resolver::iterator resolver_iterator;
48+
49+
/**
50+
* \brief Constructor.
51+
*/
52+
async_resolver(boost::asio::io_service &service,bool cache_resolved)
53+
: resolver_(service)
54+
, cache_resolved_(cache_resolved_)
55+
, resolver_strand_(new boost::asio::io_service::strand(service)) {
56+
57+
}
58+
59+
/**
60+
* \brief Destructor.
61+
*/
62+
~async_resolver()noexcept {
63+
64+
}
65+
66+
/**
67+
* \brief Resolves a host asynchronously.
68+
*/
69+
template<classOnResolved>
70+
voidresolve(const std::string &host, std::uint16_t port, OnResolved on_resolved) {
71+
if (cache_resolved_) {
72+
endpoint_cache::iterator it = endpoint_cache_.find(boost::to_lower_copy(host));
73+
if (it != endpoint_cache_.end()) {
74+
boost::system::error_code ignored;
75+
on_resolved(ignored, it->second);
76+
return;
77+
}
78+
}
79+
80+
resolver::queryquery(host,std::to_string(port));
81+
resolver_.async_resolve(query,
82+
resolver_strand_->wrap(
83+
[=](const boost::system::error_code &ec,
84+
resolver_iterator endpoint_iterator) {
85+
if (!ec && cache_resolved_) {
86+
endpoint_cache::iterator cache_it;
87+
bool inserted =false;
88+
std::tie(cache_it, inserted) = endpoint_cache_.insert(
89+
std::make_pair(host,
90+
std::make_pair(endpoint_iterator,resolver_iterator())));
91+
on_resolved(ec, cache_it->second);
92+
}
93+
else {
94+
on_resolved(ec,std::make_pair(endpoint_iterator,resolver_iterator()));
95+
}
96+
}));
97+
}
98+
99+
voidclear_resolved_cache() {
100+
endpoint_cache_.clear();
101+
}
102+
103+
private:
104+
105+
typedef boost::asio::io_service::strand strand;
106+
typedef std::unordered_map<
107+
std::string, boost::iterator_range<resolver_iterator>> endpoint_cache;
108+
109+
resolver resolver_;
110+
std::unique_ptr<strand> resolver_strand_;
111+
bool cache_resolved_;
112+
endpoint_cache endpoint_cache_;
113+
114+
};
115+
116+
}// namespace v2
117+
}// namespace http
118+
}// namespace network
119+
120+
121+
#endif// __NETWORK_HTTP_V2_CLIENT_CONNECTION_ASYNC_RESOLVER_INC__

‎http/src/network/http/v2/client/request.hpp‎

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
#ifndef __NETWORK_HTTP_V2_CLIENT_REQUEST_INC__
77
#define__NETWORK_HTTP_V2_CLIENT_REQUEST_INC__
88

9-
#include<cstdint>
109
#include<memory>
1110
#include<string>
11+
#include<vector>
12+
#include<utility>
1213
#include<network/http/v2/constants.hpp>
1314
#include<network/http/v2/message_base.hpp>
1415
#include<network/http/v2/client/client_errors.hpp>
@@ -69,7 +70,7 @@ namespace network {
6970
public:
7071

7172
typedef byte_source::string_type string_type;
72-
typedef std::vector<std::pair<std::string, std::string>> headers_type;
73+
typedef std::vector<std::pair<string_type, string_type>> headers_type;
7374
typedef headers_type::iterator headers_iterator;
7475
typedef headers_type::const_iterator const_headers_iterator;
7576

@@ -91,17 +92,17 @@ namespace network {
9192

9293
request(const request &other)
9394
: destination_(other.destination_)
94-
, byte_source_(other.byte_source_)
95-
, headers_(other.headers_)
9695
, method_(other.method_)
97-
, version_(other.version_) { }
96+
, version_(other.version_)
97+
, headers_(other.headers_)
98+
, byte_source_(other.byte_source_) { }
9899

99100
request(request &&other)noexcept
100101
: destination_(std::move(other.destination_))
101-
, byte_source_(std::move(other.byte_source_))
102-
, headers_(std::move(other.headers_))
103102
, method_(std::move(other.method_))
104-
, version_(std::move(other.version_)) { }
103+
, version_(std::move(other.version_))
104+
, headers_(std::move(other.headers_))
105+
, byte_source_(std::move(other.byte_source_)) { }
105106

106107
request &operator = (request other) {
107108
other.swap(*this);
@@ -110,10 +111,10 @@ namespace network {
110111

111112
voidswap(request &other)noexcept {
112113
std::swap(destination_, other.destination_);
113-
std::swap(byte_source_, other.byte_source_);
114-
std::swap(headers_, other.headers_);
115114
std::swap(method_, other.method_);
116115
std::swap(version_, other.version_);
116+
std::swap(headers_, other.headers_);
117+
std::swap(byte_source_, other.byte_source_);
117118
}
118119

119120
voidset_destination(uri destination) {
@@ -169,25 +170,25 @@ namespace network {
169170
private:
170171

171172
uri destination_;
172-
std::shared_ptr<byte_source> byte_source_;
173-
std::vector<std::pair<string_type, string_type>> headers_;
174173
string_type method_, version_;
174+
headers_type headers_;
175+
std::shared_ptr<byte_source> byte_source_;
175176

176177
friend std::ostream &operator << (std::ostream &os,const request &req) {
177-
std::string path{std::begin(*req.destination_.path()),std::end(*req.destination_.path())};
178-
std::string host;
179-
host.append(std::string{std::begin(*req.destination_.scheme()),
180-
std::end(*req.destination_.scheme())});
178+
request::string_type path{std::begin(*req.destination_.path()),std::end(*req.destination_.path())};
179+
request::string_type host;
180+
host.append(request::string_type{std::begin(*req.destination_.scheme()),
181+
std::end(*req.destination_.scheme())});
181182
host.append("://");
182-
host.append(std::string{std::begin(*req.destination_.authority()),
183-
std::end(*req.destination_.authority())});
183+
host.append(request::string_type{std::begin(*req.destination_.authority()),
184+
std::end(*req.destination_.authority())});
184185

185186
os << req.method_ <<"" << path <<" HTTP/" << req.version_ <<"\r\n";
186187
os <<"Host:" << host <<"\r\n";
187188
for (auto header : req.headers_) {
188189
os << header.first <<":" << header.second <<"\r\n";
189190
}
190-
return os;
191+
return os <<"\r\n";
191192
}
192193
};
193194
}// namespace v2

‎http/src/network/http/v2/client/response.hpp‎

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
// (See accompanying file LICENSE_1_0.txt or copy at
44
// http://www.boost.org/LICENSE_1_0.txt)
55

6-
#ifndef__NETWORK_HTTP_V2_RESPONSE_INC__
7-
#define__NETWORK_HTTP_V2_RESPONSE_INC__
6+
#ifndef__NETWORK_HTTP_V2_CLIENT_RESPONSE_INC__
7+
#define__NETWORK_HTTP_V2_CLIENT_RESPONSE_INC__
88

99
#include<cstdint>
10-
#include<map>
10+
#include<vector>
11+
#include<utility>
1112
#include<string>
1213
#include<future>
14+
#include<network/http/v2/constants.hpp>
15+
#include<boost/range/iterator_range.hpp>
1316
#include<network/uri.hpp>
1417

1518
namespacenetwork {
@@ -19,18 +22,54 @@ namespace network {
1922

2023
public:
2124

22-
typedef std::multimap<std::string, std::string> headers_type;
23-
typedef headers_type::const_iterator headers_iterator;
25+
typedef std::string string_type;
26+
typedef std::vector<std::pair<string_type, string_type>> headers_type;
27+
typedef headers_type::iterator headers_iterator;
2428
typedef headers_type::const_iterator const_headers_iterator;
2529

2630
response() { }
2731

28-
std::uint16_tstatus()const;
29-
std::stringstatus_message()const;
30-
const_headers_iteratorheaders_begin()const;
31-
const_headers_iteratorend_begin()const;
32-
std::pair<headers_iterator, headers_iterator>headers()const;
33-
std::future<std::string>read_body(std::size_t length)const;
32+
response(const response &other)
33+
: status_(other.status_)
34+
, version_(other.version_)
35+
, status_message_(other.status_message_)
36+
, headers_(other.headers_) {
37+
38+
}
39+
40+
response(response &&other)noexcept
41+
: status_(std::move(other.status_))
42+
, version_(std::move(other.version_))
43+
, status_message_(std::move(other.status_message_))
44+
, headers_(std::move(other.headers_)) {
45+
46+
}
47+
48+
response &operator= (response other) {
49+
other.swap(*this);
50+
return *this;
51+
}
52+
53+
voidswap(response &other)noexcept {
54+
std::swap(status_, other.status_);
55+
std::swap(version_, other.version_);
56+
std::swap(status_message_, other.status_message_);
57+
std::swap(headers_, other.headers_);
58+
}
59+
60+
std::uint16_tstatus()const {
61+
return status_;
62+
}
63+
64+
string_typestatus_message()const {
65+
return status_message_;
66+
}
67+
68+
boost::iterator_range<const_headers_iterator>headers()const {
69+
returnboost::make_iterator_range(std::begin(headers_),std::end(headers_));
70+
}
71+
72+
std::future<string_type>read_body(std::size_t length)const;
3473

3574
// destination
3675
// source
@@ -40,10 +79,19 @@ namespace network {
4079
// append_body
4180
// get_body
4281

82+
string_typeversion()const {
83+
return version_;
84+
}
85+
86+
private:
87+
88+
std::uint16_t status_;
89+
string_type version_, status_message_;
90+
headers_type headers_;
4391

4492
};
4593
}// namespace v2
4694
}// namespace http
4795
}// namespace network
4896

49-
#endif//__NETWORK_HTTP_V2_RESPONSE_INC__
97+
#endif//__NETWORK_HTTP_V2_CLIENT_RESPONSE_INC__

‎http/test/v2/client/CMakeLists.txt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
# http://www.boost.org/LICENSE_1_0.txt)
55

66
set(CPP-NETLIB_CLIENT_TESTS
7-
response_test
87
client_options_test
98
request_options_test
109
byte_source_test
10+
response_test
1111
request_test
12+
async_resolver_test
1213
client_test
1314
)
1415

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) 2013 by Glyn Matthews
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include<gtest/gtest.h>
7+
#include<boost/asio.hpp>
8+
#include<network/http/v2/client/connection/async_resolver.hpp>
9+
#include<iostream>
10+
11+
namespacehttp= network::http::v2;
12+
13+
TEST(async_resolver_test, resolve_localhost) {
14+
// server must be running on 127.0.0.1:80
15+
16+
boost::asio::io_service io_service;
17+
http::async_resolverresolver(io_service,false);
18+
resolver.resolve("127.0.0.1",80,
19+
[] (const boost::system::error_code &ec,
20+
const boost::iterator_range<http::async_resolver::resolver_iterator> &endpoints) {
21+
for (auto endpoint : endpoints) {
22+
std::cout <<"Endpoint" << std::endl;
23+
}
24+
});
25+
26+
io_service.run();
27+
}

‎http/test/v2/client/request_test.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TEST(request_test, stream_2) {
6262
"User-Agent: request_test\r\n", oss.str());
6363
}
6464

65-
TEST(request, read_headers) {
65+
TEST(request_test, read_headers) {
6666
http::request instance{network::uri{"http://www.example.com/path/to/resource/index.html"}};
6767
instance.set_version("1.1");
6868
instance.set_method("GET");
@@ -78,7 +78,7 @@ TEST(request, read_headers) {
7878
ASSERT_EQ("request_test", headers_it->second);
7979
}
8080

81-
TEST(request, clear_headers) {
81+
TEST(request_test, clear_headers) {
8282
http::request instance{network::uri{"http://www.example.com/path/to/resource/index.html"}};
8383
instance.set_version("1.1");
8484
instance.set_method("GET");
@@ -89,7 +89,7 @@ TEST(request, clear_headers) {
8989
ASSERT_TRUE(std::begin(headers) ==std::end(headers));
9090
}
9191

92-
TEST(request, remove_headers) {
92+
TEST(request_test, remove_headers) {
9393
http::request instance{network::uri{"http://www.example.com/path/to/resource/index.html"}};
9494
instance.set_version("1.1");
9595
instance.set_method("GET");
@@ -106,7 +106,7 @@ TEST(request, remove_headers) {
106106
ASSERT_TRUE(headers_it ==std::end(headers));
107107
}
108108

109-
TEST(request, remove_duplicate_headers) {
109+
TEST(request_test, remove_duplicate_headers) {
110110
http::request instance{network::uri{"http://www.example.com/path/to/resource/index.html"}};
111111
instance.set_version("1.1");
112112
instance.set_method("GET");

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp