Skip to content

Commit b89a276

Browse files
committed
Fixing implementation of message wrappers to put the IP address in the request passed to the HTTP server.
1 parent 0f692fe commit b89a276

File tree

6 files changed

+69
-31
lines changed

6 files changed

+69
-31
lines changed

boost/network/protocol/http/connection.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace boost { namespace network { namespace http {
7979

8080
void handle_read_headers(boost::system::error_code const &ec, size_t bytes_transferred) {
8181
if (!ec) {
82+
request_.source = socket_.remote_endpoint().address().to_string();
8283
boost::tribool done;
8384
boost::array<char, BOOST_HTTP_SERVER_BUFFER_SIZE>::iterator new_start;
8485
tie(done,new_start) = parser_.parse_headers(request_, buffer_.data(), buffer_.data() + bytes_transferred);

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

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ namespace boost { namespace network { namespace http {
129129
typedef string<tags::http_server>::type string_type;
130130
typedef vector<tags::http_server>::apply<request_header>::type vector_type;
131131
typedef boost::uint16_t port_type;
132+
string_type source;
132133
string_type method;
133134
string_type uri;
134135
boost::uint8_t http_version_major;

boost/network/protocol/http/message/wrappers/source.hpp

+57-28
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <boost/network/protocol/http/response_concept.hpp>
1010
#include <boost/network/protocol/http/request_concept.hpp>
11+
#include <boost/mpl/if.hpp>
1112
#include <boost/concept/requires.hpp>
1213

1314
namespace boost { namespace network { namespace http {
@@ -18,36 +19,64 @@ namespace boost { namespace network { namespace http {
1819
template <class Tag>
1920
struct basic_request;
2021

21-
namespace impl {
22-
23-
template <class Message>
24-
struct source_wrapper {
25-
typedef typename string<typename Message::tag>::type string_type;
26-
Message const & message_;
27-
source_wrapper(Message const & message)
28-
: message_(message) {}
29-
source_wrapper(source_wrapper const & other)
30-
: message_(other.message_) {}
31-
operator string_type const () {
32-
return message_.source();
33-
}
34-
};
35-
36-
} // namespace impl
37-
38-
template <class Tag>
39-
inline BOOST_CONCEPT_REQUIRES(((Response<basic_response<Tag> >)),
40-
(impl::source_wrapper<basic_response<Tag> > const))
41-
source(basic_response<Tag> const & message) {
42-
return impl::source_wrapper<basic_response<Tag> >(message);
22+
#define BOOST_NETWORK_DEFINE_HTTP_WRAPPER(name, accessor) \
23+
struct name##_pod_accessor { \
24+
protected: \
25+
template <class Message> \
26+
typename Message::string_type const & \
27+
get_value(Message const & message) const { \
28+
return message.accessor; \
29+
} \
30+
}; \
31+
\
32+
struct name##_member_accessor { \
33+
protected: \
34+
template <class Message> \
35+
typename Message::string_type \
36+
get_value(Message const & message) const { \
37+
return message.accessor(); \
38+
} \
39+
}; \
40+
\
41+
template <class Tag> \
42+
struct name##_wrapper_impl : \
43+
mpl::if_< \
44+
is_base_of<tags::pod, Tag>, \
45+
name##_pod_accessor, \
46+
name##_member_accessor \
47+
> \
48+
{}; \
49+
\
50+
template <class Message> \
51+
struct name##_wrapper : \
52+
name##_wrapper_impl<typename Message::tag>::type { \
53+
typedef typename string<typename Message::tag>::type \
54+
string_type; \
55+
Message const & message_; \
56+
name##_wrapper(Message const & message) \
57+
: message_(message) {} \
58+
name##_wrapper(name##_wrapper const & other) \
59+
: message_(other.message_) {} \
60+
operator string_type const () { \
61+
return this->get_value(message_); \
62+
} \
63+
}; \
64+
\
65+
template <class Tag> \
66+
inline BOOST_CONCEPT_REQUIRES(((Response<basic_response<Tag> >)), \
67+
(name##_wrapper<basic_response<Tag> > const)) \
68+
name (basic_response<Tag> const & message) { \
69+
return name##_wrapper<basic_response<Tag> >(message); \
70+
} \
71+
\
72+
template <class Tag> \
73+
inline BOOST_CONCEPT_REQUIRES(((Request<basic_request<Tag> >)), \
74+
(name##_wrapper<basic_request<Tag> > const)) \
75+
name (basic_request<Tag> const & message) { \
76+
return name##_wrapper<basic_request<Tag> >(message); \
4377
}
4478

45-
template <class Tag>
46-
inline BOOST_CONCEPT_REQUIRES(((Request<basic_request<Tag> >)),
47-
(impl::source_wrapper<basic_request<Tag> > const))
48-
source(basic_request<Tag> const & message) {
49-
return impl::source_wrapper<basic_request<Tag> >(message);
50-
}
79+
BOOST_NETWORK_DEFINE_HTTP_WRAPPER(source, source);
5180

5281
} // namespace http
5382

boost/network/tags.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
namespace boost { namespace network { namespace tags {
1717

18+
struct pod {};
1819
struct async {};
1920
struct http {};
2021
struct tcp {};
@@ -33,7 +34,7 @@ namespace boost { namespace network { namespace tags {
3334
typedef mpl::vector<http, keepalive, sync, udp, default_string> http_keepalive_8bit_udp_resolve_tags;
3435
typedef mpl::vector<http, simple, async, udp, default_string> http_async_8bit_udp_resolve_tags;
3536
typedef mpl::vector<http, simple, async, tcp, default_string> http_async_8bit_tcp_resolve_tags;
36-
typedef mpl::vector<http, simple, sync, default_string> http_server_tags;
37+
typedef mpl::vector<http, simple, sync, pod, default_string> http_server_tags;
3738

3839
template <class Tag>
3940
struct components;
@@ -44,7 +45,7 @@ namespace boost { namespace network { namespace tags {
4445
name##_tags, \
4546
mpl::inherit<mpl::placeholders::_1, mpl::placeholders::_2> \
4647
>::type name; \
47-
template <> struct components<name> { typedef name##_tags type; }; \
48+
template <> struct components<name> { typedef name##_tags type; };
4849

4950
BOOST_NETWORK_DEFINE_TAG(http_default_8bit_tcp_resolve);
5051
BOOST_NETWORK_DEFINE_TAG(http_default_8bit_udp_resolve);

libs/network/example/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ set(Boost_USE_MULTITHREADED ON)
1414
if (Boost_FOUND)
1515
add_executable(http_client http_client.cpp)
1616
add_executable(simple_wget simple_wget.cpp)
17+
add_executable(hello_world_server http/hello_world_server.cpp)
1718
add_executable(uri uri.cpp)
1819
target_link_libraries(http_client ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES} )
1920
target_link_libraries(simple_wget ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES} )
21+
target_link_libraries(hello_world_server ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES} )
2022
set_target_properties(http_client PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/example)
2123
set_target_properties(simple_wget PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/example)
24+
set_target_properties(hello_world_server PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/example)
2225
set_target_properties(uri PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/example)
2326
endif()

libs/network/example/http/hello_world_server.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ struct hello_world {
2828
/*<< This is the function that handles the incoming request. >>*/
2929
void operator() (server::request const &request,
3030
server::response &response) {
31+
server::string_type ip = source(request);
32+
std::ostringstream data;
33+
data << "Hello, " << ip << "!";
3134
response = server::response::stock_reply(
32-
server::response::ok, "Hello, World!");
35+
server::response::ok, data.str());
3336
}
3437
/*<< It's necessary to define a log function, but it's ignored in
3538
this example. >>*/

0 commit comments

Comments
 (0)