Skip to content

Commit 43f56f3

Browse files
committed
Additional cases for request_test.
This is just an incremental test case that uses a little of the mix between the pimpl held in the request and the native storage that is part of the request_storage_base from which the request derives from. This is the default implementation and it's possible to implement a different request type that uses different internal storage (probably a better idea for mmap-io backed storage, etc.).
1 parent 2c69f64 commit 43f56f3

File tree

5 files changed

+194
-33
lines changed

5 files changed

+194
-33
lines changed

boost/network/protocol/http/request/request.ipp

Lines changed: 159 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <boost/network/protocol/http/request/request.hpp>
1111
#include <boost/network/protocol/http/request/request_concept.hpp>
12+
#include <boost/scoped_array.hpp>
1213

1314
#ifdef BOOST_NETWORK_DEBUG
1415
BOOST_CONCEPT_ASSERT((boost::network::http::ClientRequest<boost::network::http::request>));
@@ -21,6 +22,9 @@ struct request_pimpl {
2122

2223
explicit request_pimpl(std::string const & url)
2324
: uri_(url)
25+
, read_offset_(0)
26+
, source_()
27+
, headers_()
2428
{}
2529

2630
request_pimpl* clone() {
@@ -31,14 +35,78 @@ struct request_pimpl {
3135
uri_ = uri;
3236
}
3337

38+
void set_uri(uri::uri const & uri) {
39+
uri_ = uri;
40+
}
41+
3442
void get_uri(std::string &uri) {
3543
uri = uri_.string();
3644
}
3745

46+
void get_uri(uri::uri &uri) {
47+
uri = uri_;
48+
}
49+
50+
void append_header(std::string const & name, std::string const & value) {
51+
headers_.insert(std::make_pair(name, value));
52+
}
53+
54+
void get_headers(function<bool(std::string const &, std::string const &)> predicate,
55+
function<void(std::string const &, std::string const &)> inserter) const {
56+
headers_type::const_iterator it = headers_.begin();
57+
for (; it != headers_.end(); ++it) {
58+
if (predicate(it->first, it->second)) {
59+
inserter(it->first, it->second);
60+
}
61+
}
62+
}
63+
64+
void get_headers(function<void(std::string const &, std::string const &)> inserter) const {
65+
headers_type::const_iterator it = headers_.begin();
66+
for (; it != headers_.end(); ++it) {
67+
inserter(it->first, it->second);
68+
}
69+
}
70+
71+
void get_headers(std::string const &name,
72+
function<void(std::string const &, std::string const &)> inserter) const {
73+
headers_type::const_iterator it = headers_.begin();
74+
for (; it != headers_.end(); ++it) {
75+
if (it->first == name) {
76+
inserter(it->first, it->second);
77+
}
78+
}
79+
}
80+
81+
void set_source(std::string const &source) {
82+
source_ = source;
83+
}
84+
85+
void get_source(std::string &source) const {
86+
source = source_;
87+
}
88+
89+
size_t read_offset() const {
90+
return read_offset_;
91+
}
92+
93+
void advance_read_offset(size_t bytes) {
94+
read_offset_ += bytes;
95+
}
96+
3897
private:
98+
typedef std::multimap<std::string, std::string> headers_type;
99+
39100
uri::uri uri_;
101+
size_t read_offset_;
102+
std::string source_;
103+
headers_type headers_;
104+
40105
request_pimpl(request_pimpl const &other)
41106
: uri_(other.uri_)
107+
, read_offset_(other.read_offset_)
108+
, source_(other.source_)
109+
, headers_(other.headers_)
42110
{}
43111
};
44112

@@ -68,47 +136,113 @@ void request::swap(request & other) {
68136

69137
// From message_base...
70138
// Mutators
71-
void request::set_destination(std::string const & destination){}
72-
void request::set_source(std::string const & source){}
139+
void request::set_destination(std::string const & destination) {
140+
}
141+
142+
void request::set_source(std::string const & source) {
143+
pimpl_->set_source(source);
144+
}
145+
73146
void request::append_header(std::string const & name,
74-
std::string const & value){}
75-
void request::remove_headers(std::string const & name){}
76-
void request::remove_headers(){}
77-
void request::set_body(std::string const & body){}
78-
void request::append_body(std::string const & data){}
147+
std::string const & value) {
148+
pimpl_->append_header(name, value);
149+
}
150+
151+
void request::remove_headers(std::string const & name) {
152+
}
153+
154+
void request::remove_headers() {
155+
}
156+
157+
void request::set_body(std::string const & body) {
158+
this->clear();
159+
this->append(body.data(), body.size());
160+
}
161+
162+
void request::append_body(std::string const & data) {
163+
this->append(data.data(), data.size());
164+
}
79165

80166
// Retrievers
81-
void request::get_destination(std::string & destination) const{}
82-
void request::get_source(std::string & source) const{}
83-
void request::get_headers(function<void(std::string const &, std::string const &)> inserter) const{}
84-
void request::get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) const{}
85-
void request::get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) const{}
86-
void request::get_body(std::string & body) const{}
87-
void request::get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) const{}
167+
void request::get_destination(std::string & destination) const {
168+
}
169+
170+
void request::get_source(std::string & source) const {
171+
pimpl_->get_source(source);
172+
}
173+
174+
void request::get_headers(function<void(std::string const &, std::string const &)> inserter) const {
175+
pimpl_->get_headers(inserter);
176+
}
177+
178+
void request::get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) const {
179+
pimpl_->get_headers(name, inserter);
180+
}
181+
182+
void request::get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) const {
183+
pimpl_->get_headers(predicate, inserter);
184+
}
185+
186+
void request::get_body(std::string & body) const {
187+
this->flatten(body);
188+
}
189+
190+
void request::get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) const {
191+
scoped_array<char> local_buffer(new (std::nothrow) char[size]);
192+
size_t bytes_read = this->read(local_buffer.get(),
193+
pimpl_->read_offset(),
194+
size);
195+
pimpl_->advance_read_offset(bytes_read);
196+
char const * begin = local_buffer.get();
197+
char const * end = local_buffer.get() + bytes_read;
198+
chunk_reader(make_iterator_range(begin, end));
199+
}
88200

