Skip to content

Commit

Permalink
Additional cases for request_test.
Browse files Browse the repository at this point in the history
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.).
  • Loading branch information
deanberris committed Mar 13, 2012
1 parent 2c69f64 commit 43f56f3
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 33 deletions.
184 changes: 159 additions & 25 deletions boost/network/protocol/http/request/request.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <boost/network/protocol/http/request/request.hpp>
#include <boost/network/protocol/http/request/request_concept.hpp>
#include <boost/scoped_array.hpp>

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

explicit request_pimpl(std::string const & url)
: uri_(url)
, read_offset_(0)
, source_()
, headers_()
{}

request_pimpl* clone() {
Expand All @@ -31,14 +35,78 @@ struct request_pimpl {
uri_ = uri;
}

void set_uri(uri::uri const & uri) {
uri_ = uri;
}

void get_uri(std::string &uri) {
uri = uri_.string();
}

void get_uri(uri::uri &uri) {
uri = uri_;
}

void append_header(std::string const & name, std::string const & value) {
headers_.insert(std::make_pair(name, value));
}

void get_headers(function<bool(std::string const &, std::string const &)> predicate,
function<void(std::string const &, std::string const &)> inserter) const {
headers_type::const_iterator it = headers_.begin();
for (; it != headers_.end(); ++it) {
if (predicate(it->first, it->second)) {
inserter(it->first, it->second);
}
}
}

void get_headers(function<void(std::string const &, std::string const &)> inserter) const {
headers_type::const_iterator it = headers_.begin();
for (; it != headers_.end(); ++it) {
inserter(it->first, it->second);
}
}

void get_headers(std::string const &name,
function<void(std::string const &, std::string const &)> inserter) const {
headers_type::const_iterator it = headers_.begin();
for (; it != headers_.end(); ++it) {
if (it->first == name) {
inserter(it->first, it->second);
}
}
}

void set_source(std::string const &source) {
source_ = source;
}

void get_source(std::string &source) const {
source = source_;
}

size_t read_offset() const {
return read_offset_;
}

void advance_read_offset(size_t bytes) {
read_offset_ += bytes;
}

private:
typedef std::multimap<std::string, std::string> headers_type;

uri::uri uri_;
size_t read_offset_;
std::string source_;
headers_type headers_;

request_pimpl(request_pimpl const &other)
: uri_(other.uri_)
, read_offset_(other.read_offset_)
, source_(other.source_)
, headers_(other.headers_)
{}
};

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

// From message_base...
// Mutators
void request::set_destination(std::string const & destination){}
void request::set_source(std::string const & source){}
void request::set_destination(std::string const & destination) {
}

void request::set_source(std::string const & source) {
pimpl_->set_source(source);
}

void request::append_header(std::string const & name,
std::string const & value){}
void request::remove_headers(std::string const & name){}
void request::remove_headers(){}
void request::set_body(std::string const & body){}
void request::append_body(std::string const & data){}
std::string const & value) {
pimpl_->append_header(name, value);
}

void request::remove_headers(std::string const & name) {
}

void request::remove_headers() {
}

void request::set_body(std::string const & body) {
this->clear();
this->append(body.data(), body.size());
}

void request::append_body(std::string const & data) {
this->append(data.data(), data.size());
}

// Retrievers
void request::get_destination(std::string & destination) const{}
void request::get_source(std::string & source) const{}
void request::get_headers(function<void(std::string const &, std::string const &)> inserter) const{}
void request::get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) const{}
void request::get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) const{}
void request::get_body(std::string & body) const{}
void request::get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) const{}
void request::get_destination(std::string & destination) const {
}

void request::get_source(std::string & source) const {
pimpl_->get_source(source);
}

void request::get_headers(function<void(std::string const &, std::string const &)> inserter) const {
pimpl_->get_headers(inserter);
}

void request::get_headers(std::string const & name, function<void(std::string const &, std::string const &)> inserter) const {
pimpl_->get_headers(name, inserter);
}

void request::get_headers(function<bool(std::string const &, std::string const &)> predicate, function<void(std::string const &, std::string const &)> inserter) const {
pimpl_->get_headers(predicate, inserter);
}

void request::get_body(std::string & body) const {
this->flatten(body);
}

void request::get_body(function<void(iterator_range<char const *>)> chunk_reader, size_t size) const {
scoped_array<char> local_buffer(new (std::nothrow) char[size]);
size_t bytes_read = this->read(local_buffer.get(),
pimpl_->read_offset(),
size);
pimpl_->advance_read_offset(bytes_read);
char const * begin = local_buffer.get();
char const * end = local_buffer.get() + bytes_read;
chunk_reader(make_iterator_range(begin, end));
}

// From request_base...
// Setters
void request::set_method(std::string const & method){}
void request::set_status(std::string const & status){}
void request::set_status_message(std::string const & status_message){}
void request::set_body_writer(function<void(char*, size_t)> writer){}
void request::set_method(std::string const & method) {
}

void request::set_status(std::string const & status) {
}

