Skip to content

Commit

Permalink
More complete response functionality.
Browse files Browse the repository at this point in the history
In this commit we add rudimentary header processing. The equality check
is not exactly correct as it's completely plausible that two different
response instances have different merged headers, but for the meantime
we're banking on internal equality rather than semantic equality.

What needs to happen to fix this is to add a little bit of
caching/merging logic to make sure that we're able to actually merge the
actual headers waiting in the future with the added headers manually
along with the removed headers, and compare those instead. Unfortunately
that's too much work for now and it's not really necessary at this time.
  • Loading branch information
deanberris committed Mar 15, 2012
1 parent 4ea2034 commit fcf4888
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
43 changes: 37 additions & 6 deletions boost/network/protocol/http/response/response.ipp
Expand Up @@ -8,8 +8,7 @@
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/network/protocol/http/response/response.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <set>

namespace boost { namespace network { namespace http {

Expand Down Expand Up @@ -52,19 +51,44 @@ struct response_pimpl {

void append_header(std::string const & name,
std::string const & value) {
// FIXME do something!
added_headers_.insert(std::make_pair(name, value));
}

void remove_headers(std::string const &name) {
// FIXME do something!
removed_headers_.insert(name);
}

void remove_headers() {
// FIXME do something!
if (headers_future_.get_state() == future_state::uninitialized) {
promise<std::multimap<std::string, std::string> > headers_promise;
headers_promise.set_value(std::multimap<std::string, std::string>());
unique_future<std::multimap<std::string, std::string> > tmp =
headers_promise.get_future();
std::multimap<std::string, std::string>().swap(added_headers_);
std::set<std::string>().swap(removed_headers_);
headers_future_ = move(tmp);
}
}

void get_headers(
function<void(std::string const &, std::string const &)> inserter) { /* FIXME: Do something! */ }
function<void(std::string const &, std::string const &)> inserter) {
std::multimap<std::string, std::string>::const_iterator it;
if (headers_future_.get_state() == future_state::uninitialized) {
it = added_headers_.begin();
for (;it != added_headers_.end(); ++it) {
if (removed_headers_.find(it->first) == removed_headers_.end()) {
inserter(it->first, it->second);
}
}
} else {
it = headers_future_.get().begin();
for (;it != headers_future_.get().end(); ++it) {
if (removed_headers_.find(it->first) == removed_headers_.end()) {
inserter(it->first, it->second);
}
}
}
}
void get_headers(
std::string const & name,
function<void(std::string const &, std::string const &)> inserter) { /* FIXME: Do something! */ }
Expand Down Expand Up @@ -237,6 +261,8 @@ struct response_pimpl {
if (other.body_future_.get_state() != future_state::uninitialized)
return false;
}
if (other.added_headers_ != added_headers_ || other.removed_headers_ != removed_headers_)
return false;
return true;
}

Expand All @@ -249,6 +275,9 @@ struct response_pimpl {
mutable shared_future<std::string> status_message_future_;
mutable shared_future<std::string> version_future_;
mutable shared_future<std::string> body_future_;
// TODO: use unordered_map and unordered_set here.
std::multimap<std::string, std::string> added_headers_;
std::set<std::string> removed_headers_;

response_pimpl(response_pimpl const &other)
: source_future_(other.source_future_)
Expand All @@ -258,6 +287,8 @@ struct response_pimpl {
, status_message_future_(other.status_message_future_)
, version_future_(other.version_future_)
, body_future_(other.body_future_)
, added_headers_(other.added_headers_)
, removed_headers_(other.removed_headers_)
{}
};

Expand Down
40 changes: 40 additions & 0 deletions libs/network/test/http/response_test.cpp
Expand Up @@ -29,3 +29,43 @@ BOOST_AUTO_TEST_CASE(response_value_semantics_test) {
original = copy;
BOOST_CHECK(original == copy);
}

struct multimap_inserter {
void operator()(std::string const &name, std::string const &value) const {
multimap_.insert(std::make_pair(name, value));
}
explicit multimap_inserter(std::multimap<std::string, std::string> &multimap)
: multimap_(multimap)
{}
std::multimap<std::string,std::string> & multimap_;
};

BOOST_AUTO_TEST_CASE(response_setters_and_getters_test) {
http::response response;
response.set_source("http://www.google.com/");
response.set_destination("127.0.0.1");
response.append_header("Connection", "close");
response.append_header("Content-Type", "text/plain");
response.set_body("Hello, World!");
response.set_status(200u);
response.set_status_message("OK");
response.set_version("HTTP/1.1");
std::string source, destination, body, status_message, version;
std::multimap<std::string, std::string> headers, expected_headers;
expected_headers.insert(std::make_pair("Connection", "close"));
expected_headers.insert(std::make_pair("Content-Type", "text/plain"));
boost::uint16_t status;
response.get_source(source);
response.get_destination(destination);
response.get_body(body);
response.get_status_message(status_message);
response.get_version(version);
response.get_headers(multimap_inserter(headers));
response.get_status(status);
BOOST_CHECK_EQUAL(source, std::string("http://www.google.com/"));
BOOST_CHECK_EQUAL(destination, std::string("127.0.0.1"));
BOOST_CHECK_EQUAL(body, std::string("Hello, World!"));
BOOST_CHECK_EQUAL(status, 200u);
BOOST_CHECK_EQUAL(version, std::string("HTTP/1.1"));
BOOST_CHECK(expected_headers == headers);
}

0 comments on commit fcf4888

Please sign in to comment.