89201
// From request_base...
90202
// Setters
91-
void request::set_method(std::string const & method){}
92-
void request::set_status(std::string const & status){}
93-
void request::set_status_message(std::string const & status_message){}
94-
void request::set_body_writer(function<void(char*, size_t)> writer){}
203+
void request::set_method(std::string const & method) {
204+
}
205+
206+
void request::set_status(std::string const & status) {
207+
}
208+
209+
void request::set_status_message(std::string const & status_message) {
210+
}
211+
212+
void request::set_body_writer(function<void(char*, size_t)> writer) {
213+
}
214+
95215
void request::set_uri(std::string const &uri) {
96216
pimpl_->set_uri(uri);
97217
}
98-
void request::set_uri(network::uri::uri const &uri){}
218+
219+
void request::set_uri(network::uri::uri const &uri) {
220+
pimpl_->set_uri(uri);
221+
}
99222

100223
// Getters
101-
void request::get_uri(network::uri::uri &uri) const{}
224+
void request::get_uri(network::uri::uri &uri) const {
225+
pimpl_->get_uri(uri);
226+
}
102227

103228
void request::get_uri(std::string &uri) const {
104229
pimpl_->get_uri(uri);
105230
}
106231

107-
void request::get_method(std::string & method) const{}
108-
void request::get_status(std::string & status) const{}
109-
void request::get_status_message(std::string & status_message) const{}
110-
void request::get_body(function<void(char*, size_t)> chunk_reader) const{}
111-
void request::get_body(std::string const & body) const{}
232+
void request::get_method(std::string & method) const {
233+
}
234+
235+
void request::get_status(std::string & status) const {
236+
}
237+
238+
void request::get_status_message(std::string & status_message) const {
239+
}
240+
241+
void request::get_body(function<void(char*, size_t)> chunk_reader) const {
242+
}
243+
244+
void request::get_body(std::string const & body) const {
245+
}
112246

113247
} // namespace http
114248