void request::set_status_message(std::string const & status_message) {
}

void request::set_body_writer(function<void(char*, size_t)> writer) {
}

void request::set_uri(std::string const &uri) {
pimpl_->set_uri(uri);
}
void request::set_uri(network::uri::uri const &uri){}

void request::set_uri(network::uri::uri const &uri) {
pimpl_->set_uri(uri);
}

// Getters
void request::get_uri(network::uri::uri &uri) const{}
void request::get_uri(network::uri::uri &uri) const {
pimpl_->get_uri(uri);
}

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

void request::get_method(std::string & method) const{}
void request::get_status(std::string & status) const{}
void request::get_status_message(std::string & status_message) const{}
void request::get_body(function<void(char*, size_t)> chunk_reader) const{}
void request::get_body(std::string const & body) const{}
void request::get_method(std::string & method) const {
}

void request::get_status(std::string & status) const {
}

void request::get_status_message(std::string & status_message) const {
}

void request::get_body(function<void(char*, size_t)> chunk_reader) const {
}

void request::get_body(std::string const & body) const {
}

} // namespace http

Expand Down
4 changes: 2 additions & 2 deletions boost/network/protocol/http/request/request_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ struct request_storage_base {
protected:
request_storage_base(size_t chunk_size = BOOST_NETWORK_BUFFER_CHUNK);
virtual void append(char const *data, size_t size);
virtual size_t read(char *destination, size_t offset, size_t size);
virtual void flatten(std::string &destination);
virtual size_t read(char *destination, size_t offset, size_t size) const;
virtual void flatten(std::string &destination) const;
virtual void clear();
virtual ~request_storage_base();

Expand Down
12 changes: 6 additions & 6 deletions boost/network/protocol/http/request/request_base.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ request_base::~request_base() {
struct request_storage_base_pimpl {
request_storage_base_pimpl(size_t chunk_size);
void append(char const *data, size_t size);
size_t read(char *destination, size_t offset, size_t size);
void flatten(std::string &destination);
size_t read(char *destination, size_t offset, size_t size) const;
void flatten(std::string &destination) const;
void clear();
request_storage_base_pimpl clone() const;
~request_storage_base_pimpl();
Expand All @@ -45,11 +45,11 @@ void request_storage_base::append(char const *data, size_t size) {
pimpl_->append(data, size);
}

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

void request_storage_base::flatten(std::string &destination) {
void request_storage_base::flatten(std::string &destination) const {
pimpl_->flatten(destination);
}

Expand Down Expand Up @@ -90,7 +90,7 @@ void request_storage_base_pimpl::append(char const *data, size_t size) {
}
}

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

void request_storage_base_pimpl::flatten(std::string &destination) {
void request_storage_base_pimpl::flatten(std::string &destination) const {
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
for (; chunk_iterator != chunks_.end(); ++chunk_iterator) {
destination.append(chunk_iterator->first, chunk_iterator->second);
Expand Down
1 change: 1 addition & 0 deletions libs/network/test/http/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ if (Boost_FOUND)
target_link_libraries(cpp-netlib-http-${test}
${Boost_LIBRARIES}
cppnetlib-message
cppnetlib-message-wrappers
cppnetlib-uri
cppnetlib-http-message)
set_target_properties(cpp-netlib-http-${test}
Expand Down
26 changes: 26 additions & 0 deletions libs/network/test/http/request_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

#define BOOST_TEST_MODULE HTTP Request Test
#include <boost/network/protocol/http/request.hpp>
#include <boost/network/message/wrappers.hpp>
#include <boost/test/unit_test.hpp>

namespace http = boost::network::http;
namespace uri = boost::network::uri;
namespace net = boost::network;

BOOST_AUTO_TEST_CASE(request_construction) {
http::request request;
Expand All @@ -25,3 +28,26 @@ BOOST_AUTO_TEST_CASE(request_uri_test) {
BOOST_CHECK_EQUAL(std::string("http://www.google.com/"), original);
BOOST_CHECK_EQUAL(original, copied);
}

BOOST_AUTO_TEST_CASE(request_basics_test) {
http::request request;
request.set_uri("http://www.google.com/");
request.set_source("127.0.0.1");
request.set_destination("http://www.google.com/");
request.append_header("X-Referer", "http://cpp-netlib.github.com/");
request.append_header("Connection", "close");
request.append_body("The quick brown fox jumps over the lazy dog!");

uri::uri uri_;
std::string source_, destination_, body_;
net::headers_wrapper::range_type headers_range = headers(request);
request.get_uri(uri_);
request.get_source(source_);
request.get_destination(destination_);
request.get_body(body_);

BOOST_CHECK_EQUAL(uri_.string(), std::string("http://www.google.com/"));
BOOST_CHECK_EQUAL(source_, std::string("127.0.0.1"));
BOOST_CHECK_EQUAL(body_, std::string("The quick brown fox jumps over the lazy dog!"));
BOOST_CHECK(!boost::empty(headers_range));
}

0 comments on commit 43f56f3

Please sign in to comment.