Skip to content

Commit 93954e5

Browse files
committed
Refactoring implementation of the HTTP Connections for HTTP/HTTPS async behavior, supporting POD types in the Request and Response models.
1 parent ac1648b commit 93954e5

25 files changed

+763
-489
lines changed

boost/network/message/directives.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ namespace boost { namespace network {
2323
return message_;
2424
}
2525

26-
BOOST_NETWORK_STRING_DIRECTIVE(source, source_, message.source(source_));
27-
BOOST_NETWORK_STRING_DIRECTIVE(destination, destination_, message.destination(destination_));
28-
BOOST_NETWORK_STRING_DIRECTIVE(body, body_, message.body(body_));
26+
BOOST_NETWORK_STRING_DIRECTIVE(source, source_, message.source(source_), message.source=source_);
27+
BOOST_NETWORK_STRING_DIRECTIVE(destination, destination_, message.destination(destination_), message.destination=destination_);
28+
BOOST_NETWORK_STRING_DIRECTIVE(body, body_, message.body(body_), message.body=body_);
2929

3030
} // namespace network
3131

boost/network/message/directives/detail/string_directive.hpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ namespace boost { namespace network { namespace detail {
3333
* setting the source of a message would look something like this given the
3434
* BOOST_NETWORK_STRING_DIRECTIVE macro:
3535
*
36-
* BOOST_NETWORK_STRING_DIRECTIVE(source, source_, message.source(source_));
36+
* BOOST_NETWORK_STRING_DIRECTIVE(source, source_,
37+
* message.source(source_)
38+
* , message.source=source_);
3739
*
3840
*/
3941
template <class Base>
@@ -63,12 +65,13 @@ namespace boost { namespace network { namespace detail {
6365
}
6466
};
6567

66-
#define BOOST_NETWORK_STRING_DIRECTIVE(name, value, body) \
68+
#define BOOST_NETWORK_STRING_DIRECTIVE(name, value, body, pod_body) \
6769
struct name##_directive_base { \
70+
\
6871
template <class Message> \
69-
struct string_visitor : boost::static_visitor<> { \
72+
struct normal_visitor : boost::static_visitor<> { \
7073
Message const & message; \
71-
explicit string_visitor(Message const & message) : \
74+
explicit normal_visitor(Message const & message) : \
7275
message(message) {} \
7376
void operator()( \
7477
typename boost::network::detail::string_value< \
@@ -79,8 +82,51 @@ namespace boost { namespace network { namespace detail {
7982
} \
8083
template <class T> void operator()(T const &) const { \
8184
} \
85+
}; \
86+
\
87+
template <class Message> \
88+
struct pod_visitor : boost::static_visitor<> { \
89+
Message const & message; \
90+
explicit pod_visitor(Message const & message) : \
91+
message(message) {} \
92+
void operator()( \
93+
typename boost::network::detail::string_value< \
94+
typename Message::tag \
95+
>::type const & value \
96+
) const { \
97+
pod_body; \
98+
} \
99+
template <class T> void operator()(T const &) const { \
100+
} \
101+
}; \
102+
\
103+
template <class Message> \
104+
struct string_visitor : \
105+
mpl::if_< \
106+
is_base_of< \
107+
tags::pod, \
108+
typename Message::tag \
109+
>, \
110+
pod_visitor<Message>, \
111+
normal_visitor<Message> \
112+
>::type \
113+
{ \
114+
typedef typename mpl::if_< \
115+
is_base_of< \
116+
tags::pod, \
117+
typename Message::tag \
118+
>, \
119+
pod_visitor<Message>, \
120+
normal_visitor<Message> \
121+
>::type base; \
122+
explicit string_visitor(Message const & message): \
123+
base(message) {} \
124+
string_visitor(string_visitor const & other): \
125+
base(other) {} \
126+
using base::operator(); \
82127
}; \
83128
}; \
129+
\
84130
typedef boost::network::detail::string_directive<name##_directive_base> \
85131
name##_directive; \
86132
template <class T> inline name##_directive const \

boost/network/message/directives/header.hpp

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
// Copyright Dean Michael Berris 2007.
2+
// Copyright Dean Michael Berris 2007-2010.
33
// Distributed under the Boost Software License, Version 1.0.
44
// (See accompanying file LICENSE_1_0.txt or copy at
55
// http://www.boost.org/LICENSE_1_0.txt)
@@ -18,38 +18,68 @@
1818
#include <boost/variant/static_visitor.hpp>
1919

2020
namespace boost { namespace network {
21+
22+
namespace impl {
2123

22-
namespace impl {
24+
template <class KeyType, class ValueType>
25+
struct header_directive {
2326

24-
template <class KeyType, class ValueType>
25-
struct header_directive {
27+
explicit header_directive(KeyType const & header_name,
28+
ValueType const & header_value) :
29+
_header_name(header_name),
30+
_header_value(header_value)
31+
{ };
2632

27-
explicit header_directive(KeyType const & header_name,
28-
ValueType const & header_value) :
29-
_header_name(header_name),
30-
_header_value(header_value)
31-
{ };
33+
template <class Message>
34+
struct pod_directive {
35+
template <class T1, class T2>
36+
static void eval(Message const & message, T1 const & key, T2 const & value) {
37+
typedef typename Message::headers_container_type::value_type value_type;
38+
value_type value_ = { key, value };
39+
message.headers.insert(message.headers.end(), value_);
40+
}
41+
};
3242

33-
template <class Message>
34-
void operator() (Message const & msg) const {
35-
typedef typename Message::headers_container_type::value_type value_type;
36-
msg.add_header(value_type(_header_name, _header_value));
37-
}
43+
template <class Message>
44+
struct normal_directive {
45+
template <class T1, class T2>
46+
static void eval(Message const & message, T1 const & key, T2 const & value) {
47+
typedef typename Message::headers_container_type::value_type value_type;
48+
message.add_header(value_type(key, value));
49+
}
50+
};
51+
52+
template <class Message>
53+
struct directive_impl :
54+
mpl::if_<
55+
is_base_of<
56+
tags::pod,
57+
typename Message::tag
58+
>,
59+
pod_directive<Message>,
60+
normal_directive<Message>
61+
>::type
62+
{};
63+
64+
template <class Message>
65+
void operator() (Message const & msg) const {
66+
typedef typename Message::headers_container_type::value_type value_type;
67+
directive_impl<Message>::eval(msg, _header_name, _header_value);
68+
}
3869

39-
private:
70+
private:
4071

41-
KeyType const & _header_name;
42-
ValueType const & _header_value;
43-
};
44-
} // namespace impl
72+
KeyType const & _header_name;
73+
ValueType const & _header_value;
74+
};
4575

46-
template <class T1, class T2>
47-
inline impl::header_directive<T1, T2>
48-
header(T1 const & header_name,
49-
T2 const & header_value) {
50-
return impl::header_directive<T1, T2>(header_name,
51-
header_value);
52-
}
76+
} // namespace impl
77+
78+
template <class T1, class T2>
79+
inline impl::header_directive<T1, T2>
80+
header(T1 const & header_name, T2 const & header_value) {
81+
return impl::header_directive<T1, T2>(header_name, header_value);
82+
}
5383
} // namespace network
5484
} // namespace boost
5585

boost/network/message/modifiers/add_header.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ namespace boost { namespace network {
2727
message.add_header(std::make_pair(key, value));
2828
}
2929

30+
template <class Message, class KeyType, class ValueType, class Async>
31+
inline void add_header(Message const & message, KeyType const & key, ValueType const & value, tags::http_server const &, Async const &) {
32+
typedef typename Message::headers_container_type::value_type value_type;
33+
value_type header_ = { key, value };
34+
message.headers.insert(message.headers.end(), header_);
35+
}
36+
3037
}
3138

3239
template <class Tag, template <class> class Message, class KeyType, class ValueType>

boost/network/message/modifiers/body.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ namespace boost { namespace network {
2323
message.body(body_);
2424
}
2525

26+
template <class Message, class ValueType, class Async>
27+
inline void body(Message const & message, ValueType const & body_, tags::http_server, Async) {
28+
message.body = body_;
29+
}
30+
2631
} // namespace impl
2732

2833
template <class Tag, template <class> class Message, class ValueType>

boost/network/message/modifiers/clear_headers.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,29 @@
1212
namespace boost { namespace network {
1313

1414
namespace impl {
15-
template <class Message>
16-
inline void clear_headers(Message const & message, mpl::false_ const &) {
15+
template <class Message, class Tag>
16+
inline void clear_headers(Message const & message, Tag const &, mpl::false_ const &) {
1717
(typename Message::headers_container_type()).swap(message.headers());
1818
}
1919

20-
template <class Message>
21-
inline void clear_headers(Message const & message, mpl::true_ const &) {
20+
template <class Message, class Tag>
21+
inline void clear_headers(Message const & message, Tag const &, mpl::true_ const &) {
2222
boost::promise<typename Message::headers_container_type> header_promise;
2323
boost::shared_future<typename Message::headers_container_type> headers_future(header_promise.get_future());
2424
message.headers(headers_future);
2525
header_promise.set_value(typename Message::headers_container_type());
2626
}
2727

28+
template <class Message, class Async>
29+
inline void clear_headers(Message const & message, tags::http_server const &, Async const &) {
30+
(typename Message::headers_container_type()).swap(message.headers);
31+
}
32+
2833
} // namespace impl
2934

3035
template <class Tag, template <class> class Message>
3136
inline void clear_headers(Message<Tag> const & message) {
32-
impl::clear_headers(message, is_async<Tag>());
37+
impl::clear_headers(message, Tag(), is_async<Tag>());
3338
}
3439

3540
} // namespace network

boost/network/message/modifiers/destination.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ namespace boost { namespace network {
2323
inline void destination(Message const & message, ValueType const & destination_, Tag const &, mpl::true_ const &) {
2424
message.destination(destination_);
2525
}
26+
27+
template <class Message, class ValueType, class Async>
28+
inline void destination(Message const & message, ValueType const & destination_, tags::http_server, Async) {
29+
message.destination = destination_;
30+
}
2631
}
2732

2833
template <class Tag, template<class> class Message, class ValueType>

boost/network/message/modifiers/remove_header.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// http://www.boost.org/LICENSE_1_0.txt)
99

1010
#include <boost/network/support/is_async.hpp>
11+
#include <algorithm>
1112

1213
namespace boost { namespace network {
1314

@@ -28,6 +29,30 @@ namespace boost { namespace network {
2829
message.remove_header(key);
2930
}
3031

32+
template <class KeyType>
33+
struct equals {
34+
explicit equals(KeyType const & key_)
35+
: key(key_) {}
36+
equals(equals const & other)
37+
: key(other.key) {}
38+
template <class RequestHeader>
39+
bool operator()(RequestHeader const & header) {
40+
return boost::iequals(header.name, key);
41+
}
42+
KeyType const & key;
43+
};
44+
45+
template <class Message, class KeyType, class Async>
46+
inline void remove_header(Message const & message, KeyType const & key, tags::http_server const &, Async const &) {
47+
typedef typename Message::headers_container_type::iterator iterator;
48+
iterator end = message.headers.end();
49+
iterator new_end = std::remove_if(
50+
message.headers.begin(),
51+
message.headers.end(),
52+
equals<KeyType>(key));
53+
message.headers.erase(new_end, end);
54+
}
55+
3156
} // namespace impl
3257

3358
template <class Tag, template <class> class Message, class KeyType>

boost/network/message/modifiers/source.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ namespace boost { namespace network {
2323
message.source(source_);
2424
}
2525

26+
template <class Message, class ValueType, class Async>
27+
inline void source(Message const & message, ValueType const & source_, tags::http_server const &, Async const &) {
28+
message.source = source_;
29+
}
30+
2631
} // namespace impl
2732

2833
template <class Tag, template <class> class Message, class ValueType>

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ namespace boost { namespace network { namespace http { namespace impl {
2525
typedef basic_response<Tag> response;
2626

2727
static boost::shared_ptr<async_connection_base<Tag,version_major,version_minor> > new_connection(resolve_function resolve, boost::shared_ptr<resolver_type> resolver, bool follow_redirect, bool https) {
28+
boost::shared_ptr<async_connection_base<Tag,version_major,version_minor> > temp;
2829
if (https) {
2930
#ifdef BOOST_NETWORK_ENABLE_HTTPS
30-
// FIXME fill this up with the HTTPS implementation.
31-
// return dynamic_cast<async_connection_base<Tag,version_major,version_minor>*>(new https_async_connection<Tag,version_major,version_minor>(resolve, resolver, follow_redirect));
31+
temp.reset(new https_async_connection<Tag,version_major,version_minor>(resolver, resolve, follow_redirect));
32+
return temp;
3233
#else
3334
throw std::runtime_error("HTTPS not supported.");
3435
#endif
3536
}
36-
boost::shared_ptr<async_connection_base<Tag,version_major,version_minor> > temp;
3737
temp.reset(new http_async_connection<Tag,version_major,version_minor>(resolver, resolve, follow_redirect));
3838
assert(temp.get() != 0);
3939
return temp;

0 commit comments

Comments
 (0)