boost/network/protocol/http/request/request_base.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ struct request_storage_base {
2727
protected:
2828
request_storage_base(size_t chunk_size = BOOST_NETWORK_BUFFER_CHUNK);
2929
virtual void append(char const *data, size_t size);
30-
virtual size_t read(char *destination, size_t offset, size_t size);
31-
virtual void flatten(std::string &destination);
30+
virtual size_t read(char *destination, size_t offset, size_t size) const;
31+
virtual void flatten(std::string &destination) const;
3232
virtual void clear();
3333
virtual ~request_storage_base();
3434

boost/network/protocol/http/request/request_base.ipp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ request_base::~request_base() {
2020
struct request_storage_base_pimpl {
2121
request_storage_base_pimpl(size_t chunk_size);
2222
void append(char const *data, size_t size);
23-
size_t read(char *destination, size_t offset, size_t size);
24-
void flatten(std::string &destination);
23+
size_t read(char *destination, size_t offset, size_t size) const;
24+
void flatten(std::string &destination) const;
2525
void clear();
2626
request_storage_base_pimpl clone() const;
2727
~request_storage_base_pimpl();
@@ -45,11 +45,11 @@ void request_storage_base::append(char const *data, size_t size) {
4545
pimpl_->append(data, size);
4646
}
4747

48-
size_t request_storage_base::read(char *destination, size_t offset, size_t size) {
48+
size_t request_storage_base::read(char *destination, size_t offset, size_t size) const {
4949
return pimpl_->read(destination, offset, size);
5050
}
5151

52-
void request_storage_base::flatten(std::string &destination) {
52+
void request_storage_base::flatten(std::string &destination) const {
5353
pimpl_->flatten(destination);
5454
}
5555

@@ -90,7 +90,7 @@ void request_storage_base_pimpl::append(char const *data, size_t size) {
9090
}
9191
}
9292

93-
size_t request_storage_base_pimpl::read(char *destination, size_t offset, size_t size) {
93+
size_t request_storage_base_pimpl::read(char *destination, size_t offset, size_t size) const {
9494
if (chunks_.empty()) return 0;
9595
// First we find which chunk we're going to read from using the provided
9696
// offset and some arithmetic to determine the correct one.
@@ -114,7 +114,7 @@ size_t request_storage_base_pimpl::read(char *destination, size_t offset, size_t
114114
return read_count;
115115
}
116116

117-
void request_storage_base_pimpl::flatten(std::string &destination) {
117+
void request_storage_base_pimpl::flatten(std::string &destination) const {
118118
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
119119
for (; chunk_iterator != chunks_.end(); ++chunk_iterator) {
120120
destination.append(chunk_iterator->first, chunk_iterator->second);

libs/network/test/http/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ if (Boost_FOUND)
2626
target_link_libraries(cpp-netlib-http-${test}
2727
${Boost_LIBRARIES}
2828
cppnetlib-message
29+
cppnetlib-message-wrappers
2930
cppnetlib-uri
3031
cppnetlib-http-message)
3132
set_target_properties(cpp-netlib-http-${test}

libs/network/test/http/request_test.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66

77
#define BOOST_TEST_MODULE HTTP Request Test
88
#include <boost/network/protocol/http/request.hpp>
9+
#include <boost/network/message/wrappers.hpp>
910
#include <boost/test/unit_test.hpp>
1011

1112
namespace http = boost::network::http;
13+
namespace uri = boost::network::uri;
14+
namespace net = boost::network;
1215

1316
BOOST_AUTO_TEST_CASE(request_construction) {
1417
http::request request;
@@ -25,3 +28,26 @@ BOOST_AUTO_TEST_CASE(request_uri_test) {
2528
BOOST_CHECK_EQUAL(std::string("http://www.google.com/"), original);
2629
BOOST_CHECK_EQUAL(original, copied);
2730
}
31+
32+
BOOST_AUTO_TEST_CASE(request_basics_test) {
33+
http::request request;
34+
request.set_uri("http://www.google.com/");
35+
request.set_source("127.0.0.1");
36+
request.set_destination("http://www.google.com/");
37+
request.append_header("X-Referer", "http://cpp-netlib.github.com/");
38+
request.append_header("Connection", "close");
39+
request.append_body("The quick brown fox jumps over the lazy dog!");
40+
41+
uri::uri uri_;
42+
std::string source_, destination_, body_;
43+
net::headers_wrapper::range_type headers_range = headers(request);
44+
request.get_uri(uri_);
45+
request.get_source(source_);
46+
request.get_destination(destination_);
47+
request.get_body(body_);
48+
49+
BOOST_CHECK_EQUAL(uri_.string(), std::string("http://www.google.com/"));
50+
BOOST_CHECK_EQUAL(source_, std::string("127.0.0.1"));
51+
BOOST_CHECK_EQUAL(body_, std::string("The quick brown fox jumps over the lazy dog!"));
52+
BOOST_CHECK(!boost::empty(headers_range));
53+
}

0 commit comments

Comments
 (0)