From a2f2e8cca053534494bc1be411891d1310d83e12 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 28 Aug 2010 08:37:21 +0200 Subject: [PATCH 001/438] Used XMPP package with cpp-netlib 0.6 because there were too many changes on the 0.7 branch. Tests compile and succeed. --- boost/network/protocol/xmpp.hpp | 13 ++ boost/network/protocol/xmpp/client.hpp | 96 ++++++++++ boost/network/protocol/xmpp/details/ns.hpp | 72 ++++++++ boost/network/protocol/xmpp/directives.hpp | 38 ++++ .../protocol/xmpp/directives/attribute.hpp | 22 +++ .../protocol/xmpp/directives/destination.hpp | 22 +++ .../network/protocol/xmpp/directives/from.hpp | 22 +++ boost/network/protocol/xmpp/directives/id.hpp | 22 +++ .../protocol/xmpp/directives/namespace.hpp | 22 +++ .../protocol/xmpp/directives/source.hpp | 22 +++ .../network/protocol/xmpp/directives/text.hpp | 22 +++ boost/network/protocol/xmpp/directives/to.hpp | 22 +++ .../network/protocol/xmpp/directives/type.hpp | 41 +++++ boost/network/protocol/xmpp/element.hpp | 172 ++++++++++++++++++ boost/network/protocol/xmpp/element_io.hpp | 57 ++++++ boost/network/protocol/xmpp/errors.hpp | 22 +++ boost/network/protocol/xmpp/iq.hpp | 63 +++++++ boost/network/protocol/xmpp/message.hpp | 83 +++++++++ .../parser_backends/expat/element_parser.hpp | 126 +++++++++++++ .../parser_backends/expat/stanza_parser.hpp | 124 +++++++++++++ .../xmpp/parser_backends/expat_parser.hpp | 31 ++++ .../libxml2/element_parser.hpp | 129 +++++++++++++ .../parser_backends/libxml2/stanza_parser.hpp | 127 +++++++++++++ .../xmpp/parser_backends/libxml2_parser.hpp | 31 ++++ boost/network/protocol/xmpp/presence.hpp | 63 +++++++ boost/network/protocol/xmpp/stanza.hpp | 64 +++++++ .../protocol/xmpp/traits/element_children.hpp | 42 +++++ .../protocol/xmpp/traits/parser_backend.hpp | 41 +++++ libs/network/test/CMakeLists.txt | 36 ++++ .../test/xmpp/expat_element_parser_tests.cpp | 77 ++++++++ .../test/xmpp/expat_stanza_parser_tests.cpp | 61 +++++++ .../xmpp/libxml2_element_parser_tests.cpp | 77 ++++++++ .../test/xmpp/libxml2_stanza_parser_tests.cpp | 61 +++++++ libs/network/test/xmpp/xmpp_element_tests.cpp | 88 +++++++++ libs/network/test/xmpp/xmpp_iq_tests.cpp | 27 +++ libs/network/test/xmpp/xmpp_message_tests.cpp | 80 ++++++++ .../network/test/xmpp/xmpp_presence_tests.cpp | 27 +++ libs/network/test/xmpp/xmpp_stanza_tests.cpp | 10 + libs/network/test/xmpp/xmpp_uri_tests.cpp | 23 +++ 39 files changed, 2178 insertions(+) create mode 100644 boost/network/protocol/xmpp.hpp create mode 100644 boost/network/protocol/xmpp/client.hpp create mode 100644 boost/network/protocol/xmpp/details/ns.hpp create mode 100644 boost/network/protocol/xmpp/directives.hpp create mode 100644 boost/network/protocol/xmpp/directives/attribute.hpp create mode 100644 boost/network/protocol/xmpp/directives/destination.hpp create mode 100644 boost/network/protocol/xmpp/directives/from.hpp create mode 100644 boost/network/protocol/xmpp/directives/id.hpp create mode 100644 boost/network/protocol/xmpp/directives/namespace.hpp create mode 100644 boost/network/protocol/xmpp/directives/source.hpp create mode 100644 boost/network/protocol/xmpp/directives/text.hpp create mode 100644 boost/network/protocol/xmpp/directives/to.hpp create mode 100644 boost/network/protocol/xmpp/directives/type.hpp create mode 100644 boost/network/protocol/xmpp/element.hpp create mode 100644 boost/network/protocol/xmpp/element_io.hpp create mode 100644 boost/network/protocol/xmpp/errors.hpp create mode 100644 boost/network/protocol/xmpp/iq.hpp create mode 100644 boost/network/protocol/xmpp/message.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp create mode 100644 boost/network/protocol/xmpp/presence.hpp create mode 100644 boost/network/protocol/xmpp/stanza.hpp create mode 100644 boost/network/protocol/xmpp/traits/element_children.hpp create mode 100644 boost/network/protocol/xmpp/traits/parser_backend.hpp create mode 100644 libs/network/test/xmpp/expat_element_parser_tests.cpp create mode 100644 libs/network/test/xmpp/expat_stanza_parser_tests.cpp create mode 100644 libs/network/test/xmpp/libxml2_element_parser_tests.cpp create mode 100644 libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_element_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_iq_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_message_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_presence_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_uri_tests.cpp diff --git a/boost/network/protocol/xmpp.hpp b/boost/network/protocol/xmpp.hpp new file mode 100644 index 000000000..39bd5a4c1 --- /dev/null +++ b/boost/network/protocol/xmpp.hpp @@ -0,0 +1,13 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_INC__ + + + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp new file mode 100644 index 000000000..42e61f422 --- /dev/null +++ b/boost/network/protocol/xmpp/client.hpp @@ -0,0 +1,96 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ + + +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Handler, + class Tag + > +class basic_client : boost::noncopyable { +public: + + typedef typename string::type string_type; + + typedef basic_message message; + typedef basic_presence presence; + typedef basic_iq iq; + + explicit basic_client(Handler handler); + + ~basic_client(); + + void connect(const string_type &proxy_host, + const string_type &proxy_port); + + void disconnect(); + + void authenticate(const string_type &jid, + const string_type &password); + + void send_message(const message_type &message); + + void send_presence(const presence_type &presence); + + void send_iq(const iq_type &iq); + + string_type jid() const; + + string_type bound_jid() const; + +private: + + // tcp socket + // tls + // sasl + + // parameters, such as jid, bound_jid, domain, port etc. + + // io_service + + // xml parser + + // event handler + + // stream open handler + + // connection event handlers + + Handler handler_; + +}; + + + +template < + class Handler + > +struct client : basic_client { + + explicit client(Handler handler) : basic_client(handler) { + + } + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ diff --git a/boost/network/protocol/xmpp/details/ns.hpp b/boost/network/protocol/xmpp/details/ns.hpp new file mode 100644 index 000000000..c58c7747e --- /dev/null +++ b/boost/network/protocol/xmpp/details/ns.hpp @@ -0,0 +1,72 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace details { +class namespaces { +public: + + static const char *client() { + return "jabber:client"; + } + + static const char *component() { + return "jabber:component:accept"; + } + + static const char *streams() { + return "http://etherx.jabber.org/streams"; + } + + static const char *streams_ietf() { + return "urn:ietf:params:xml:ns:xmpp-streams"; + } + + static const char *tls() { + return "urn:ietf:params:xml:ns:xmpp-tls"; + } + + static const char *sasl() { + return "urn:ietf:params:xml:ns:xmpp-sasl"; + } + + static const char *bind() { + return "urn:ietf:params:xml:ns:xmpp-bind"; + } + + static const char *session() { + return "urn:ietf:params:xml:ns:xmpp-session"; + } + + static const char *auth() { + return "jabber:iq:auth"; + } + + static const char *disco_info() { + return "http://jabber.org/protocol/disco#info"; + } + + static const char *disco_items() { + return "http://jabber.org/protocol/disco#items"; + } + + static const char *roster() { + return "jabber:iq:roster"; + } +}; +} // namespace details +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ diff --git a/boost/network/protocol/xmpp/directives.hpp b/boost/network/protocol/xmpp/directives.hpp new file mode 100644 index 000000000..4d9b54c47 --- /dev/null +++ b/boost/network/protocol/xmpp/directives.hpp @@ -0,0 +1,38 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ + + +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag, + class Directive + > +inline +basic_stanza &operator << (basic_stanza &stanza, + const Directive &directive) { + directive(stanza); + return stanza; +} +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ diff --git a/boost/network/protocol/xmpp/directives/attribute.hpp b/boost/network/protocol/xmpp/directives/attribute.hpp new file mode 100644 index 000000000..528ed79a5 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/attribute.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ diff --git a/boost/network/protocol/xmpp/directives/destination.hpp b/boost/network/protocol/xmpp/directives/destination.hpp new file mode 100644 index 000000000..49991d230 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/destination.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ diff --git a/boost/network/protocol/xmpp/directives/from.hpp b/boost/network/protocol/xmpp/directives/from.hpp new file mode 100644 index 000000000..4bd0989a2 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/from.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ diff --git a/boost/network/protocol/xmpp/directives/id.hpp b/boost/network/protocol/xmpp/directives/id.hpp new file mode 100644 index 000000000..59b324c7f --- /dev/null +++ b/boost/network/protocol/xmpp/directives/id.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ diff --git a/boost/network/protocol/xmpp/directives/namespace.hpp b/boost/network/protocol/xmpp/directives/namespace.hpp new file mode 100644 index 000000000..90723783b --- /dev/null +++ b/boost/network/protocol/xmpp/directives/namespace.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ diff --git a/boost/network/protocol/xmpp/directives/source.hpp b/boost/network/protocol/xmpp/directives/source.hpp new file mode 100644 index 000000000..a09c5af3f --- /dev/null +++ b/boost/network/protocol/xmpp/directives/source.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ diff --git a/boost/network/protocol/xmpp/directives/text.hpp b/boost/network/protocol/xmpp/directives/text.hpp new file mode 100644 index 000000000..d334b38e4 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/text.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ diff --git a/boost/network/protocol/xmpp/directives/to.hpp b/boost/network/protocol/xmpp/directives/to.hpp new file mode 100644 index 000000000..fa722f5f2 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/to.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ diff --git a/boost/network/protocol/xmpp/directives/type.hpp b/boost/network/protocol/xmpp/directives/type.hpp new file mode 100644 index 000000000..72e2f160a --- /dev/null +++ b/boost/network/protocol/xmpp/directives/type.hpp @@ -0,0 +1,41 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace details { +template < + typename T + > +struct type_directive { + + explicit type_directive(T type) + : type_(type) { + + } + + template < + class MessageTag + > + void operator () (basic_message &message) const { + message.type() = type_; + } + + T type_; + +}; +} // namespace details +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp new file mode 100644 index 000000000..22f0e3c4a --- /dev/null +++ b/boost/network/protocol/xmpp/element.hpp @@ -0,0 +1,172 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_element { + +public: + + struct tag {}; + struct text {}; + + typedef typename string::type string_type; + typedef typename headers_container::type headers_container_type; + typedef typename element_children::type element_children_type; + + basic_element() { + + } + + basic_element(tag, const string_type &name) + : name_(name) { + + } + + basic_element(text, const string_type &text) + : text_(text) { + + } + + basic_element(const basic_element &other) + : name_(other.name_), + attributes_(other.attributes_), + children_(other.children_), + text_(other.text_) { + + } + + basic_element &operator = (const basic_element &other) { + basic_element tmp(other); + swap(tmp); + return *this; + } + + ~basic_element() { + + } + + void swap(basic_element &other) { + std::swap(name_, other.name_); + std::swap(attributes_, other.attributes_); + std::swap(children_, other.children_); + std::swap(text_, other.text_); + } + + void set_name(const string_type &name) { + assert(!is_text()); + name_ = name; + } + + string_type get_name() const { + assert(is_tag()); + return name_; + } + + void set_text(const string_type &text) { + assert(!is_tag()); + text_ = text; + } + + boost::optional get_text() const { + assert(is_text()); + return text_.get(); + } + + bool is_tag() const { + return !name_.empty(); + } + + bool is_text() const { + return static_cast(text_); + } + + void set_attribute(const string_type &name, const string_type &value) { + assert(is_tag()); + attributes_.insert(typename headers_container_type::value_type(name, value)); + } + + boost::optional get_attribute(const string_type &name) const { + typename headers_container_type::const_iterator it = attributes_.find(name); + if (it != attributes_.end()) { + return it->second; + } + return boost::none; + } + + boost::iterator_range + get_attributes() const { + return boost::make_iterator_range(boost::begin(attributes_), + boost::end(attributes_)); + } + + boost::optional get_namespace() const { + return get_attribute("xmlns"); + } + + boost::optional get_type() const { + return get_attribute("type"); + } + + boost::optional get_lang() const { + return get_attribute("xml:lang"); + } + + boost::optional get_id() const { + return get_attribute("id"); + } + + void add_child(basic_element *element) { + assert(is_tag()); + boost::shared_ptr > shared_element(element); + children_.push_back(shared_element); + } + + boost::iterator_range + get_children() const { + return boost::make_iterator_range(boost::begin(children_), + boost::end(children_)); + } + +private: + + // if it's a tag node + string_type name_; + headers_container_type attributes_; + element_children_type children_; + + // if it's a text node + boost::optional text_; + +}; + + +typedef basic_element element; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp new file mode 100644 index 000000000..72924ec96 --- /dev/null +++ b/boost/network/protocol/xmpp/element_io.hpp @@ -0,0 +1,57 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +std::ostream &operator << (std::ostream &os, + const basic_element &element) { + if (element.is_tag()) { + os << "<" << element.get_name(); + boost::iterator_range::headers_container_type::const_iterator> + attributes(element.get_attributes()); + + typename basic_element::headers_container_type::const_iterator + attr_it(boost::begin(attributes)), + attr_end(boost::end(attributes)); + for (; attr_it != attr_end; ++attr_it) { + os << " " << attr_it->first << "=\"" << attr_it->second << "\""; + } + os << ">"; + + boost::iterator_range::element_children_type::const_iterator> + children(element.get_children()); + + typename basic_element::element_children_type::const_iterator + child_it(boost::begin(children)), + child_end(boost::end(children)); + for (; child_it != child_end; ++child_it) { + os << **child_it; + } + os << ""; + } + else { + os << element.get_text().get(); + } + return os; +} +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/boost/network/protocol/xmpp/errors.hpp b/boost/network/protocol/xmpp/errors.hpp new file mode 100644 index 000000000..5acbcbc06 --- /dev/null +++ b/boost/network/protocol/xmpp/errors.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +enum errors { + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp new file mode 100644 index 000000000..7ee8a95d7 --- /dev/null +++ b/boost/network/protocol/xmpp/iq.hpp @@ -0,0 +1,63 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_iq + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_iq() { + + } + + basic_iq(const basic_iq &other) + : basic_stanza(other) { + + } + + basic_iq &operator = (const basic_iq &other) { + basic_iq tmp(other); + swap(tmp); + return *this; + } + + ~basic_iq() { + + } + + void swap(basic_iq &other) { + base_type::swap(other); + } + +}; + + +typedef basic_iq iq; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp new file mode 100644 index 000000000..915e9c42b --- /dev/null +++ b/boost/network/protocol/xmpp/message.hpp @@ -0,0 +1,83 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_message + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_message() { + + } + + basic_message(const basic_message &other) + : basic_stanza(other) { + + } + + basic_message &operator = (const basic_message &other) { + basic_message tmp(other); + swap(tmp); + return *this; + } + + ~basic_message() { + + } + + void swap(basic_message &other) { + base_type::swap(other); + } + + void set_type(const string_type &type) { + static const char *type_ = "type"; + set_attribute(string_type(type_, type_ + std::strlen(type_)), type); + } + + string_type type() const { + static const char *type_ = "type"; + return attribute(string_type(type_, type_ + std::strlen(type_))); + } + + void set_id(const string_type &id) { + static const char *id_ = "id"; + set_attribute(string_type(id_, id_ + std::strlen(id_)), id); + } + + string_type id() const { + static const char *id_ = "id"; + return attribute(string_type(id_, id_ + std::strlen(id_))); + } + +}; + + +typedef basic_message message; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp new file mode 100644 index 000000000..0721d9da4 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp @@ -0,0 +1,126 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_element_parser { +public: + + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_expat_element_parser() { + parser_ = XML_ParserCreate(NULL); + // handle the case where the parser is NULL + element_ = 0; + depth_ = 0; + + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, start_element, end_element); + XML_SetCharacterDataHandler(parser_, cdata); + } + + ~basic_expat_element_parser() { + XML_ParserFree(parser_); + } + + bool feed(const string_type &chunk) { + return feed(chunk, 0); + } + + bool feed(const string_type &chunk, element_type *element) { + element_ = element; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + +private: + + static void set_name(element_type *element, const XML_Char *name) { + const XML_Char *name_begin = name; + const XML_Char *name_end = name_begin + std::strlen(name_begin); + + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(element_type *element, const XML_Char **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const XML_Char *key_begin = attrs[i]; + const XML_Char *key_end = key_begin + std::strlen(key_begin); + + const XML_Char *val_begin = attrs[i + 1]; + const XML_Char *val_end = val_begin + std::strlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const XML_Char *name, + const XML_Char **attrs) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->element_, name); + set_attributes(parser->element_, attrs); + } + else if (parser->depth_ > 1) { + element_type *child = new element_type; + set_name(child, name); + set_attributes(child, attrs); + parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const XML_Char *name) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void cdata(void *userdata, + const XML_Char *s, + int len) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + parser->element_->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + XML_Parser parser_; + element_type *element_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp new file mode 100644 index 000000000..80bbeea39 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp @@ -0,0 +1,124 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_stanza_parser { +public: + + typedef typename string::type string_type; + + typedef basic_stanza stanza_type; + + basic_expat_stanza_parser() { + parser_ = XML_ParserCreate(NULL); + // handle the case where the parser is NULL + stanza_ = 0; + depth_ = 0; + + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, start_element, end_element); + XML_SetCharacterDataHandler(parser_, cdata); + } + + ~basic_expat_stanza_parser() { + XML_ParserFree(parser_); + } + + bool feed(const string_type &chunk) { + stanza_ = 0; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + stanza_ = &stanza; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + +private: + + static void set_name(stanza_type *stanza, const XML_Char *name) { + const XML_Char *name_begin = name; + const XML_Char *name_end = name_begin + std::strlen(name_begin); + + stanza->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(stanza_type *stanza, const XML_Char **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const XML_Char *key_begin = attrs[i]; + const XML_Char *key_end = key_begin + std::strlen(key_begin); + + const XML_Char *val_begin = attrs[i + 1]; + const XML_Char *val_end = val_begin + std::strlen(val_begin); + + stanza->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const XML_Char *name, + const XML_Char **attrs) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->stanza_, name); + set_attributes(parser->stanza_, attrs); + } + else if (parser->depth_ > 1) { + // element_type *child = new element_type; + // set_name(child, name); + // set_attributes(child, attrs); + // parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const XML_Char *name) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void cdata(void *userdata, + const XML_Char *s, + int len) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + } + + XML_Parser parser_; + stanza_type *stanza_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp new file mode 100644 index 000000000..48c3aa1f1 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp @@ -0,0 +1,31 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_parser + : public basic_expat_element_parser { + +public: + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp new file mode 100644 index 000000000..53a628743 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp @@ -0,0 +1,129 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_element_parser { + +public: + + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_libxml2_element_parser() { + std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); + handlers_.startElement = start_element; + handlers_.endElement = end_element; + handlers_.characters = characters; + depth_ = 0; + element_ = 0; + + context_ = xmlCreatePushParserCtxt(&handlers_, + this, 0, 0, 0); + // assert(!context_); + } + + ~basic_libxml2_element_parser() { + xmlFreeParserCtxt(context_); + } + + bool feed(const string_type &chunk) { + return feed(chunk, 0); + } + + bool feed(const string_type &chunk, element_type *element) { + element_ = element; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + +private: + + static void set_name(element_type *element, const xmlChar *name) { + const xmlChar *name_begin = name; + const xmlChar *name_end = name_begin + xmlStrlen(name_begin); + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(basic_element *element, const xmlChar **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const xmlChar *key_begin = attrs[i]; + const xmlChar *key_end = key_begin + xmlStrlen(key_begin); + + const xmlChar *val_begin = attrs[i + 1]; + const xmlChar *val_end = val_begin + xmlStrlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const xmlChar *name, + const xmlChar **attrs) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->element_, name); + set_attributes(parser->element_, attrs); + } + else if (parser->depth_ > 1) { + element_type *child = new element_type; + set_name(child, name); + set_attributes(child, attrs); + parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const xmlChar *name) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void characters(void *userdata, + const xmlChar *s, + int len) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + parser->element_->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + xmlParserCtxtPtr context_; + xmlSAXHandler handlers_; + element_type *element_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp new file mode 100644 index 000000000..8f40fa77b --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp @@ -0,0 +1,127 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_stanza_parser { + +public: + + typedef typename string::type string_type; + + typedef basic_stanza stanza_type; + + basic_libxml2_stanza_parser() { + std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); + handlers_.startElement = start_element; + handlers_.endElement = end_element; + handlers_.characters = characters; + depth_ = 0; + stanza_ = 0; + + context_ = xmlCreatePushParserCtxt(&handlers_, + this, 0, 0, 0); + // assert(!context_); + } + + ~basic_libxml2_stanza_parser() { + xmlFreeParserCtxt(context_); + } + + bool feed(const string_type &chunk) { + stanza_ = 0; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + stanza_ = &stanza; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + +private: + + static void set_name(stanza_type *stanza, const xmlChar *name) { + const xmlChar *name_begin = name; + const xmlChar *name_end = name_begin + xmlStrlen(name_begin); + stanza->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(basic_stanza *stanza, const xmlChar **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const xmlChar *key_begin = attrs[i]; + const xmlChar *key_end = key_begin + xmlStrlen(key_begin); + + const xmlChar *val_begin = attrs[i + 1]; + const xmlChar *val_end = val_begin + xmlStrlen(val_begin); + + stanza->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const xmlChar *name, + const xmlChar **attrs) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->stanza_, name); + set_attributes(parser->stanza_, attrs); + } + else if (parser->depth_ > 1) { + // element_type *child = new element_type; + // set_name(child, name); + // set_attributes(child, attrs); + // parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const xmlChar *name) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void characters(void *userdata, + const xmlChar *s, + int len) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + } + + xmlParserCtxtPtr context_; + xmlSAXHandler handlers_; + stanza_type *stanza_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp new file mode 100644 index 000000000..799c0ed2d --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp @@ -0,0 +1,31 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_parser + : public basic_libxml2_element_parser { + +public: + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp new file mode 100644 index 000000000..60ba2aa2e --- /dev/null +++ b/boost/network/protocol/xmpp/presence.hpp @@ -0,0 +1,63 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_presence + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_presence() { + + } + + basic_presence(const basic_presence &other) + : basic_stanza(other) { + + } + + basic_presence &operator = (const basic_presence &other) { + basic_presence tmp(other); + swap(tmp); + return *this; + } + + ~basic_presence() { + + } + + void swap(basic_presence &other) { + base_type::swap(other); + } + +}; + + +typedef basic_presence presence; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp new file mode 100644 index 000000000..b3d06ebad --- /dev/null +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -0,0 +1,64 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_stanza + : public boost::network::basic_message { + + typedef boost::network::basic_message base_type; + +public: + + typedef typename base_type::string_type string_type; + + void set_name(const string_type &name) { + name_ = name; + } + + string_type name() const { + return name_; + } + + void set_attribute(const string_type &key, const string_type &value) { + this->headers().insert(std::make_pair(key, value)); + } + + string_type attribute(const string_type &key) const { + typename headers_range >::type range + = this->headers().equal_range(key); + if (boost::begin(range) == boost::end(range)) { + return string_type(); + } + + return boost::begin(range)->second; + } + +private: + + string_type name_; + +}; + + +typedef basic_stanza stanza; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ diff --git a/boost/network/protocol/xmpp/traits/element_children.hpp b/boost/network/protocol/xmpp/traits/element_children.hpp new file mode 100644 index 000000000..a2692c881 --- /dev/null +++ b/boost/network/protocol/xmpp/traits/element_children.hpp @@ -0,0 +1,42 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ + + +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_element; + + +template < + class Tag + > +struct element_children { + typedef unsupported_tag type; +}; + + +template <> +struct element_children { + typedef std::list > > type; +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ diff --git a/boost/network/protocol/xmpp/traits/parser_backend.hpp b/boost/network/protocol/xmpp/traits/parser_backend.hpp new file mode 100644 index 000000000..7ab680a8b --- /dev/null +++ b/boost/network/protocol/xmpp/traits/parser_backend.hpp @@ -0,0 +1,41 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_parser; + + +template < + class Tag + > +struct parser_backend { + typedef unsupported_tag type; +}; + + +template <> +struct parser_backend { + typedef basic_expat_parser type; +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index b2810641d..72f9dfd55 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -10,6 +10,8 @@ include_directories(${OPENSSL_INCLUDE_DIR}) find_package( Threads ) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) +find_package( EXPAT ) +find_package( LibXml2 ) if (Boost_FOUND) add_executable(cpp-netlib-hello_world hello_world.cpp) @@ -39,5 +41,39 @@ if (Boost_FOUND) add_test(cpp-netlib-message_test ../../../build/tests/cpp-netlib-message_test) add_test(cpp-netlib-http_message_test ../../../build/tests/cpp-netlib-http_message_test) add_test(cpp-netlib-url_test ../../../build/tests/cpp-netlib-url_test) + + add_executable(cpp-netlib-xmpp_element_tests xmpp/xmpp_element_tests.cpp) + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_element_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + add_test(cpp-netlib-xmpp_element_tests ../../../build/tests/cpp-netlib-xmpp_element_tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + + if (EXPAT_FOUND) + include_directories( ${EXPAT_INCLUDE_DIRS} ) + add_executable(cpp-netlib-expat_element_parser_tests xmpp/expat_element_parser_tests.cpp) + add_executable(cpp-netlib-expat_stanza_parser_tests xmpp/expat_stanza_parser_tests.cpp) + target_link_libraries(cpp-netlib-expat_element_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-expat_element_parser_tests ../../../build/tests/cpp-netlib-expat_element_parser_tests) + add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + endif() + + if (LIBXML2_FOUND) + include_directories( ${LIBXML2_INCLUDE_DIR} ) + add_executable(cpp-netlib-libxml2_element_parser_tests xmpp/libxml2_element_parser_tests.cpp) + add_executable(cpp-netlib-libxml2_stanza_parser_tests xmpp/libxml2_stanza_parser_tests.cpp) + target_link_libraries(cpp-netlib-libxml2_element_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parserg_tests) + add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parserg_tests) + endif() + endif() diff --git a/libs/network/test/xmpp/expat_element_parser_tests.cpp b/libs/network/test/xmpp/expat_element_parser_tests.cpp new file mode 100644 index 000000000..6b13f0505 --- /dev/null +++ b/libs/network/test/xmpp/expat_element_parser_tests.cpp @@ -0,0 +1,77 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +basic_expat_element_parser element_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + element_parser.feed(""); + } + + ~xml_document_fixture() { + element_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("body", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("show", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("iq", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); +} diff --git a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp new file mode 100644 index 000000000..cf9dafe92 --- /dev/null +++ b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp @@ -0,0 +1,61 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::message; +using boost::network::xmpp::presence; +using boost::network::xmpp::iq; + + +basic_expat_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.name()); + BOOST_CHECK_EQUAL("foo", instance.attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + iq instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("iq", instance.name()); + BOOST_CHECK_EQUAL("bar", instance.attribute("to")); +} diff --git a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp b/libs/network/test/xmpp/libxml2_element_parser_tests.cpp new file mode 100644 index 000000000..4723d8ef5 --- /dev/null +++ b/libs/network/test/xmpp/libxml2_element_parser_tests.cpp @@ -0,0 +1,77 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +basic_libxml2_parser libxml2_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + libxml2_parser.feed(""); + } + + ~xml_document_fixture() { + libxml2_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("body", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("show", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("iq", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); +} diff --git a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp new file mode 100644 index 000000000..f2242df34 --- /dev/null +++ b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp @@ -0,0 +1,61 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::message; +using boost::network::xmpp::presence; +using boost::network::xmpp::iq; + + +basic_libxml2_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.name()); + BOOST_CHECK_EQUAL("foo", instance.attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + iq instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("iq", instance.name()); + BOOST_CHECK_EQUAL("bar", instance.attribute("to")); +} diff --git a/libs/network/test/xmpp/xmpp_element_tests.cpp b/libs/network/test/xmpp/xmpp_element_tests.cpp new file mode 100644 index 000000000..9dcf60c41 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_element_tests.cpp @@ -0,0 +1,88 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP element tests +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +BOOST_AUTO_TEST_CASE(default_constructor_test) { + element instance; + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(!instance.is_text()); +} + + +BOOST_AUTO_TEST_CASE(tag_constructor_test) { + element instance(element::tag(), "message"); + BOOST_CHECK(instance.is_tag()); + BOOST_CHECK(!instance.is_text()); + BOOST_CHECK_EQUAL(instance.get_name(), std::string("message")); +} + + +BOOST_AUTO_TEST_CASE(text_constructor_test) { + element instance(element::text(), "data"); + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(instance.is_text()); + BOOST_CHECK(instance.get_text()); + BOOST_CHECK_EQUAL(instance.get_text().get(), std::string("data")); +} + + +BOOST_AUTO_TEST_CASE(text_constructor_empty_string_test) { + element instance(element::text(), ""); + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(instance.is_text()); + BOOST_CHECK(instance.get_text().get().empty()); +} + + +BOOST_AUTO_TEST_CASE(children_test) { + element instance(element::tag(), "message"); + instance.set_attribute("from", "someone@example.org"); + instance.set_attribute("to", "world@example.org"); + element *body = new element(element::tag(), "body"); + element *text = new element(element::text(), "Hello world!"); + body->add_child(text); + instance.add_child(body); + + boost::iterator_range + children_1(instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children_1), + boost::end(children_1)), 1); + + boost::iterator_range + children_2((*boost::begin(children_1))->get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children_2), + boost::end(children_2)), 1); + BOOST_CHECK((*boost::begin(children_2))->is_text()); + BOOST_CHECK_EQUAL((*boost::begin(children_2))->get_text(), std::string("Hello world!")); +} + + +BOOST_AUTO_TEST_CASE(element_ostream_test) { + element instance(element::tag(), "message"); + instance.set_attribute("from", "someone@example.org"); + instance.set_attribute("to", "world@example.org"); + element *body = new element(element::tag(), "body"); + element *text = new element(element::text(), "Hello world!"); + body->add_child(text); + instance.add_child(body); + + std::ostringstream os; + os << instance; + + BOOST_CHECK_EQUAL(os.str(), + std::string("" + "Hello world!")); +} diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp new file mode 100644 index 000000000..5a971a2c0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP iq tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::iq; + + +BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { + iq instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_iq_destination_directive_test) { + iq instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp new file mode 100644 index 000000000..0098a4450 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -0,0 +1,80 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP message tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::message; + + +BOOST_AUTO_TEST_CASE(xmpp_message_source_directive_test) { + message instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_destination_directive_test) { + message instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_header_directive_test) { + message instance; + instance << boost::network::header("type", "chat"); + BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); + boost::network::headers_range::type range + = boost::network::headers(instance)["type"]; + BOOST_CHECK (boost::begin(range) != boost::end(range)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_body_directive_test) { + message instance; + instance << boost::network::header("type", "chat") + << boost::network::body("Hello world!"); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_type_accessor_test) { + message instance; + instance.set_type("chat"); + BOOST_CHECK_EQUAL("chat", instance.type()); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { + message instance; + instance.set_id("t2w4qax3"); + BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); +} + + +// BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { +// message instance; +// instance << xmpp::type("chat"); +// BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); +// } +// +// +// BOOST_AUTO_TEST_CASE(xmpp_message_id_directive_test) { +// message instance; +// instance << xmpp::id("t2w4qax3"); +// BOOST_CHECK_EQUAL("t2w4qax3", xmpp::id(instance)); +// } +// +// +// BOOST_AUTO_TEST_CASE(xmpp_message_error_directive_test) { +// message instance; +// instance << boost::network::source("source@example.com") +// << boost::network::destination("dest@example.com") +// ; +// } diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp new file mode 100644 index 000000000..3997bd0db --- /dev/null +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP presence tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::presence; + + +BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { + presence instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_presence_destination_directive_test) { + presence instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp new file mode 100644 index 000000000..31288c95a --- /dev/null +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -0,0 +1,10 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP stanza tests +#include +#include diff --git a/libs/network/test/xmpp/xmpp_uri_tests.cpp b/libs/network/test/xmpp/xmpp_uri_tests.cpp new file mode 100644 index 000000000..6bd6bc36c --- /dev/null +++ b/libs/network/test/xmpp/xmpp_uri_tests.cpp @@ -0,0 +1,23 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include + +namespace xmpp = boost::network::uri::xmpp; + + +BOOST_AUTO_TEST_CASE(simple_uri_test) { + xmpp::uri uri("node@jabber.org"); + BOOST_CHECK(uri.to_string() == "node@jabber.org"); + BOOST_CHECK(uri.node() == "node"); + BOOST_CHECK(uri.domain() == "jabber.org"); + BOOST_CHECK(uri.resource().empty()); +} From ed524a1b41d5d08bdbd119540e9b080b7f3f0a7f Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 28 Aug 2010 11:27:10 +0200 Subject: [PATCH 002/438] Refactored XML element outside XMPP. --- boost/network/detail/xml_wrappers/element.hpp | 172 ++++++++++++++++++ .../detail/xml_wrappers/element_io.hpp | 57 ++++++ .../parser_backends/expat/element_parser.hpp | 12 +- .../parser_backends/expat/stanza_parser.hpp | 10 +- .../parser_backends/expat_parser.hpp | 12 +- .../libxml2/element_parser.hpp | 12 +- .../parser_backends/libxml2/stanza_parser.hpp | 10 +- .../parser_backends/libxml2_parser.hpp | 12 +- .../xml_wrappers}/traits/element_children.hpp | 10 +- .../xml_wrappers}/traits/parser_backend.hpp | 10 +- .../protocol/xmpp/{details => detail}/ns.hpp | 0 boost/network/protocol/xmpp/element.hpp | 160 +--------------- boost/network/protocol/xmpp/element_io.hpp | 45 +---- libs/network/test/CMakeLists.txt | 71 +++++--- .../expat_element_parser_tests.cpp | 10 +- .../libxml2_element_parser_tests.cpp | 10 +- .../xml_element_tests.cpp} | 10 +- 17 files changed, 338 insertions(+), 285 deletions(-) create mode 100644 boost/network/detail/xml_wrappers/element.hpp create mode 100644 boost/network/detail/xml_wrappers/element_io.hpp rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat/element_parser.hpp (90%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat/stanza_parser.hpp (91%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat_parser.hpp (53%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2/element_parser.hpp (90%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2/stanza_parser.hpp (92%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2_parser.hpp (53%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/traits/element_children.hpp (71%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/traits/parser_backend.hpp (71%) rename boost/network/protocol/xmpp/{details => detail}/ns.hpp (100%) rename libs/network/test/{xmpp => xml_wrappers}/expat_element_parser_tests.cpp (89%) rename libs/network/test/{xmpp => xml_wrappers}/libxml2_element_parser_tests.cpp (89%) rename libs/network/test/{xmpp/xmpp_element_tests.cpp => xml_wrappers/xml_element_tests.cpp} (92%) diff --git a/boost/network/detail/xml_wrappers/element.hpp b/boost/network/detail/xml_wrappers/element.hpp new file mode 100644 index 000000000..9300c59b3 --- /dev/null +++ b/boost/network/detail/xml_wrappers/element.hpp @@ -0,0 +1,172 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace detail { +template < + class Tag + > +class basic_element { + +public: + + struct tag {}; + struct text {}; + + typedef typename string::type string_type; + typedef typename headers_container::type headers_container_type; + typedef typename element_children::type element_children_type; + + basic_element() { + + } + + basic_element(tag, const string_type &name) + : name_(name) { + + } + + basic_element(text, const string_type &text) + : text_(text) { + + } + + basic_element(const basic_element &other) + : name_(other.name_), + attributes_(other.attributes_), + children_(other.children_), + text_(other.text_) { + + } + + basic_element &operator = (const basic_element &other) { + basic_element tmp(other); + swap(tmp); + return *this; + } + + ~basic_element() { + + } + + void swap(basic_element &other) { + std::swap(name_, other.name_); + std::swap(attributes_, other.attributes_); + std::swap(children_, other.children_); + std::swap(text_, other.text_); + } + + void set_name(const string_type &name) { + assert(!is_text()); + name_ = name; + } + + string_type get_name() const { + assert(is_tag()); + return name_; + } + + void set_text(const string_type &text) { + assert(!is_tag()); + text_ = text; + } + + boost::optional get_text() const { + assert(is_text()); + return text_.get(); + } + + bool is_tag() const { + return !name_.empty(); + } + + bool is_text() const { + return static_cast(text_); + } + + void set_attribute(const string_type &name, const string_type &value) { + assert(is_tag()); + attributes_.insert(typename headers_container_type::value_type(name, value)); + } + + boost::optional get_attribute(const string_type &name) const { + typename headers_container_type::const_iterator it = attributes_.find(name); + if (it != attributes_.end()) { + return it->second; + } + return boost::none; + } + + boost::iterator_range + get_attributes() const { + return boost::make_iterator_range(boost::begin(attributes_), + boost::end(attributes_)); + } + + boost::optional get_namespace() const { + return get_attribute("xmlns"); + } + + boost::optional get_type() const { + return get_attribute("type"); + } + + boost::optional get_lang() const { + return get_attribute("xml:lang"); + } + + boost::optional get_id() const { + return get_attribute("id"); + } + + void add_child(basic_element *element) { + assert(is_tag()); + boost::shared_ptr > shared_element(element); + children_.push_back(shared_element); + } + + boost::iterator_range + get_children() const { + return boost::make_iterator_range(boost::begin(children_), + boost::end(children_)); + } + +private: + + // if it's a tag node + string_type name_; + headers_container_type attributes_; + element_children_type children_; + + // if it's a text node + boost::optional text_; + +}; + + +typedef basic_element element; +} // namespace detail +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ diff --git a/boost/network/detail/xml_wrappers/element_io.hpp b/boost/network/detail/xml_wrappers/element_io.hpp new file mode 100644 index 000000000..9590cec00 --- /dev/null +++ b/boost/network/detail/xml_wrappers/element_io.hpp @@ -0,0 +1,57 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace detail { +template < + class Tag + > +std::ostream &operator << (std::ostream &os, + const basic_element &element) { + if (element.is_tag()) { + os << "<" << element.get_name(); + boost::iterator_range::headers_container_type::const_iterator> + attributes(element.get_attributes()); + + typename basic_element::headers_container_type::const_iterator + attr_it(boost::begin(attributes)), + attr_end(boost::end(attributes)); + for (; attr_it != attr_end; ++attr_it) { + os << " " << attr_it->first << "=\"" << attr_it->second << "\""; + } + os << ">"; + + boost::iterator_range::element_children_type::const_iterator> + children(element.get_children()); + + typename basic_element::element_children_type::const_iterator + child_it(boost::begin(children)), + child_end(boost::end(children)); + for (; child_it != child_end; ++child_it) { + os << **child_it; + } + os << ""; + } + else { + os << element.get_text().get(); + } + return os; +} +} // namespace detail +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp similarity index 90% rename from boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp index 0721d9da4..e73b3e536 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp @@ -4,19 +4,19 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ # include -# include +# include # include # include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -118,9 +118,9 @@ class basic_expat_element_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp similarity index 91% rename from boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp index 80bbeea39..127d2cca7 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ # include @@ -16,7 +16,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -116,9 +116,9 @@ class basic_expat_stanza_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp similarity index 53% rename from boost/network/protocol/xmpp/parser_backends/expat_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp index 48c3aa1f1..c569f1281 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp @@ -4,16 +4,16 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# include +# include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -23,9 +23,9 @@ class basic_expat_parser public: }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp similarity index 90% rename from boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp index 53a628743..74494bab4 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp @@ -4,19 +4,19 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ # include -# include +# include # include # include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -121,9 +121,9 @@ class basic_libxml2_element_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp similarity index 92% rename from boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp index 8f40fa77b..fc9d6e8e3 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ # include @@ -16,7 +16,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -119,9 +119,9 @@ class basic_libxml2_stanza_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp similarity index 53% rename from boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp index 799c0ed2d..b49c49091 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp @@ -4,16 +4,16 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# include +# include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -23,9 +23,9 @@ class basic_libxml2_parser public: }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/traits/element_children.hpp b/boost/network/detail/xml_wrappers/traits/element_children.hpp similarity index 71% rename from boost/network/protocol/xmpp/traits/element_children.hpp rename to boost/network/detail/xml_wrappers/traits/element_children.hpp index a2692c881..a9164a43b 100644 --- a/boost/network/protocol/xmpp/traits/element_children.hpp +++ b/boost/network/detail/xml_wrappers/traits/element_children.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ # include @@ -15,7 +15,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -34,9 +34,9 @@ template <> struct element_children { typedef std::list > > type; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ diff --git a/boost/network/protocol/xmpp/traits/parser_backend.hpp b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp similarity index 71% rename from boost/network/protocol/xmpp/traits/parser_backend.hpp rename to boost/network/detail/xml_wrappers/traits/parser_backend.hpp index 7ab680a8b..c33f5440b 100644 --- a/boost/network/protocol/xmpp/traits/parser_backend.hpp +++ b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ # include @@ -14,7 +14,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -33,9 +33,9 @@ template <> struct parser_backend { typedef basic_expat_parser type; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ diff --git a/boost/network/protocol/xmpp/details/ns.hpp b/boost/network/protocol/xmpp/detail/ns.hpp similarity index 100% rename from boost/network/protocol/xmpp/details/ns.hpp rename to boost/network/protocol/xmpp/detail/ns.hpp diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp index 22f0e3c4a..4225054eb 100644 --- a/boost/network/protocol/xmpp/element.hpp +++ b/boost/network/protocol/xmpp/element.hpp @@ -8,165 +8,7 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ -# include -# include -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag - > -class basic_element { - -public: - - struct tag {}; - struct text {}; - - typedef typename string::type string_type; - typedef typename headers_container::type headers_container_type; - typedef typename element_children::type element_children_type; - - basic_element() { - - } - - basic_element(tag, const string_type &name) - : name_(name) { - - } - - basic_element(text, const string_type &text) - : text_(text) { - - } - - basic_element(const basic_element &other) - : name_(other.name_), - attributes_(other.attributes_), - children_(other.children_), - text_(other.text_) { - - } - - basic_element &operator = (const basic_element &other) { - basic_element tmp(other); - swap(tmp); - return *this; - } - - ~basic_element() { - - } - - void swap(basic_element &other) { - std::swap(name_, other.name_); - std::swap(attributes_, other.attributes_); - std::swap(children_, other.children_); - std::swap(text_, other.text_); - } - - void set_name(const string_type &name) { - assert(!is_text()); - name_ = name; - } - - string_type get_name() const { - assert(is_tag()); - return name_; - } - - void set_text(const string_type &text) { - assert(!is_tag()); - text_ = text; - } - - boost::optional get_text() const { - assert(is_text()); - return text_.get(); - } - - bool is_tag() const { - return !name_.empty(); - } - - bool is_text() const { - return static_cast(text_); - } - - void set_attribute(const string_type &name, const string_type &value) { - assert(is_tag()); - attributes_.insert(typename headers_container_type::value_type(name, value)); - } - - boost::optional get_attribute(const string_type &name) const { - typename headers_container_type::const_iterator it = attributes_.find(name); - if (it != attributes_.end()) { - return it->second; - } - return boost::none; - } - - boost::iterator_range - get_attributes() const { - return boost::make_iterator_range(boost::begin(attributes_), - boost::end(attributes_)); - } - - boost::optional get_namespace() const { - return get_attribute("xmlns"); - } - - boost::optional get_type() const { - return get_attribute("type"); - } - - boost::optional get_lang() const { - return get_attribute("xml:lang"); - } - - boost::optional get_id() const { - return get_attribute("id"); - } - - void add_child(basic_element *element) { - assert(is_tag()); - boost::shared_ptr > shared_element(element); - children_.push_back(shared_element); - } - - boost::iterator_range - get_children() const { - return boost::make_iterator_range(boost::begin(children_), - boost::end(children_)); - } - -private: - - // if it's a tag node - string_type name_; - headers_container_type attributes_; - element_children_type children_; - - // if it's a text node - boost::optional text_; - -}; - - -typedef basic_element element; -} // namespace xmpp -} // namespace network -} // namespace boost +# include #endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp index 72924ec96..155b4fd22 100644 --- a/boost/network/protocol/xmpp/element_io.hpp +++ b/boost/network/protocol/xmpp/element_io.hpp @@ -8,50 +8,7 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag - > -std::ostream &operator << (std::ostream &os, - const basic_element &element) { - if (element.is_tag()) { - os << "<" << element.get_name(); - boost::iterator_range::headers_container_type::const_iterator> - attributes(element.get_attributes()); - - typename basic_element::headers_container_type::const_iterator - attr_it(boost::begin(attributes)), - attr_end(boost::end(attributes)); - for (; attr_it != attr_end; ++attr_it) { - os << " " << attr_it->first << "=\"" << attr_it->second << "\""; - } - os << ">"; - - boost::iterator_range::element_children_type::const_iterator> - children(element.get_children()); - - typename basic_element::element_children_type::const_iterator - child_it(boost::begin(children)), - child_end(boost::end(children)); - for (; child_it != child_end; ++child_it) { - os << **child_it; - } - os << ""; - } - else { - os << element.get_text().get(); - } - return os; -} -} // namespace xmpp -} // namespace network -} // namespace boost +# include #endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 72f9dfd55..454c9a9b7 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -32,7 +32,18 @@ if (Boost_FOUND) target_link_libraries(cpp-netlib-http_localhost_tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}) target_link_libraries(cpp-netlib-https_localhost_tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}) target_link_libraries(cpp-netlib-url_test ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}) - set_target_properties(cpp-netlib-hello_world cpp-netlib-http_1_0_test cpp-netlib-http_1_1_test cpp-netlib-message_test cpp-netlib-http_message_test cpp-netlib-message_transform_test cpp-netlib-http_localhost_tests cpp-netlib-https_localhost_tests cpp-netlib-url_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + + set_target_properties(cpp-netlib-hello_world + cpp-netlib-http_1_0_test + cpp-netlib-http_1_1_test + cpp-netlib-message_test + cpp-netlib-http_message_test + cpp-netlib-message_transform_test + cpp-netlib-http_localhost_tests + cpp-netlib-https_localhost_tests + cpp-netlib-url_test + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-hello_world python httplib_acceptance.py ../../../build/tests/cpp-netlib-hello_world ../../../build/tests/cpp-netlib-hello_world.passed) add_test(cpp-netlib-http_1_0_test ../../../build/tests/cpp-netlib-http_1_0_test) add_test(cpp-netlib-http_1_1_test ../../../build/tests/cpp-netlib-http_1_1_test) @@ -42,38 +53,52 @@ if (Boost_FOUND) add_test(cpp-netlib-http_message_test ../../../build/tests/cpp-netlib-http_message_test) add_test(cpp-netlib-url_test ../../../build/tests/cpp-netlib-url_test) - add_executable(cpp-netlib-xmpp_element_tests xmpp/xmpp_element_tests.cpp) - add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) - add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) - add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) - target_link_libraries(cpp-netlib-xmpp_element_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) - add_test(cpp-netlib-xmpp_element_tests ../../../build/tests/cpp-netlib-xmpp_element_tests) - add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) - add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) - add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + add_executable(cpp-netlib-xml_element_tests xml_wrappers/xml_element_tests.cpp) + target_link_libraries(cpp-netlib-xml_element_tests ${Boost_LIBRARIES}) + add_test(cpp-netlib-xml_element_tests ../../../build/tests/cpp-netlib-xml_element_tests) + + set_target_properties(cpp-netlib-xml_element_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) - add_executable(cpp-netlib-expat_element_parser_tests xmpp/expat_element_parser_tests.cpp) - add_executable(cpp-netlib-expat_stanza_parser_tests xmpp/expat_stanza_parser_tests.cpp) + add_executable(cpp-netlib-expat_element_parser_tests xml_wrappers/expat_element_parser_tests.cpp) target_link_libraries(cpp-netlib-expat_element_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) - target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) add_test(cpp-netlib-expat_element_parser_tests ../../../build/tests/cpp-netlib-expat_element_parser_tests) - add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + # add_executable(cpp-netlib-expat_stanza_parser_tests xml_wrappers/expat_stanza_parser_tests.cpp) + # target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + # add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + set_target_properties(cpp-netlib-expat_element_parser_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() if (LIBXML2_FOUND) include_directories( ${LIBXML2_INCLUDE_DIR} ) - add_executable(cpp-netlib-libxml2_element_parser_tests xmpp/libxml2_element_parser_tests.cpp) - add_executable(cpp-netlib-libxml2_stanza_parser_tests xmpp/libxml2_stanza_parser_tests.cpp) + add_executable(cpp-netlib-libxml2_element_parser_tests xml_wrappers/libxml2_element_parser_tests.cpp) target_link_libraries(cpp-netlib-libxml2_element_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) - target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) - add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parserg_tests) - add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parserg_tests) + add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parser_tests) + + # add_executable(cpp-netlib-libxml2_stanza_parser_tests xml_wrappers/libxml2_stanza_parser_tests.cpp) + # target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + # add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parser_tests) + set_target_properties(cpp-netlib-libxml2_element_parser_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() -endif() + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + set_target_properties(cpp-netlib-xmpp_message_tests + cpp-netlib-xmpp_presence_tests + cpp-netlib-xmpp_iq_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) +endif() diff --git a/libs/network/test/xmpp/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp similarity index 89% rename from libs/network/test/xmpp/expat_element_parser_tests.cpp rename to libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index 6b13f0505..e2a00bd51 100644 --- a/libs/network/test/xmpp/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -5,14 +5,14 @@ -#define BOOST_TEST_MODULE XMPP XML parsers +#define BOOST_TEST_MODULE expat wrapper tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; basic_expat_element_parser element_parser; diff --git a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp similarity index 89% rename from libs/network/test/xmpp/libxml2_element_parser_tests.cpp rename to libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp index 4723d8ef5..47889b3cb 100644 --- a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp @@ -5,14 +5,14 @@ -#define BOOST_TEST_MODULE XMPP XML parsers +#define BOOST_TEST_MODULE libxml2 wrapper tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; basic_libxml2_parser libxml2_parser; diff --git a/libs/network/test/xmpp/xmpp_element_tests.cpp b/libs/network/test/xml_wrappers/xml_element_tests.cpp similarity index 92% rename from libs/network/test/xmpp/xmpp_element_tests.cpp rename to libs/network/test/xml_wrappers/xml_element_tests.cpp index 9dcf60c41..849b49881 100644 --- a/libs/network/test/xmpp/xmpp_element_tests.cpp +++ b/libs/network/test/xml_wrappers/xml_element_tests.cpp @@ -4,14 +4,14 @@ // http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_TEST_MODULE XMPP element tests +#define BOOST_TEST_MODULE XML element tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; BOOST_AUTO_TEST_CASE(default_constructor_test) { From 7fa57489f1896089d8d1d90b623fb1e570654826 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 29 Aug 2010 13:34:02 +0200 Subject: [PATCH 003/438] Updated client comments. --- boost/network/auth/sasl.hpp | 34 ++++++ boost/network/protocol/xmpp/client.hpp | 100 ++++++++++++++++-- boost/network/protocol/xmpp/element.hpp | 14 --- boost/network/protocol/xmpp/element_io.hpp | 14 --- boost/network/tls/tls.hpp | 26 +++++ libs/network/test/xmpp/xmpp_iq_tests.cpp | 5 +- libs/network/test/xmpp/xmpp_message_tests.cpp | 15 ++- .../network/test/xmpp/xmpp_presence_tests.cpp | 5 +- libs/network/test/xmpp/xmpp_stanza_tests.cpp | 10 -- libs/network/test/xmpp/xmpp_uri_tests.cpp | 23 ---- 10 files changed, 160 insertions(+), 86 deletions(-) create mode 100644 boost/network/auth/sasl.hpp delete mode 100644 boost/network/protocol/xmpp/element.hpp delete mode 100644 boost/network/protocol/xmpp/element_io.hpp create mode 100644 boost/network/tls/tls.hpp delete mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp delete mode 100644 libs/network/test/xmpp/xmpp_uri_tests.cpp diff --git a/boost/network/auth/sasl.hpp b/boost/network/auth/sasl.hpp new file mode 100644 index 000000000..dfcc8cd26 --- /dev/null +++ b/boost/network/auth/sasl.hpp @@ -0,0 +1,34 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_AUTH_SASL_INC__ +# define __BOOST_NETWORK_AUTH_SASL_INC__ + + +# include + + +namespace boost { +namespace network { +namespace auth { +template < + class Tag + > +class basic_sasl { + +public: + + // basic_sasl(PLAIN); + + // basic_sasl(DIGEST); + +}; +} // namespace auth +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_AUTH_SASL_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 42e61f422..b099b3627 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -28,9 +28,9 @@ class basic_client : boost::noncopyable { typedef typename string::type string_type; - typedef basic_message message; - typedef basic_presence presence; - typedef basic_iq iq; + typedef basic_message message_type; + typedef basic_presence presence_type; + typedef basic_iq iq_type; explicit basic_client(Handler handler); @@ -52,30 +52,108 @@ class basic_client : boost::noncopyable { string_type jid() const; - string_type bound_jid() const; - private: + void handle_stream_start(); + void handle_stream_stanza(); + void handle_stream_end(); + // tcp socket // tls // sasl - // parameters, such as jid, bound_jid, domain, port etc. + // parameters, such as jid, domain, port etc. + string_type jid_; // io_service + boost::asio::io_service io_service_; // xml parser - // event handler + Handler handler_; + +}; - // stream open handler - // connection event handlers +template < + class Tag, + class Handler + > +basic_client::basic_client(Handler handler) { + // set the handlers +} + +template < + class Tag, + class Handler + > +basic_client::~basic_client() { - Handler handler_; +} -}; +template < + class Tag, + class Handler + > +void basic_client::connect(const string_type &proxy_host, + const string_type &proxy_port) { + // get the JID domain + // default port is 52222 + // open socket + // socket has a state + // signal connection handler +} + +template < + class Tag, + class Handler + > +void basic_client::disconnect() { + // close socket + // signal connection handler +} + +template < + class Tag, + class Handler + > +void basic_client::authenticate(const string_type &jid, + const string_type &password) { + +} + +template < + class Tag, + class Handler + > +void basic_client::send_message(const message_type &message) { + +} + +template < + class Tag, + class Handler + > +void basic_client::send_presence(const presence_type &presence) { + +} +template < + class Tag, + class Handler + > +void basic_client::send_iq(const iq_type &iq) { + +} + +template < + class Tag, + class Handler + > +basic_client::string_type +basic_client::jid() const { + return jid_; +} template < diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp deleted file mode 100644 index 4225054eb..000000000 --- a/boost/network/protocol/xmpp/element.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ - - -# include - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp deleted file mode 100644 index 155b4fd22..000000000 --- a/boost/network/protocol/xmpp/element_io.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ - - -# include - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/boost/network/tls/tls.hpp b/boost/network/tls/tls.hpp new file mode 100644 index 000000000..ed7edc4e2 --- /dev/null +++ b/boost/network/tls/tls.hpp @@ -0,0 +1,26 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_TLS_TLS_INC__ +# define __BOOST_NETWORK_TLS_TLS_INC__ + + +namespace boost { +namespace network { +class tls { +public: + + // credentials + // start + // read + // write + +}; +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_TLS_TLS_INC__ diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index 5a971a2c0..e2f527d87 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -10,18 +10,17 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::iq; BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { - iq instance; + xmpp::iq instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_iq_destination_directive_test) { - iq instance; + xmpp::iq instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp index 0098a4450..61c6811f7 100644 --- a/libs/network/test/xmpp/xmpp_message_tests.cpp +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -10,49 +10,48 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::message; BOOST_AUTO_TEST_CASE(xmpp_message_source_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_destination_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_header_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::header("type", "chat"); BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); - boost::network::headers_range::type range + boost::network::headers_range::type range = boost::network::headers(instance)["type"]; BOOST_CHECK (boost::begin(range) != boost::end(range)); } BOOST_AUTO_TEST_CASE(xmpp_message_body_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::header("type", "chat") << boost::network::body("Hello world!"); } BOOST_AUTO_TEST_CASE(xmpp_message_type_accessor_test) { - message instance; + xmpp::message instance; instance.set_type("chat"); BOOST_CHECK_EQUAL("chat", instance.type()); } BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { - message instance; + xmpp::message instance; instance.set_id("t2w4qax3"); BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); } diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp index 3997bd0db..4d9428df4 100644 --- a/libs/network/test/xmpp/xmpp_presence_tests.cpp +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -10,18 +10,17 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::presence; BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { - presence instance; + xmpp::presence instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_presence_destination_directive_test) { - presence instance; + xmpp::presence instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp deleted file mode 100644 index 31288c95a..000000000 --- a/libs/network/test/xmpp/xmpp_stanza_tests.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP stanza tests -#include -#include diff --git a/libs/network/test/xmpp/xmpp_uri_tests.cpp b/libs/network/test/xmpp/xmpp_uri_tests.cpp deleted file mode 100644 index 6bd6bc36c..000000000 --- a/libs/network/test/xmpp/xmpp_uri_tests.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include - -namespace xmpp = boost::network::uri::xmpp; - - -BOOST_AUTO_TEST_CASE(simple_uri_test) { - xmpp::uri uri("node@jabber.org"); - BOOST_CHECK(uri.to_string() == "node@jabber.org"); - BOOST_CHECK(uri.node() == "node"); - BOOST_CHECK(uri.domain() == "jabber.org"); - BOOST_CHECK(uri.resource().empty()); -} From 5b58e64afb2b211791a020decb77d23dc9f6e77e Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Thu, 2 Sep 2010 20:17:06 +0200 Subject: [PATCH 004/438] I moved stuff around and forgot to check it in. --- boost/network/protocol/xmpp/detail/ns.hpp | 72 ------------------- boost/network/protocol/xmpp/directives.hpp | 38 ---------- .../protocol/xmpp/directives/attribute.hpp | 22 ------ .../protocol/xmpp/directives/destination.hpp | 22 ------ .../network/protocol/xmpp/directives/from.hpp | 22 ------ boost/network/protocol/xmpp/directives/id.hpp | 22 ------ .../protocol/xmpp/directives/namespace.hpp | 22 ------ .../protocol/xmpp/directives/source.hpp | 22 ------ .../network/protocol/xmpp/directives/text.hpp | 22 ------ boost/network/protocol/xmpp/directives/to.hpp | 22 ------ .../network/protocol/xmpp/directives/type.hpp | 41 ----------- boost/network/protocol/xmpp/errors.hpp | 22 ------ boost/network/protocol/xmpp/iq.hpp | 2 +- boost/network/protocol/xmpp/message.hpp | 6 +- boost/network/protocol/xmpp/presence.hpp | 2 +- boost/network/protocol/xmpp/stanza.hpp | 26 +++---- .../test/xmpp/expat_stanza_parser_tests.cpp | 61 ---------------- .../test/xmpp/libxml2_stanza_parser_tests.cpp | 61 ---------------- 18 files changed, 18 insertions(+), 489 deletions(-) delete mode 100644 boost/network/protocol/xmpp/detail/ns.hpp delete mode 100644 boost/network/protocol/xmpp/directives.hpp delete mode 100644 boost/network/protocol/xmpp/directives/attribute.hpp delete mode 100644 boost/network/protocol/xmpp/directives/destination.hpp delete mode 100644 boost/network/protocol/xmpp/directives/from.hpp delete mode 100644 boost/network/protocol/xmpp/directives/id.hpp delete mode 100644 boost/network/protocol/xmpp/directives/namespace.hpp delete mode 100644 boost/network/protocol/xmpp/directives/source.hpp delete mode 100644 boost/network/protocol/xmpp/directives/text.hpp delete mode 100644 boost/network/protocol/xmpp/directives/to.hpp delete mode 100644 boost/network/protocol/xmpp/directives/type.hpp delete mode 100644 boost/network/protocol/xmpp/errors.hpp delete mode 100644 libs/network/test/xmpp/expat_stanza_parser_tests.cpp delete mode 100644 libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp diff --git a/boost/network/protocol/xmpp/detail/ns.hpp b/boost/network/protocol/xmpp/detail/ns.hpp deleted file mode 100644 index c58c7747e..000000000 --- a/boost/network/protocol/xmpp/detail/ns.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace details { -class namespaces { -public: - - static const char *client() { - return "jabber:client"; - } - - static const char *component() { - return "jabber:component:accept"; - } - - static const char *streams() { - return "http://etherx.jabber.org/streams"; - } - - static const char *streams_ietf() { - return "urn:ietf:params:xml:ns:xmpp-streams"; - } - - static const char *tls() { - return "urn:ietf:params:xml:ns:xmpp-tls"; - } - - static const char *sasl() { - return "urn:ietf:params:xml:ns:xmpp-sasl"; - } - - static const char *bind() { - return "urn:ietf:params:xml:ns:xmpp-bind"; - } - - static const char *session() { - return "urn:ietf:params:xml:ns:xmpp-session"; - } - - static const char *auth() { - return "jabber:iq:auth"; - } - - static const char *disco_info() { - return "http://jabber.org/protocol/disco#info"; - } - - static const char *disco_items() { - return "http://jabber.org/protocol/disco#items"; - } - - static const char *roster() { - return "jabber:iq:roster"; - } -}; -} // namespace details -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ diff --git a/boost/network/protocol/xmpp/directives.hpp b/boost/network/protocol/xmpp/directives.hpp deleted file mode 100644 index 4d9b54c47..000000000 --- a/boost/network/protocol/xmpp/directives.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ - - -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag, - class Directive - > -inline -basic_stanza &operator << (basic_stanza &stanza, - const Directive &directive) { - directive(stanza); - return stanza; -} -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ diff --git a/boost/network/protocol/xmpp/directives/attribute.hpp b/boost/network/protocol/xmpp/directives/attribute.hpp deleted file mode 100644 index 528ed79a5..000000000 --- a/boost/network/protocol/xmpp/directives/attribute.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ diff --git a/boost/network/protocol/xmpp/directives/destination.hpp b/boost/network/protocol/xmpp/directives/destination.hpp deleted file mode 100644 index 49991d230..000000000 --- a/boost/network/protocol/xmpp/directives/destination.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ diff --git a/boost/network/protocol/xmpp/directives/from.hpp b/boost/network/protocol/xmpp/directives/from.hpp deleted file mode 100644 index 4bd0989a2..000000000 --- a/boost/network/protocol/xmpp/directives/from.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ diff --git a/boost/network/protocol/xmpp/directives/id.hpp b/boost/network/protocol/xmpp/directives/id.hpp deleted file mode 100644 index 59b324c7f..000000000 --- a/boost/network/protocol/xmpp/directives/id.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ diff --git a/boost/network/protocol/xmpp/directives/namespace.hpp b/boost/network/protocol/xmpp/directives/namespace.hpp deleted file mode 100644 index 90723783b..000000000 --- a/boost/network/protocol/xmpp/directives/namespace.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ diff --git a/boost/network/protocol/xmpp/directives/source.hpp b/boost/network/protocol/xmpp/directives/source.hpp deleted file mode 100644 index a09c5af3f..000000000 --- a/boost/network/protocol/xmpp/directives/source.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ diff --git a/boost/network/protocol/xmpp/directives/text.hpp b/boost/network/protocol/xmpp/directives/text.hpp deleted file mode 100644 index d334b38e4..000000000 --- a/boost/network/protocol/xmpp/directives/text.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ diff --git a/boost/network/protocol/xmpp/directives/to.hpp b/boost/network/protocol/xmpp/directives/to.hpp deleted file mode 100644 index fa722f5f2..000000000 --- a/boost/network/protocol/xmpp/directives/to.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ diff --git a/boost/network/protocol/xmpp/directives/type.hpp b/boost/network/protocol/xmpp/directives/type.hpp deleted file mode 100644 index 72e2f160a..000000000 --- a/boost/network/protocol/xmpp/directives/type.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace details { -template < - typename T - > -struct type_directive { - - explicit type_directive(T type) - : type_(type) { - - } - - template < - class MessageTag - > - void operator () (basic_message &message) const { - message.type() = type_; - } - - T type_; - -}; -} // namespace details -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ diff --git a/boost/network/protocol/xmpp/errors.hpp b/boost/network/protocol/xmpp/errors.hpp deleted file mode 100644 index 5acbcbc06..000000000 --- a/boost/network/protocol/xmpp/errors.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -enum errors { - -}; -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp index 7ee8a95d7..f6c55c819 100644 --- a/boost/network/protocol/xmpp/iq.hpp +++ b/boost/network/protocol/xmpp/iq.hpp @@ -29,7 +29,7 @@ class basic_iq typedef typename base_type::headers_container_type headers_container_type; basic_iq() { - + set_name("iq"); } basic_iq(const basic_iq &other) diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp index 915e9c42b..4d6b2a7dc 100644 --- a/boost/network/protocol/xmpp/message.hpp +++ b/boost/network/protocol/xmpp/message.hpp @@ -29,7 +29,7 @@ class basic_message typedef typename base_type::headers_container_type headers_container_type; basic_message() { - + set_name("message"); } basic_message(const basic_message &other) @@ -58,7 +58,7 @@ class basic_message string_type type() const { static const char *type_ = "type"; - return attribute(string_type(type_, type_ + std::strlen(type_))); + return get_attribute(string_type(type_, type_ + std::strlen(type_))); } void set_id(const string_type &id) { @@ -68,7 +68,7 @@ class basic_message string_type id() const { static const char *id_ = "id"; - return attribute(string_type(id_, id_ + std::strlen(id_))); + return get_attribute(string_type(id_, id_ + std::strlen(id_))); } }; diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp index 60ba2aa2e..4c486b0d8 100644 --- a/boost/network/protocol/xmpp/presence.hpp +++ b/boost/network/protocol/xmpp/presence.hpp @@ -29,7 +29,7 @@ class basic_presence typedef typename base_type::headers_container_type headers_container_type; basic_presence() { - + set_name("presence"); } basic_presence(const basic_presence &other) diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index b3d06ebad..aa80bab4c 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -9,6 +9,7 @@ # include +# include namespace boost { @@ -26,31 +27,30 @@ class basic_stanza typedef typename base_type::string_type string_type; + explicit basic_stanza(const string_type &name) { + + } + void set_name(const string_type &name) { - name_ = name; + element_.set_name(name); } - string_type name() const { - return name_; + string_type get_name() const { + return element_.get_name(); } void set_attribute(const string_type &key, const string_type &value) { - this->headers().insert(std::make_pair(key, value)); + element_.set_attribute(key, value); } - string_type attribute(const string_type &key) const { - typename headers_range >::type range - = this->headers().equal_range(key); - if (boost::begin(range) == boost::end(range)) { - return string_type(); - } - - return boost::begin(range)->second; + string_type get_attribute(const string_type &key) const { + boost::optional attr = element_.get_attribute(key); + return attr? *attr : string_type(); } private: - string_type name_; + detail::basic_element element_; }; diff --git a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp deleted file mode 100644 index cf9dafe92..000000000 --- a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include -#include - - -using namespace boost::network::xmpp; -using boost::network::xmpp::message; -using boost::network::xmpp::presence; -using boost::network::xmpp::iq; - - -basic_expat_stanza_parser stanza_parser; - - -namespace { -struct xml_document_fixture { - xml_document_fixture() { - stanza_parser.feed(""); - } - - ~xml_document_fixture() { - stanza_parser.feed(""); - } -}; -} // namespace - - -BOOST_GLOBAL_FIXTURE(xml_document_fixture); - - -BOOST_AUTO_TEST_CASE(parse_message_test) { - message instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("message", instance.name()); - BOOST_CHECK_EQUAL("foo", instance.attribute("to")); -} - - -BOOST_AUTO_TEST_CASE(parse_presence_test) { - presence instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("presence", instance.name()); -} - - -BOOST_AUTO_TEST_CASE(parse_iq_test) { - iq instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("iq", instance.name()); - BOOST_CHECK_EQUAL("bar", instance.attribute("to")); -} diff --git a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp deleted file mode 100644 index f2242df34..000000000 --- a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include -#include - - -using namespace boost::network::xmpp; -using boost::network::xmpp::message; -using boost::network::xmpp::presence; -using boost::network::xmpp::iq; - - -basic_libxml2_stanza_parser stanza_parser; - - -namespace { -struct xml_document_fixture { - xml_document_fixture() { - stanza_parser.feed(""); - } - - ~xml_document_fixture() { - stanza_parser.feed(""); - } -}; -} // namespace - - -BOOST_GLOBAL_FIXTURE(xml_document_fixture); - - -BOOST_AUTO_TEST_CASE(parse_message_test) { - message instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("message", instance.name()); - BOOST_CHECK_EQUAL("foo", instance.attribute("to")); -} - - -BOOST_AUTO_TEST_CASE(parse_presence_test) { - presence instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("presence", instance.name()); -} - - -BOOST_AUTO_TEST_CASE(parse_iq_test) { - iq instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("iq", instance.name()); - BOOST_CHECK_EQUAL("bar", instance.attribute("to")); -} From 8c2c5516563b1560d300355a94818aeb5c734049 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Mon, 13 Sep 2010 23:14:59 +0200 Subject: [PATCH 005/438] Added first test for XMPP client. --- .../xml_wrappers/traits/parser_backend.hpp | 1 - boost/network/protocol/xmpp/client.hpp | 98 +++++++++++++------ .../protocol/xmpp/detail/stanza_parser.hpp | 59 +++++++++++ boost/network/protocol/xmpp/iq.hpp | 3 +- boost/network/protocol/xmpp/message.hpp | 3 +- boost/network/protocol/xmpp/presence.hpp | 3 +- boost/network/protocol/xmpp/stanza.hpp | 10 +- libs/network/test/CMakeLists.txt | 38 ++++--- .../expat_element_parser_tests.cpp | 1 - libs/network/test/xmpp/xmpp_client_tests.cpp | 37 +++++++ libs/network/test/xmpp/xmpp_message_tests.cpp | 14 +-- .../network/test/xmpp/xmpp_presence_tests.cpp | 1 + libs/network/test/xmpp/xmpp_stanza_tests.cpp | 54 ++++++++++ 13 files changed, 265 insertions(+), 57 deletions(-) create mode 100644 boost/network/protocol/xmpp/detail/stanza_parser.hpp create mode 100644 libs/network/test/xmpp/xmpp_client_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp diff --git a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp index c33f5440b..b2e1baad2 100644 --- a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp +++ b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp @@ -9,7 +9,6 @@ # include -# include namespace boost { diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index b099b3627..892bc4a1e 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -8,22 +8,30 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ -# include +# include # include # include +# include # include # include # include +# include +# include namespace boost { namespace network { namespace xmpp { template < - class Handler, - class Tag + class Tag, + class Handler > class basic_client : boost::noncopyable { + +private: + + typedef basic_client this_type; + public: typedef typename string::type string_type; @@ -32,7 +40,7 @@ class basic_client : boost::noncopyable { typedef basic_presence presence_type; typedef basic_iq iq_type; - explicit basic_client(Handler handler); + explicit basic_client(Handler &handler); ~basic_client(); @@ -50,28 +58,31 @@ class basic_client : boost::noncopyable { void send_iq(const iq_type &iq); - string_type jid() const; + void set_jid(const string_type &jid); + + string_type get_jid() const; private: - void handle_stream_start(); - void handle_stream_stanza(); - void handle_stream_end(); + void write_stanza(const basic_stanza &stanza); + void close_socket(); + + Handler &handler_; + + // io_service + boost::asio::io_service io_service_; // tcp socket + boost::asio::ip::tcp::socket socket_; + // tls // sasl // parameters, such as jid, domain, port etc. string_type jid_; - // io_service - boost::asio::io_service io_service_; - // xml parser - Handler handler_; - }; @@ -79,24 +90,27 @@ template < class Tag, class Handler > -basic_client::basic_client(Handler handler) { +basic_client::basic_client(Handler &handler) + : handler_(handler), socket_(io_service_) { // set the handlers } + template < class Tag, class Handler > -basic_client::~basic_client() { +basic_client::~basic_client() { } + template < class Tag, class Handler > -void basic_client::connect(const string_type &proxy_host, - const string_type &proxy_port) { +void basic_client::connect(const string_type &proxy_host, + const string_type &proxy_port) { // get the JID domain // default port is 52222 // open socket @@ -108,17 +122,19 @@ template < class Tag, class Handler > -void basic_client::disconnect() { +void basic_client::disconnect() { // close socket // signal connection handler + io_service_.post( + boost::bind(&this_type::close_socket, this)); } template < class Tag, class Handler > -void basic_client::authenticate(const string_type &jid, - const string_type &password) { +void basic_client::authenticate(const string_type &jid, + const string_type &password) { } @@ -126,42 +142,64 @@ template < class Tag, class Handler > -void basic_client::send_message(const message_type &message) { - +void basic_client::send_message(const message_type &message) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(message))); } template < class Tag, class Handler > -void basic_client::send_presence(const presence_type &presence) { - +void basic_client::send_presence(const presence_type &presence) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(presence))); } template < class Tag, class Handler > -void basic_client::send_iq(const iq_type &iq) { - +void basic_client::send_iq(const iq_type &iq) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(iq))); } template < class Tag, class Handler > -basic_client::string_type -basic_client::jid() const { +typename basic_client::string_type +basic_client::get_jid() const { return jid_; } +template < + class Tag, + class Handler + > +void basic_client::write_stanza(const basic_stanza &stanza) { + +} + + +template < + class Tag, + class Handler + > +void basic_client::close_socket() { + socket_.close(); +} + + template < class Handler > -struct client : basic_client { +struct client : basic_client { - explicit client(Handler handler) : basic_client(handler) { + explicit client(Handler &handler) + : basic_client(handler) { } diff --git a/boost/network/protocol/xmpp/detail/stanza_parser.hpp b/boost/network/protocol/xmpp/detail/stanza_parser.hpp new file mode 100644 index 000000000..761c5ec65 --- /dev/null +++ b/boost/network/protocol/xmpp/detail/stanza_parser.hpp @@ -0,0 +1,59 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + + +namespace boost { +namespace network { +namespace xmpp { +namespace detail { +template < + class Tag + > +class basic_stanza_parser { +public: + + typedef basic_stanza stanza_type; + typedef typename string::type string_type; + typedef typename boost::network::detail::parser_backend::type parser_type; + + basic_stanza_parser() { + + } + + ~basic_stanza_parser() { + + } + + bool feed(const string_type &chunk) { + parser_.feed(chunk); + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + parser_.feed(chunk, &stanza.element()); + } + +private: + + parser_type parser_; + +}; +} // namespace detail +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp index f6c55c819..c861aa8ce 100644 --- a/boost/network/protocol/xmpp/iq.hpp +++ b/boost/network/protocol/xmpp/iq.hpp @@ -29,7 +29,8 @@ class basic_iq typedef typename base_type::headers_container_type headers_container_type; basic_iq() { - set_name("iq"); + static const char name[] = {'i', 'q'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_iq(const basic_iq &other) diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp index 4d6b2a7dc..926453f13 100644 --- a/boost/network/protocol/xmpp/message.hpp +++ b/boost/network/protocol/xmpp/message.hpp @@ -29,7 +29,8 @@ class basic_message typedef typename base_type::headers_container_type headers_container_type; basic_message() { - set_name("message"); + static const char name[] = {'m', 'e', 's', 's', 'a', 'g', 'e'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_message(const basic_message &other) diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp index 4c486b0d8..f18494b5d 100644 --- a/boost/network/protocol/xmpp/presence.hpp +++ b/boost/network/protocol/xmpp/presence.hpp @@ -29,7 +29,8 @@ class basic_presence typedef typename base_type::headers_container_type headers_container_type; basic_presence() { - set_name("presence"); + static const char name[] = {'p', 'r', 'e', 's', 'e', 'n', 'c', 'e'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_presence(const basic_presence &other) diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index aa80bab4c..ca0aa793a 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -27,10 +27,14 @@ class basic_stanza typedef typename base_type::string_type string_type; - explicit basic_stanza(const string_type &name) { + explicit basic_stanza() { } + explicit basic_stanza(const string_type &name) { + element_.set_name(name); + } + void set_name(const string_type &name) { element_.set_name(name); } @@ -48,6 +52,10 @@ class basic_stanza return attr? *attr : string_type(); } + detail::basic_element &element() { + return element_; + } + private: detail::basic_element element_; diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 454c9a9b7..bdd60a902 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -60,6 +60,20 @@ if (Boost_FOUND) set_target_properties(cpp-netlib-xml_element_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + set_target_properties(cpp-netlib-xmpp_message_tests + cpp-netlib-xmpp_presence_tests + cpp-netlib-xmpp_iq_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) add_executable(cpp-netlib-expat_element_parser_tests xml_wrappers/expat_element_parser_tests.cpp) @@ -69,8 +83,18 @@ if (Boost_FOUND) # add_executable(cpp-netlib-expat_stanza_parser_tests xml_wrappers/expat_stanza_parser_tests.cpp) # target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) # add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + add_executable(cpp-netlib-xmpp_stanza_tests xmpp/xmpp_stanza_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_stanza_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-xmpp_stanza_tests ../../../build/tests/cpp-netlib-xmpp_stanza_tests) + add_executable(cpp-netlib-xmpp_client_tests xmpp/xmpp_client_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_client_tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-xmpp_client_tests ../../../build/tests/cpp-netlib-xmpp_client_tests) + set_target_properties(cpp-netlib-expat_element_parser_tests + cpp-netlib-xmpp_stanza_tests + cpp-netlib-xmpp_client_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() @@ -87,18 +111,4 @@ if (Boost_FOUND) PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() - add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) - add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) - add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) - target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) - set_target_properties(cpp-netlib-xmpp_message_tests - cpp-netlib-xmpp_presence_tests - cpp-netlib-xmpp_iq_tests - PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) - add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) - add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) - add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) - endif() diff --git a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index e2a00bd51..856e15b48 100644 --- a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -4,7 +4,6 @@ // http://www.boost.org/LICENSE_1_0.txt) - #define BOOST_TEST_MODULE expat wrapper tests #include #include diff --git a/libs/network/test/xmpp/xmpp_client_tests.cpp b/libs/network/test/xmpp/xmpp_client_tests.cpp new file mode 100644 index 000000000..b6345facc --- /dev/null +++ b/libs/network/test/xmpp/xmpp_client_tests.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP client tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +struct test_handler; +typedef xmpp::client client; + + +struct test_handler { + + void handle(const client::message_type &message) { + + } + + void handle(const client::presence_type &presence) { + + } + + void handle(const client::iq_type &iq) { + + } + +}; + + +BOOST_AUTO_TEST_CASE(test_client_connection) { + test_handler handler; + client instance(handler); +} diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp index 61c6811f7..a13b9b77c 100644 --- a/libs/network/test/xmpp/xmpp_message_tests.cpp +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -57,13 +57,13 @@ BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { } -// BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { -// message instance; -// instance << xmpp::type("chat"); -// BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); -// } -// -// +BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { + // xmpp::message instance; + // instance << xmpp::type("chat"); + // BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); +} + + // BOOST_AUTO_TEST_CASE(xmpp_message_id_directive_test) { // message instance; // instance << xmpp::id("t2w4qax3"); diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp index 4d9428df4..f373cfe38 100644 --- a/libs/network/test/xmpp/xmpp_presence_tests.cpp +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -15,6 +15,7 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { xmpp::presence instance; instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("presence", instance.get_name()); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp new file mode 100644 index 000000000..d85c08ad0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -0,0 +1,54 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP stanza tests +#include +#include +#include +#include +#include +#include +#include +#include +// #include + + +namespace xmpp = boost::network::xmpp; + + +xmpp::detail::basic_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + xmpp::message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + xmpp::presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); +} From 12e542fdba64558a578738d97ff0a6f4ffaa9657 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Fri, 17 Sep 2010 23:45:38 +0200 Subject: [PATCH 006/438] Updates XMPP namespaces. --- boost/network/protocol/xmpp/client.hpp | 174 ++++++++++++++---- boost/network/protocol/xmpp/namespaces.hpp | 83 +++++++++ libs/network/test/CMakeLists.txt | 4 + libs/network/test/xmpp/xmpp_iq_tests.cpp | 1 + .../test/xmpp/xmpp_namespace_tests.cpp | 35 ++++ libs/network/test/xmpp/xmpp_stanza_tests.cpp | 2 +- 6 files changed, 261 insertions(+), 38 deletions(-) create mode 100644 boost/network/protocol/xmpp/namespaces.hpp create mode 100644 libs/network/test/xmpp/xmpp_namespace_tests.cpp diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 892bc4a1e..fbbcae83e 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -12,11 +12,14 @@ # include # include # include +# include # include # include # include # include +# include # include +# include namespace boost { @@ -24,13 +27,15 @@ namespace network { namespace xmpp { template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > class basic_client : boost::noncopyable { private: - typedef basic_client this_type; + typedef basic_client this_type; public: @@ -44,13 +49,14 @@ class basic_client : boost::noncopyable { ~basic_client(); - void connect(const string_type &proxy_host, - const string_type &proxy_port); + void set_lang(const string_type &lang); - void disconnect(); + void connect(const string_type &jid, + const string_type &password); + + void run(); - void authenticate(const string_type &jid, - const string_type &password); + void disconnect(); void send_message(const message_type &message); @@ -58,14 +64,15 @@ class basic_client : boost::noncopyable { void send_iq(const iq_type &iq); - void set_jid(const string_type &jid); - string_type get_jid() const; private: - void write_stanza(const basic_stanza &stanza); - void close_socket(); + void handle_connect(const boost::system::error_code &error, + boost::asio::ip::tcp::resolver::iterator iterator); + void handle_write_stanza(const basic_stanza &stanza); + void handle_read_stanza(const boost::system::error_code &ec); + void handle_disconnect(); Handler &handler_; @@ -83,123 +90,216 @@ class basic_client : boost::noncopyable { // xml parser + // std::deque stanza_queue_; + }; template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -basic_client::basic_client(Handler &handler) +basic_client::basic_client(Handler &handler) : handler_(handler), socket_(io_service_) { - // set the handlers + } template < class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +basic_client::~basic_client() { + +} + +template < + class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -basic_client::~basic_client() { +void basic_client::set_lang(const string_type &lang) { } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::connect(const string_type &proxy_host, - const string_type &proxy_port) { +void basic_client::connect(const string_type &jid, + const string_type &password) { + using boost::asio::ip::tcp; + // get the JID domain - // default port is 52222 + // default port is 5222 // open socket // socket has a state // signal connection handler + + jid_ = jid; + + string_type host = "127.0.0.1"; + string_type port = "5222"; + + tcp::resolver resolver(io_service_); + tcp::resolver::query query(host, port); + tcp::resolver::iterator iterator = resolver.resolve(query); + socket_.async_connect(&this_type::handle_connect, + this, + boost::asio::placeholders::error, + iterator); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::disconnect() { - // close socket - // signal connection handler - io_service_.post( - boost::bind(&this_type::close_socket, this)); +void basic_client::run() { + io_service_.run(); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::authenticate(const string_type &jid, - const string_type &password) { - +void basic_client::disconnect() { + io_service_.post( + boost::bind(&this_type::handle_disconnect, this)); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_message(const message_type &message) { +void basic_client::send_message(const message_type &message) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(message))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(message))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_presence(const presence_type &presence) { +void basic_client::send_presence(const presence_type &presence) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(presence))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(presence))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_iq(const iq_type &iq) { +void basic_client::send_iq(const iq_type &iq) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(iq))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(iq))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -typename basic_client::string_type -basic_client::get_jid() const { +typename basic_client::string_type +basic_client::get_jid() const { return jid_; } +template < + class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +void basic_client::handle_connect( + const boost::system::error_code& ec, + boost::asio::ip::tcp::resolver::iterator iterator) { + if (!ec) { + + // open stream + // TODO: where does "lang" come from? + string_type s = + "" + ""; // xmpp_ns_Streams + + // boost::asio::async_read( + // socket_, + // boost::asio::buffer(read_msg_.data(), chat_message::header_length), + // boost::bind(&chat_client::handle_read_header, this, + // boost::asio::placeholders::error)); + } + else if (iterator != boost::asio::ip::tcp::resolver::iterator()) { + socket_.close(); + boost::asio::ip::tcp::endpoint endpoint = *iterator; + socket_.async_connect( + endpoint, + boost::bind(&this_type::handle_connect, + this, + boost::asio::placeholders::error, + ++iterator)); + } + else { + // unable to connect + } +} template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::write_stanza(const basic_stanza &stanza) { - +void basic_client::handle_write_stanza(const basic_stanza &stanza) { + // stanza ==> string + // socket_.async_write(socket_, + // boost::asio::buffer(stanza.string()), + // boost::bind(&this_type::handle_write...)) } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::close_socket() { +void basic_client::handle_disconnect() { + // close stream + string_type s = ""; socket_.close(); + // handler_.disconnected(); } template < class Handler > -struct client : basic_client { +struct client : basic_client { explicit client(Handler &handler) - : basic_client(handler) { + : basic_client(handler) { } diff --git a/boost/network/protocol/xmpp/namespaces.hpp b/boost/network/protocol/xmpp/namespaces.hpp new file mode 100644 index 000000000..75bfeb5e7 --- /dev/null +++ b/boost/network/protocol/xmpp/namespaces.hpp @@ -0,0 +1,83 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +namespace ns { +template < + class Tag + > +inline +typename string::type client() { + static const char client[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'l', 'i', 'e', 'n', 't'}; + return typename string::type( + client, client + sizeof(client)); +} + +template < + class Tag + > +inline +typename string::type server() { + static const char server[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 's', 'e', 'r', 'v', 'e', 'r'}; + return typename string::type( + server, server + sizeof(server)); +} + +template < + class Tag + > +inline +typename string::type component() { + static const char component[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'o', 'm', 'p', 'o', + 'n', 'e', 'n', 't', ':', 'a', 'c', 'c', 'e', 'p', 't'}; + return typename string::type( + component, component + sizeof(component)); +} + +template < + class Tag + > +inline +typename string::type streams() { + static const char streams[] = { + 'h', 't', 't', 'p', ':', '/', '/', 'e', 't', 'h', 'e', 'r', + 'x', '.', 'j', 'a', 'b', 'b', 'e', 'r', '.', 'o', 'r', 'g', + '/', 's', 't', 'r', 'e', 'a', 'm', 's'}; + return typename string::type( + streams, streams + sizeof(streams)); +} + +template < + class Tag + > +inline +typename string::type streams_ietf() { + static const char streams_ietf[] = { + 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', + 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', + 'm', 'p', 'p', '-', 's', 't', 'r', 'e', 'a', 'm', 's'}; + return typename string::type( + streams_ietf, streams_ietf + sizeof(streams_ietf)); +} +} // namespace ns +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index bdd60a902..b5f647768 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -63,16 +63,20 @@ if (Boost_FOUND) add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + add_executable(cpp-netlib-xmpp_namespace_tests xmpp/xmpp_namespace_tests.cpp) target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_namespace_tests ${Boost_LIBRARIES}) set_target_properties(cpp-netlib-xmpp_message_tests cpp-netlib-xmpp_presence_tests cpp-netlib-xmpp_iq_tests + cpp-netlib-xmpp_namespace_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + add_test(cpp-netlib-xmpp_namespace_tests ../../../build/tests/cpp-netlib-xmpp_namespace_tests) if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index e2f527d87..ad14bb726 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -7,6 +7,7 @@ #define BOOST_TEST_MODULE XMPP iq tests #include #include +#include namespace xmpp = boost::network::xmpp; diff --git a/libs/network/test/xmpp/xmpp_namespace_tests.cpp b/libs/network/test/xmpp/xmpp_namespace_tests.cpp new file mode 100644 index 000000000..5bb82c3f0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_namespace_tests.cpp @@ -0,0 +1,35 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP namespace tests +#include +#include +#include +#include +#include + + +namespace xmpp = boost::network::xmpp; + + +typedef boost::mpl::list< + boost::network::tags::default_string, + boost::network::tags::default_wstring + > tag_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_namespaces, T, tag_types) { + BOOST_CHECK(boost::equal(std::string("jabber:client"), + xmpp::ns::client())); + BOOST_CHECK(boost::equal(std::string("jabber:server"), + xmpp::ns::server())); + BOOST_CHECK(boost::equal(std::string("jabber:component:accept"), + xmpp::ns::component())); + BOOST_CHECK(boost::equal(std::string("http://etherx.jabber.org/streams"), + xmpp::ns::streams())); + BOOST_CHECK(boost::equal(std::string("urn:ietf:params:xml:ns:xmpp-streams"), + xmpp::ns::streams_ietf())); +} diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp index d85c08ad0..2c85f65cb 100644 --- a/libs/network/test/xmpp/xmpp_stanza_tests.cpp +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -13,7 +13,7 @@ #include #include #include -// #include +#include namespace xmpp = boost::network::xmpp; From 770d7eb267c1301fad0528d5a89281b6489b0d0d Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 28 Aug 2010 08:37:21 +0200 Subject: [PATCH 007/438] Used XMPP package with cpp-netlib 0.6 because there were too many changes on the 0.7 branch. Tests compile and succeed. --- boost/network/protocol/xmpp.hpp | 13 ++ boost/network/protocol/xmpp/client.hpp | 96 ++++++++++ boost/network/protocol/xmpp/details/ns.hpp | 72 ++++++++ boost/network/protocol/xmpp/directives.hpp | 38 ++++ .../protocol/xmpp/directives/attribute.hpp | 22 +++ .../protocol/xmpp/directives/destination.hpp | 22 +++ .../network/protocol/xmpp/directives/from.hpp | 22 +++ boost/network/protocol/xmpp/directives/id.hpp | 22 +++ .../protocol/xmpp/directives/namespace.hpp | 22 +++ .../protocol/xmpp/directives/source.hpp | 22 +++ .../network/protocol/xmpp/directives/text.hpp | 22 +++ boost/network/protocol/xmpp/directives/to.hpp | 22 +++ .../network/protocol/xmpp/directives/type.hpp | 41 +++++ boost/network/protocol/xmpp/element.hpp | 172 ++++++++++++++++++ boost/network/protocol/xmpp/element_io.hpp | 57 ++++++ boost/network/protocol/xmpp/errors.hpp | 22 +++ boost/network/protocol/xmpp/iq.hpp | 63 +++++++ boost/network/protocol/xmpp/message.hpp | 83 +++++++++ .../parser_backends/expat/element_parser.hpp | 126 +++++++++++++ .../parser_backends/expat/stanza_parser.hpp | 124 +++++++++++++ .../xmpp/parser_backends/expat_parser.hpp | 31 ++++ .../libxml2/element_parser.hpp | 129 +++++++++++++ .../parser_backends/libxml2/stanza_parser.hpp | 127 +++++++++++++ .../xmpp/parser_backends/libxml2_parser.hpp | 31 ++++ boost/network/protocol/xmpp/presence.hpp | 63 +++++++ boost/network/protocol/xmpp/stanza.hpp | 64 +++++++ .../protocol/xmpp/traits/element_children.hpp | 42 +++++ .../protocol/xmpp/traits/parser_backend.hpp | 41 +++++ libs/network/test/CMakeLists.txt | 36 ++++ .../test/xmpp/expat_element_parser_tests.cpp | 77 ++++++++ .../test/xmpp/expat_stanza_parser_tests.cpp | 61 +++++++ .../xmpp/libxml2_element_parser_tests.cpp | 77 ++++++++ .../test/xmpp/libxml2_stanza_parser_tests.cpp | 61 +++++++ libs/network/test/xmpp/xmpp_element_tests.cpp | 88 +++++++++ libs/network/test/xmpp/xmpp_iq_tests.cpp | 27 +++ libs/network/test/xmpp/xmpp_message_tests.cpp | 80 ++++++++ .../network/test/xmpp/xmpp_presence_tests.cpp | 27 +++ libs/network/test/xmpp/xmpp_stanza_tests.cpp | 10 + libs/network/test/xmpp/xmpp_uri_tests.cpp | 23 +++ 39 files changed, 2178 insertions(+) create mode 100644 boost/network/protocol/xmpp.hpp create mode 100644 boost/network/protocol/xmpp/client.hpp create mode 100644 boost/network/protocol/xmpp/details/ns.hpp create mode 100644 boost/network/protocol/xmpp/directives.hpp create mode 100644 boost/network/protocol/xmpp/directives/attribute.hpp create mode 100644 boost/network/protocol/xmpp/directives/destination.hpp create mode 100644 boost/network/protocol/xmpp/directives/from.hpp create mode 100644 boost/network/protocol/xmpp/directives/id.hpp create mode 100644 boost/network/protocol/xmpp/directives/namespace.hpp create mode 100644 boost/network/protocol/xmpp/directives/source.hpp create mode 100644 boost/network/protocol/xmpp/directives/text.hpp create mode 100644 boost/network/protocol/xmpp/directives/to.hpp create mode 100644 boost/network/protocol/xmpp/directives/type.hpp create mode 100644 boost/network/protocol/xmpp/element.hpp create mode 100644 boost/network/protocol/xmpp/element_io.hpp create mode 100644 boost/network/protocol/xmpp/errors.hpp create mode 100644 boost/network/protocol/xmpp/iq.hpp create mode 100644 boost/network/protocol/xmpp/message.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/expat_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp create mode 100644 boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp create mode 100644 boost/network/protocol/xmpp/presence.hpp create mode 100644 boost/network/protocol/xmpp/stanza.hpp create mode 100644 boost/network/protocol/xmpp/traits/element_children.hpp create mode 100644 boost/network/protocol/xmpp/traits/parser_backend.hpp create mode 100644 libs/network/test/xmpp/expat_element_parser_tests.cpp create mode 100644 libs/network/test/xmpp/expat_stanza_parser_tests.cpp create mode 100644 libs/network/test/xmpp/libxml2_element_parser_tests.cpp create mode 100644 libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_element_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_iq_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_message_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_presence_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_uri_tests.cpp diff --git a/boost/network/protocol/xmpp.hpp b/boost/network/protocol/xmpp.hpp new file mode 100644 index 000000000..39bd5a4c1 --- /dev/null +++ b/boost/network/protocol/xmpp.hpp @@ -0,0 +1,13 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_INC__ + + + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp new file mode 100644 index 000000000..42e61f422 --- /dev/null +++ b/boost/network/protocol/xmpp/client.hpp @@ -0,0 +1,96 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ + + +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Handler, + class Tag + > +class basic_client : boost::noncopyable { +public: + + typedef typename string::type string_type; + + typedef basic_message message; + typedef basic_presence presence; + typedef basic_iq iq; + + explicit basic_client(Handler handler); + + ~basic_client(); + + void connect(const string_type &proxy_host, + const string_type &proxy_port); + + void disconnect(); + + void authenticate(const string_type &jid, + const string_type &password); + + void send_message(const message_type &message); + + void send_presence(const presence_type &presence); + + void send_iq(const iq_type &iq); + + string_type jid() const; + + string_type bound_jid() const; + +private: + + // tcp socket + // tls + // sasl + + // parameters, such as jid, bound_jid, domain, port etc. + + // io_service + + // xml parser + + // event handler + + // stream open handler + + // connection event handlers + + Handler handler_; + +}; + + + +template < + class Handler + > +struct client : basic_client { + + explicit client(Handler handler) : basic_client(handler) { + + } + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ diff --git a/boost/network/protocol/xmpp/details/ns.hpp b/boost/network/protocol/xmpp/details/ns.hpp new file mode 100644 index 000000000..c58c7747e --- /dev/null +++ b/boost/network/protocol/xmpp/details/ns.hpp @@ -0,0 +1,72 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace details { +class namespaces { +public: + + static const char *client() { + return "jabber:client"; + } + + static const char *component() { + return "jabber:component:accept"; + } + + static const char *streams() { + return "http://etherx.jabber.org/streams"; + } + + static const char *streams_ietf() { + return "urn:ietf:params:xml:ns:xmpp-streams"; + } + + static const char *tls() { + return "urn:ietf:params:xml:ns:xmpp-tls"; + } + + static const char *sasl() { + return "urn:ietf:params:xml:ns:xmpp-sasl"; + } + + static const char *bind() { + return "urn:ietf:params:xml:ns:xmpp-bind"; + } + + static const char *session() { + return "urn:ietf:params:xml:ns:xmpp-session"; + } + + static const char *auth() { + return "jabber:iq:auth"; + } + + static const char *disco_info() { + return "http://jabber.org/protocol/disco#info"; + } + + static const char *disco_items() { + return "http://jabber.org/protocol/disco#items"; + } + + static const char *roster() { + return "jabber:iq:roster"; + } +}; +} // namespace details +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ diff --git a/boost/network/protocol/xmpp/directives.hpp b/boost/network/protocol/xmpp/directives.hpp new file mode 100644 index 000000000..4d9b54c47 --- /dev/null +++ b/boost/network/protocol/xmpp/directives.hpp @@ -0,0 +1,38 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ + + +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag, + class Directive + > +inline +basic_stanza &operator << (basic_stanza &stanza, + const Directive &directive) { + directive(stanza); + return stanza; +} +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ diff --git a/boost/network/protocol/xmpp/directives/attribute.hpp b/boost/network/protocol/xmpp/directives/attribute.hpp new file mode 100644 index 000000000..528ed79a5 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/attribute.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ diff --git a/boost/network/protocol/xmpp/directives/destination.hpp b/boost/network/protocol/xmpp/directives/destination.hpp new file mode 100644 index 000000000..49991d230 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/destination.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ diff --git a/boost/network/protocol/xmpp/directives/from.hpp b/boost/network/protocol/xmpp/directives/from.hpp new file mode 100644 index 000000000..4bd0989a2 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/from.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ diff --git a/boost/network/protocol/xmpp/directives/id.hpp b/boost/network/protocol/xmpp/directives/id.hpp new file mode 100644 index 000000000..59b324c7f --- /dev/null +++ b/boost/network/protocol/xmpp/directives/id.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ diff --git a/boost/network/protocol/xmpp/directives/namespace.hpp b/boost/network/protocol/xmpp/directives/namespace.hpp new file mode 100644 index 000000000..90723783b --- /dev/null +++ b/boost/network/protocol/xmpp/directives/namespace.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ diff --git a/boost/network/protocol/xmpp/directives/source.hpp b/boost/network/protocol/xmpp/directives/source.hpp new file mode 100644 index 000000000..a09c5af3f --- /dev/null +++ b/boost/network/protocol/xmpp/directives/source.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ diff --git a/boost/network/protocol/xmpp/directives/text.hpp b/boost/network/protocol/xmpp/directives/text.hpp new file mode 100644 index 000000000..d334b38e4 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/text.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ diff --git a/boost/network/protocol/xmpp/directives/to.hpp b/boost/network/protocol/xmpp/directives/to.hpp new file mode 100644 index 000000000..fa722f5f2 --- /dev/null +++ b/boost/network/protocol/xmpp/directives/to.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace directives { + +} // namespace directives +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ diff --git a/boost/network/protocol/xmpp/directives/type.hpp b/boost/network/protocol/xmpp/directives/type.hpp new file mode 100644 index 000000000..72e2f160a --- /dev/null +++ b/boost/network/protocol/xmpp/directives/type.hpp @@ -0,0 +1,41 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +namespace details { +template < + typename T + > +struct type_directive { + + explicit type_directive(T type) + : type_(type) { + + } + + template < + class MessageTag + > + void operator () (basic_message &message) const { + message.type() = type_; + } + + T type_; + +}; +} // namespace details +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp new file mode 100644 index 000000000..22f0e3c4a --- /dev/null +++ b/boost/network/protocol/xmpp/element.hpp @@ -0,0 +1,172 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_element { + +public: + + struct tag {}; + struct text {}; + + typedef typename string::type string_type; + typedef typename headers_container::type headers_container_type; + typedef typename element_children::type element_children_type; + + basic_element() { + + } + + basic_element(tag, const string_type &name) + : name_(name) { + + } + + basic_element(text, const string_type &text) + : text_(text) { + + } + + basic_element(const basic_element &other) + : name_(other.name_), + attributes_(other.attributes_), + children_(other.children_), + text_(other.text_) { + + } + + basic_element &operator = (const basic_element &other) { + basic_element tmp(other); + swap(tmp); + return *this; + } + + ~basic_element() { + + } + + void swap(basic_element &other) { + std::swap(name_, other.name_); + std::swap(attributes_, other.attributes_); + std::swap(children_, other.children_); + std::swap(text_, other.text_); + } + + void set_name(const string_type &name) { + assert(!is_text()); + name_ = name; + } + + string_type get_name() const { + assert(is_tag()); + return name_; + } + + void set_text(const string_type &text) { + assert(!is_tag()); + text_ = text; + } + + boost::optional get_text() const { + assert(is_text()); + return text_.get(); + } + + bool is_tag() const { + return !name_.empty(); + } + + bool is_text() const { + return static_cast(text_); + } + + void set_attribute(const string_type &name, const string_type &value) { + assert(is_tag()); + attributes_.insert(typename headers_container_type::value_type(name, value)); + } + + boost::optional get_attribute(const string_type &name) const { + typename headers_container_type::const_iterator it = attributes_.find(name); + if (it != attributes_.end()) { + return it->second; + } + return boost::none; + } + + boost::iterator_range + get_attributes() const { + return boost::make_iterator_range(boost::begin(attributes_), + boost::end(attributes_)); + } + + boost::optional get_namespace() const { + return get_attribute("xmlns"); + } + + boost::optional get_type() const { + return get_attribute("type"); + } + + boost::optional get_lang() const { + return get_attribute("xml:lang"); + } + + boost::optional get_id() const { + return get_attribute("id"); + } + + void add_child(basic_element *element) { + assert(is_tag()); + boost::shared_ptr > shared_element(element); + children_.push_back(shared_element); + } + + boost::iterator_range + get_children() const { + return boost::make_iterator_range(boost::begin(children_), + boost::end(children_)); + } + +private: + + // if it's a tag node + string_type name_; + headers_container_type attributes_; + element_children_type children_; + + // if it's a text node + boost::optional text_; + +}; + + +typedef basic_element element; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp new file mode 100644 index 000000000..72924ec96 --- /dev/null +++ b/boost/network/protocol/xmpp/element_io.hpp @@ -0,0 +1,57 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +std::ostream &operator << (std::ostream &os, + const basic_element &element) { + if (element.is_tag()) { + os << "<" << element.get_name(); + boost::iterator_range::headers_container_type::const_iterator> + attributes(element.get_attributes()); + + typename basic_element::headers_container_type::const_iterator + attr_it(boost::begin(attributes)), + attr_end(boost::end(attributes)); + for (; attr_it != attr_end; ++attr_it) { + os << " " << attr_it->first << "=\"" << attr_it->second << "\""; + } + os << ">"; + + boost::iterator_range::element_children_type::const_iterator> + children(element.get_children()); + + typename basic_element::element_children_type::const_iterator + child_it(boost::begin(children)), + child_end(boost::end(children)); + for (; child_it != child_end; ++child_it) { + os << **child_it; + } + os << ""; + } + else { + os << element.get_text().get(); + } + return os; +} +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/boost/network/protocol/xmpp/errors.hpp b/boost/network/protocol/xmpp/errors.hpp new file mode 100644 index 000000000..5acbcbc06 --- /dev/null +++ b/boost/network/protocol/xmpp/errors.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ + + +namespace boost { +namespace network { +namespace xmpp { +enum errors { + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp new file mode 100644 index 000000000..7ee8a95d7 --- /dev/null +++ b/boost/network/protocol/xmpp/iq.hpp @@ -0,0 +1,63 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_iq + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_iq() { + + } + + basic_iq(const basic_iq &other) + : basic_stanza(other) { + + } + + basic_iq &operator = (const basic_iq &other) { + basic_iq tmp(other); + swap(tmp); + return *this; + } + + ~basic_iq() { + + } + + void swap(basic_iq &other) { + base_type::swap(other); + } + +}; + + +typedef basic_iq iq; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_IQ_INC__ diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp new file mode 100644 index 000000000..915e9c42b --- /dev/null +++ b/boost/network/protocol/xmpp/message.hpp @@ -0,0 +1,83 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_message + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_message() { + + } + + basic_message(const basic_message &other) + : basic_stanza(other) { + + } + + basic_message &operator = (const basic_message &other) { + basic_message tmp(other); + swap(tmp); + return *this; + } + + ~basic_message() { + + } + + void swap(basic_message &other) { + base_type::swap(other); + } + + void set_type(const string_type &type) { + static const char *type_ = "type"; + set_attribute(string_type(type_, type_ + std::strlen(type_)), type); + } + + string_type type() const { + static const char *type_ = "type"; + return attribute(string_type(type_, type_ + std::strlen(type_))); + } + + void set_id(const string_type &id) { + static const char *id_ = "id"; + set_attribute(string_type(id_, id_ + std::strlen(id_)), id); + } + + string_type id() const { + static const char *id_ = "id"; + return attribute(string_type(id_, id_ + std::strlen(id_))); + } + +}; + + +typedef basic_message message; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_MESSAGE_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp new file mode 100644 index 000000000..0721d9da4 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp @@ -0,0 +1,126 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_element_parser { +public: + + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_expat_element_parser() { + parser_ = XML_ParserCreate(NULL); + // handle the case where the parser is NULL + element_ = 0; + depth_ = 0; + + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, start_element, end_element); + XML_SetCharacterDataHandler(parser_, cdata); + } + + ~basic_expat_element_parser() { + XML_ParserFree(parser_); + } + + bool feed(const string_type &chunk) { + return feed(chunk, 0); + } + + bool feed(const string_type &chunk, element_type *element) { + element_ = element; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + +private: + + static void set_name(element_type *element, const XML_Char *name) { + const XML_Char *name_begin = name; + const XML_Char *name_end = name_begin + std::strlen(name_begin); + + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(element_type *element, const XML_Char **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const XML_Char *key_begin = attrs[i]; + const XML_Char *key_end = key_begin + std::strlen(key_begin); + + const XML_Char *val_begin = attrs[i + 1]; + const XML_Char *val_end = val_begin + std::strlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const XML_Char *name, + const XML_Char **attrs) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->element_, name); + set_attributes(parser->element_, attrs); + } + else if (parser->depth_ > 1) { + element_type *child = new element_type; + set_name(child, name); + set_attributes(child, attrs); + parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const XML_Char *name) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void cdata(void *userdata, + const XML_Char *s, + int len) { + basic_expat_element_parser *parser + = static_cast *>(userdata); + + parser->element_->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + XML_Parser parser_; + element_type *element_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp new file mode 100644 index 000000000..80bbeea39 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp @@ -0,0 +1,124 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_stanza_parser { +public: + + typedef typename string::type string_type; + + typedef basic_stanza stanza_type; + + basic_expat_stanza_parser() { + parser_ = XML_ParserCreate(NULL); + // handle the case where the parser is NULL + stanza_ = 0; + depth_ = 0; + + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, start_element, end_element); + XML_SetCharacterDataHandler(parser_, cdata); + } + + ~basic_expat_stanza_parser() { + XML_ParserFree(parser_); + } + + bool feed(const string_type &chunk) { + stanza_ = 0; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + stanza_ = &stanza; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + +private: + + static void set_name(stanza_type *stanza, const XML_Char *name) { + const XML_Char *name_begin = name; + const XML_Char *name_end = name_begin + std::strlen(name_begin); + + stanza->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(stanza_type *stanza, const XML_Char **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const XML_Char *key_begin = attrs[i]; + const XML_Char *key_end = key_begin + std::strlen(key_begin); + + const XML_Char *val_begin = attrs[i + 1]; + const XML_Char *val_end = val_begin + std::strlen(val_begin); + + stanza->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const XML_Char *name, + const XML_Char **attrs) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->stanza_, name); + set_attributes(parser->stanza_, attrs); + } + else if (parser->depth_ > 1) { + // element_type *child = new element_type; + // set_name(child, name); + // set_attributes(child, attrs); + // parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const XML_Char *name) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void cdata(void *userdata, + const XML_Char *s, + int len) { + basic_expat_stanza_parser *parser + = static_cast *>(userdata); + } + + XML_Parser parser_; + stanza_type *stanza_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp b/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp new file mode 100644 index 000000000..48c3aa1f1 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp @@ -0,0 +1,31 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_parser + : public basic_expat_element_parser { + +public: + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp new file mode 100644 index 000000000..53a628743 --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp @@ -0,0 +1,129 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_element_parser { + +public: + + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_libxml2_element_parser() { + std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); + handlers_.startElement = start_element; + handlers_.endElement = end_element; + handlers_.characters = characters; + depth_ = 0; + element_ = 0; + + context_ = xmlCreatePushParserCtxt(&handlers_, + this, 0, 0, 0); + // assert(!context_); + } + + ~basic_libxml2_element_parser() { + xmlFreeParserCtxt(context_); + } + + bool feed(const string_type &chunk) { + return feed(chunk, 0); + } + + bool feed(const string_type &chunk, element_type *element) { + element_ = element; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + +private: + + static void set_name(element_type *element, const xmlChar *name) { + const xmlChar *name_begin = name; + const xmlChar *name_end = name_begin + xmlStrlen(name_begin); + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(basic_element *element, const xmlChar **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const xmlChar *key_begin = attrs[i]; + const xmlChar *key_end = key_begin + xmlStrlen(key_begin); + + const xmlChar *val_begin = attrs[i + 1]; + const xmlChar *val_end = val_begin + xmlStrlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const xmlChar *name, + const xmlChar **attrs) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->element_, name); + set_attributes(parser->element_, attrs); + } + else if (parser->depth_ > 1) { + element_type *child = new element_type; + set_name(child, name); + set_attributes(child, attrs); + parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const xmlChar *name) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void characters(void *userdata, + const xmlChar *s, + int len) { + basic_libxml2_element_parser *parser + = static_cast *>(userdata); + + parser->element_->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + xmlParserCtxtPtr context_; + xmlSAXHandler handlers_; + element_type *element_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp new file mode 100644 index 000000000..8f40fa77b --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp @@ -0,0 +1,127 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_stanza_parser { + +public: + + typedef typename string::type string_type; + + typedef basic_stanza stanza_type; + + basic_libxml2_stanza_parser() { + std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); + handlers_.startElement = start_element; + handlers_.endElement = end_element; + handlers_.characters = characters; + depth_ = 0; + stanza_ = 0; + + context_ = xmlCreatePushParserCtxt(&handlers_, + this, 0, 0, 0); + // assert(!context_); + } + + ~basic_libxml2_stanza_parser() { + xmlFreeParserCtxt(context_); + } + + bool feed(const string_type &chunk) { + stanza_ = 0; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + stanza_ = &stanza; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + +private: + + static void set_name(stanza_type *stanza, const xmlChar *name) { + const xmlChar *name_begin = name; + const xmlChar *name_end = name_begin + xmlStrlen(name_begin); + stanza->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(basic_stanza *stanza, const xmlChar **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const xmlChar *key_begin = attrs[i]; + const xmlChar *key_end = key_begin + xmlStrlen(key_begin); + + const xmlChar *val_begin = attrs[i + 1]; + const xmlChar *val_end = val_begin + xmlStrlen(val_begin); + + stanza->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const xmlChar *name, + const xmlChar **attrs) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + + if (parser->depth_ == 1) { + set_name(parser->stanza_, name); + set_attributes(parser->stanza_, attrs); + } + else if (parser->depth_ > 1) { + // element_type *child = new element_type; + // set_name(child, name); + // set_attributes(child, attrs); + // parser->element_->add_child(child); + } + + ++parser->depth_; + } + + static void end_element(void *userdata, + const xmlChar *name) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + + --parser->depth_; + } + + static void characters(void *userdata, + const xmlChar *s, + int len) { + basic_libxml2_stanza_parser *parser + = static_cast *>(userdata); + } + + xmlParserCtxtPtr context_; + xmlSAXHandler handlers_; + stanza_type *stanza_; + int depth_; + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp b/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp new file mode 100644 index 000000000..799c0ed2d --- /dev/null +++ b/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp @@ -0,0 +1,31 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_libxml2_parser + : public basic_libxml2_element_parser { + +public: + +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp new file mode 100644 index 000000000..60ba2aa2e --- /dev/null +++ b/boost/network/protocol/xmpp/presence.hpp @@ -0,0 +1,63 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ + + +# include +// # include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_presence + : public basic_stanza { + + typedef basic_stanza base_type; + +public: + + typedef typename base_type::string_type string_type; + typedef typename base_type::headers_container_type headers_container_type; + + basic_presence() { + + } + + basic_presence(const basic_presence &other) + : basic_stanza(other) { + + } + + basic_presence &operator = (const basic_presence &other) { + basic_presence tmp(other); + swap(tmp); + return *this; + } + + ~basic_presence() { + + } + + void swap(basic_presence &other) { + base_type::swap(other); + } + +}; + + +typedef basic_presence presence; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PRESENCE_INC__ diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp new file mode 100644 index 000000000..b3d06ebad --- /dev/null +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -0,0 +1,64 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_stanza + : public boost::network::basic_message { + + typedef boost::network::basic_message base_type; + +public: + + typedef typename base_type::string_type string_type; + + void set_name(const string_type &name) { + name_ = name; + } + + string_type name() const { + return name_; + } + + void set_attribute(const string_type &key, const string_type &value) { + this->headers().insert(std::make_pair(key, value)); + } + + string_type attribute(const string_type &key) const { + typename headers_range >::type range + = this->headers().equal_range(key); + if (boost::begin(range) == boost::end(range)) { + return string_type(); + } + + return boost::begin(range)->second; + } + +private: + + string_type name_; + +}; + + +typedef basic_stanza stanza; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_STANZA_INC__ diff --git a/boost/network/protocol/xmpp/traits/element_children.hpp b/boost/network/protocol/xmpp/traits/element_children.hpp new file mode 100644 index 000000000..a2692c881 --- /dev/null +++ b/boost/network/protocol/xmpp/traits/element_children.hpp @@ -0,0 +1,42 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ + + +# include +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_element; + + +template < + class Tag + > +struct element_children { + typedef unsupported_tag type; +}; + + +template <> +struct element_children { + typedef std::list > > type; +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ diff --git a/boost/network/protocol/xmpp/traits/parser_backend.hpp b/boost/network/protocol/xmpp/traits/parser_backend.hpp new file mode 100644 index 000000000..7ab680a8b --- /dev/null +++ b/boost/network/protocol/xmpp/traits/parser_backend.hpp @@ -0,0 +1,41 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_expat_parser; + + +template < + class Tag + > +struct parser_backend { + typedef unsupported_tag type; +}; + + +template <> +struct parser_backend { + typedef basic_expat_parser type; +}; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 8df8ab4d1..66ff73670 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -13,6 +13,8 @@ endif() find_package( Threads ) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) +find_package( EXPAT ) +find_package( LibXml2 ) if (Boost_FOUND) add_executable(cpp-netlib-http_incremental_parser http_incremental_parser.cpp) @@ -56,5 +58,39 @@ if (Boost_FOUND) add_test(cpp-netlib-message_test ../../../build/tests/cpp-netlib-message_test) add_test(cpp-netlib-http_message_test ../../../build/tests/cpp-netlib-http_message_test) add_test(cpp-netlib-url_test ../../../build/tests/cpp-netlib-url_test) + + add_executable(cpp-netlib-xmpp_element_tests xmpp/xmpp_element_tests.cpp) + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_element_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + add_test(cpp-netlib-xmpp_element_tests ../../../build/tests/cpp-netlib-xmpp_element_tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + + if (EXPAT_FOUND) + include_directories( ${EXPAT_INCLUDE_DIRS} ) + add_executable(cpp-netlib-expat_element_parser_tests xmpp/expat_element_parser_tests.cpp) + add_executable(cpp-netlib-expat_stanza_parser_tests xmpp/expat_stanza_parser_tests.cpp) + target_link_libraries(cpp-netlib-expat_element_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-expat_element_parser_tests ../../../build/tests/cpp-netlib-expat_element_parser_tests) + add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + endif() + + if (LIBXML2_FOUND) + include_directories( ${LIBXML2_INCLUDE_DIR} ) + add_executable(cpp-netlib-libxml2_element_parser_tests xmpp/libxml2_element_parser_tests.cpp) + add_executable(cpp-netlib-libxml2_stanza_parser_tests xmpp/libxml2_stanza_parser_tests.cpp) + target_link_libraries(cpp-netlib-libxml2_element_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parserg_tests) + add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parserg_tests) + endif() + endif() diff --git a/libs/network/test/xmpp/expat_element_parser_tests.cpp b/libs/network/test/xmpp/expat_element_parser_tests.cpp new file mode 100644 index 000000000..6b13f0505 --- /dev/null +++ b/libs/network/test/xmpp/expat_element_parser_tests.cpp @@ -0,0 +1,77 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +basic_expat_element_parser element_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + element_parser.feed(""); + } + + ~xml_document_fixture() { + element_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("body", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("show", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + element instance; + element_parser.feed("", &instance); + BOOST_CHECK_EQUAL("iq", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); +} diff --git a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp new file mode 100644 index 000000000..cf9dafe92 --- /dev/null +++ b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp @@ -0,0 +1,61 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::message; +using boost::network::xmpp::presence; +using boost::network::xmpp::iq; + + +basic_expat_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.name()); + BOOST_CHECK_EQUAL("foo", instance.attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + iq instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("iq", instance.name()); + BOOST_CHECK_EQUAL("bar", instance.attribute("to")); +} diff --git a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp b/libs/network/test/xmpp/libxml2_element_parser_tests.cpp new file mode 100644 index 000000000..4723d8ef5 --- /dev/null +++ b/libs/network/test/xmpp/libxml2_element_parser_tests.cpp @@ -0,0 +1,77 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +basic_libxml2_parser libxml2_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + libxml2_parser.feed(""); + } + + ~xml_document_fixture() { + libxml2_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("body", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("show", (*boost::begin(children))->get_name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + element instance; + libxml2_parser.feed("", &instance); + BOOST_CHECK_EQUAL("iq", instance.get_name()); + BOOST_CHECK(instance.get_attribute("to")); + BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); +} diff --git a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp new file mode 100644 index 000000000..f2242df34 --- /dev/null +++ b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp @@ -0,0 +1,61 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::message; +using boost::network::xmpp::presence; +using boost::network::xmpp::iq; + + +basic_libxml2_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.name()); + BOOST_CHECK_EQUAL("foo", instance.attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.name()); +} + + +BOOST_AUTO_TEST_CASE(parse_iq_test) { + iq instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("iq", instance.name()); + BOOST_CHECK_EQUAL("bar", instance.attribute("to")); +} diff --git a/libs/network/test/xmpp/xmpp_element_tests.cpp b/libs/network/test/xmpp/xmpp_element_tests.cpp new file mode 100644 index 000000000..9dcf60c41 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_element_tests.cpp @@ -0,0 +1,88 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP element tests +#include +#include +#include + + +using namespace boost::network::xmpp; +using boost::network::xmpp::element; + + +BOOST_AUTO_TEST_CASE(default_constructor_test) { + element instance; + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(!instance.is_text()); +} + + +BOOST_AUTO_TEST_CASE(tag_constructor_test) { + element instance(element::tag(), "message"); + BOOST_CHECK(instance.is_tag()); + BOOST_CHECK(!instance.is_text()); + BOOST_CHECK_EQUAL(instance.get_name(), std::string("message")); +} + + +BOOST_AUTO_TEST_CASE(text_constructor_test) { + element instance(element::text(), "data"); + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(instance.is_text()); + BOOST_CHECK(instance.get_text()); + BOOST_CHECK_EQUAL(instance.get_text().get(), std::string("data")); +} + + +BOOST_AUTO_TEST_CASE(text_constructor_empty_string_test) { + element instance(element::text(), ""); + BOOST_CHECK(!instance.is_tag()); + BOOST_CHECK(instance.is_text()); + BOOST_CHECK(instance.get_text().get().empty()); +} + + +BOOST_AUTO_TEST_CASE(children_test) { + element instance(element::tag(), "message"); + instance.set_attribute("from", "someone@example.org"); + instance.set_attribute("to", "world@example.org"); + element *body = new element(element::tag(), "body"); + element *text = new element(element::text(), "Hello world!"); + body->add_child(text); + instance.add_child(body); + + boost::iterator_range + children_1(instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children_1), + boost::end(children_1)), 1); + + boost::iterator_range + children_2((*boost::begin(children_1))->get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children_2), + boost::end(children_2)), 1); + BOOST_CHECK((*boost::begin(children_2))->is_text()); + BOOST_CHECK_EQUAL((*boost::begin(children_2))->get_text(), std::string("Hello world!")); +} + + +BOOST_AUTO_TEST_CASE(element_ostream_test) { + element instance(element::tag(), "message"); + instance.set_attribute("from", "someone@example.org"); + instance.set_attribute("to", "world@example.org"); + element *body = new element(element::tag(), "body"); + element *text = new element(element::text(), "Hello world!"); + body->add_child(text); + instance.add_child(body); + + std::ostringstream os; + os << instance; + + BOOST_CHECK_EQUAL(os.str(), + std::string("" + "Hello world!")); +} diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp new file mode 100644 index 000000000..5a971a2c0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP iq tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::iq; + + +BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { + iq instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_iq_destination_directive_test) { + iq instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp new file mode 100644 index 000000000..0098a4450 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -0,0 +1,80 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP message tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::message; + + +BOOST_AUTO_TEST_CASE(xmpp_message_source_directive_test) { + message instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_destination_directive_test) { + message instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_header_directive_test) { + message instance; + instance << boost::network::header("type", "chat"); + BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); + boost::network::headers_range::type range + = boost::network::headers(instance)["type"]; + BOOST_CHECK (boost::begin(range) != boost::end(range)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_body_directive_test) { + message instance; + instance << boost::network::header("type", "chat") + << boost::network::body("Hello world!"); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_type_accessor_test) { + message instance; + instance.set_type("chat"); + BOOST_CHECK_EQUAL("chat", instance.type()); +} + + +BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { + message instance; + instance.set_id("t2w4qax3"); + BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); +} + + +// BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { +// message instance; +// instance << xmpp::type("chat"); +// BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); +// } +// +// +// BOOST_AUTO_TEST_CASE(xmpp_message_id_directive_test) { +// message instance; +// instance << xmpp::id("t2w4qax3"); +// BOOST_CHECK_EQUAL("t2w4qax3", xmpp::id(instance)); +// } +// +// +// BOOST_AUTO_TEST_CASE(xmpp_message_error_directive_test) { +// message instance; +// instance << boost::network::source("source@example.com") +// << boost::network::destination("dest@example.com") +// ; +// } diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp new file mode 100644 index 000000000..3997bd0db --- /dev/null +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -0,0 +1,27 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP presence tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +using boost::network::xmpp::presence; + + +BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { + presence instance; + instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); +} + + +BOOST_AUTO_TEST_CASE(xmpp_presence_destination_directive_test) { + presence instance; + instance << boost::network::destination("dest@example.com"); + BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); +} diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp new file mode 100644 index 000000000..31288c95a --- /dev/null +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -0,0 +1,10 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP stanza tests +#include +#include diff --git a/libs/network/test/xmpp/xmpp_uri_tests.cpp b/libs/network/test/xmpp/xmpp_uri_tests.cpp new file mode 100644 index 000000000..6bd6bc36c --- /dev/null +++ b/libs/network/test/xmpp/xmpp_uri_tests.cpp @@ -0,0 +1,23 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + + +#define BOOST_TEST_MODULE XMPP XML parsers +#include +#include +#include +#include + +namespace xmpp = boost::network::uri::xmpp; + + +BOOST_AUTO_TEST_CASE(simple_uri_test) { + xmpp::uri uri("node@jabber.org"); + BOOST_CHECK(uri.to_string() == "node@jabber.org"); + BOOST_CHECK(uri.node() == "node"); + BOOST_CHECK(uri.domain() == "jabber.org"); + BOOST_CHECK(uri.resource().empty()); +} From 65f35a5ebb57b249ce21320910b756c8333c7fc1 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 28 Aug 2010 11:27:10 +0200 Subject: [PATCH 008/438] Refactored XML element outside XMPP. --- boost/network/detail/xml_wrappers/element.hpp | 172 ++++++++++++++++++ .../detail/xml_wrappers/element_io.hpp | 57 ++++++ .../parser_backends/expat/element_parser.hpp | 12 +- .../parser_backends/expat/stanza_parser.hpp | 10 +- .../parser_backends/expat_parser.hpp | 12 +- .../libxml2/element_parser.hpp | 12 +- .../parser_backends/libxml2/stanza_parser.hpp | 10 +- .../parser_backends/libxml2_parser.hpp | 12 +- .../xml_wrappers}/traits/element_children.hpp | 10 +- .../xml_wrappers}/traits/parser_backend.hpp | 10 +- .../protocol/xmpp/{details => detail}/ns.hpp | 0 boost/network/protocol/xmpp/element.hpp | 160 +--------------- boost/network/protocol/xmpp/element_io.hpp | 45 +---- libs/network/test/CMakeLists.txt | 72 +++++--- .../expat_element_parser_tests.cpp | 10 +- .../libxml2_element_parser_tests.cpp | 10 +- .../xml_element_tests.cpp} | 10 +- 17 files changed, 339 insertions(+), 285 deletions(-) create mode 100644 boost/network/detail/xml_wrappers/element.hpp create mode 100644 boost/network/detail/xml_wrappers/element_io.hpp rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat/element_parser.hpp (90%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat/stanza_parser.hpp (91%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/expat_parser.hpp (53%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2/element_parser.hpp (90%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2/stanza_parser.hpp (92%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/parser_backends/libxml2_parser.hpp (53%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/traits/element_children.hpp (71%) rename boost/network/{protocol/xmpp => detail/xml_wrappers}/traits/parser_backend.hpp (71%) rename boost/network/protocol/xmpp/{details => detail}/ns.hpp (100%) rename libs/network/test/{xmpp => xml_wrappers}/expat_element_parser_tests.cpp (89%) rename libs/network/test/{xmpp => xml_wrappers}/libxml2_element_parser_tests.cpp (89%) rename libs/network/test/{xmpp/xmpp_element_tests.cpp => xml_wrappers/xml_element_tests.cpp} (92%) diff --git a/boost/network/detail/xml_wrappers/element.hpp b/boost/network/detail/xml_wrappers/element.hpp new file mode 100644 index 000000000..9300c59b3 --- /dev/null +++ b/boost/network/detail/xml_wrappers/element.hpp @@ -0,0 +1,172 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ + + +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { +namespace network { +namespace detail { +template < + class Tag + > +class basic_element { + +public: + + struct tag {}; + struct text {}; + + typedef typename string::type string_type; + typedef typename headers_container::type headers_container_type; + typedef typename element_children::type element_children_type; + + basic_element() { + + } + + basic_element(tag, const string_type &name) + : name_(name) { + + } + + basic_element(text, const string_type &text) + : text_(text) { + + } + + basic_element(const basic_element &other) + : name_(other.name_), + attributes_(other.attributes_), + children_(other.children_), + text_(other.text_) { + + } + + basic_element &operator = (const basic_element &other) { + basic_element tmp(other); + swap(tmp); + return *this; + } + + ~basic_element() { + + } + + void swap(basic_element &other) { + std::swap(name_, other.name_); + std::swap(attributes_, other.attributes_); + std::swap(children_, other.children_); + std::swap(text_, other.text_); + } + + void set_name(const string_type &name) { + assert(!is_text()); + name_ = name; + } + + string_type get_name() const { + assert(is_tag()); + return name_; + } + + void set_text(const string_type &text) { + assert(!is_tag()); + text_ = text; + } + + boost::optional get_text() const { + assert(is_text()); + return text_.get(); + } + + bool is_tag() const { + return !name_.empty(); + } + + bool is_text() const { + return static_cast(text_); + } + + void set_attribute(const string_type &name, const string_type &value) { + assert(is_tag()); + attributes_.insert(typename headers_container_type::value_type(name, value)); + } + + boost::optional get_attribute(const string_type &name) const { + typename headers_container_type::const_iterator it = attributes_.find(name); + if (it != attributes_.end()) { + return it->second; + } + return boost::none; + } + + boost::iterator_range + get_attributes() const { + return boost::make_iterator_range(boost::begin(attributes_), + boost::end(attributes_)); + } + + boost::optional get_namespace() const { + return get_attribute("xmlns"); + } + + boost::optional get_type() const { + return get_attribute("type"); + } + + boost::optional get_lang() const { + return get_attribute("xml:lang"); + } + + boost::optional get_id() const { + return get_attribute("id"); + } + + void add_child(basic_element *element) { + assert(is_tag()); + boost::shared_ptr > shared_element(element); + children_.push_back(shared_element); + } + + boost::iterator_range + get_children() const { + return boost::make_iterator_range(boost::begin(children_), + boost::end(children_)); + } + +private: + + // if it's a tag node + string_type name_; + headers_container_type attributes_; + element_children_type children_; + + // if it's a text node + boost::optional text_; + +}; + + +typedef basic_element element; +} // namespace detail +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ diff --git a/boost/network/detail/xml_wrappers/element_io.hpp b/boost/network/detail/xml_wrappers/element_io.hpp new file mode 100644 index 000000000..9590cec00 --- /dev/null +++ b/boost/network/detail/xml_wrappers/element_io.hpp @@ -0,0 +1,57 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ + + +# include +# include + + +namespace boost { +namespace network { +namespace detail { +template < + class Tag + > +std::ostream &operator << (std::ostream &os, + const basic_element &element) { + if (element.is_tag()) { + os << "<" << element.get_name(); + boost::iterator_range::headers_container_type::const_iterator> + attributes(element.get_attributes()); + + typename basic_element::headers_container_type::const_iterator + attr_it(boost::begin(attributes)), + attr_end(boost::end(attributes)); + for (; attr_it != attr_end; ++attr_it) { + os << " " << attr_it->first << "=\"" << attr_it->second << "\""; + } + os << ">"; + + boost::iterator_range::element_children_type::const_iterator> + children(element.get_children()); + + typename basic_element::element_children_type::const_iterator + child_it(boost::begin(children)), + child_end(boost::end(children)); + for (; child_it != child_end; ++child_it) { + os << **child_it; + } + os << ""; + } + else { + os << element.get_text().get(); + } + return os; +} +} // namespace detail +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp similarity index 90% rename from boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp index 0721d9da4..e73b3e536 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp @@ -4,19 +4,19 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ # include -# include +# include # include # include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -118,9 +118,9 @@ class basic_expat_element_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp similarity index 91% rename from boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp index 80bbeea39..127d2cca7 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat/stanza_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ # include @@ -16,7 +16,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -116,9 +116,9 @@ class basic_expat_stanza_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp similarity index 53% rename from boost/network/protocol/xmpp/parser_backends/expat_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp index 48c3aa1f1..c569f1281 100644 --- a/boost/network/protocol/xmpp/parser_backends/expat_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp @@ -4,16 +4,16 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# include +# include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -23,9 +23,9 @@ class basic_expat_parser public: }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp similarity index 90% rename from boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp index 53a628743..74494bab4 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp @@ -4,19 +4,19 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ # include -# include +# include # include # include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -121,9 +121,9 @@ class basic_libxml2_element_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp similarity index 92% rename from boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp index 8f40fa77b..fc9d6e8e3 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2/stanza_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ # include @@ -16,7 +16,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -119,9 +119,9 @@ class basic_libxml2_stanza_parser { int depth_; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp similarity index 53% rename from boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp rename to boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp index 799c0ed2d..b49c49091 100644 --- a/boost/network/protocol/xmpp/parser_backends/libxml2_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp @@ -4,16 +4,16 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# include +# include namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -23,9 +23,9 @@ class basic_libxml2_parser public: }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/traits/element_children.hpp b/boost/network/detail/xml_wrappers/traits/element_children.hpp similarity index 71% rename from boost/network/protocol/xmpp/traits/element_children.hpp rename to boost/network/detail/xml_wrappers/traits/element_children.hpp index a2692c881..a9164a43b 100644 --- a/boost/network/protocol/xmpp/traits/element_children.hpp +++ b/boost/network/detail/xml_wrappers/traits/element_children.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ # include @@ -15,7 +15,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -34,9 +34,9 @@ template <> struct element_children { typedef std::list > > type; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_ELEMENT_CHILDREN_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ diff --git a/boost/network/protocol/xmpp/traits/parser_backend.hpp b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp similarity index 71% rename from boost/network/protocol/xmpp/traits/parser_backend.hpp rename to boost/network/detail/xml_wrappers/traits/parser_backend.hpp index 7ab680a8b..c33f5440b 100644 --- a/boost/network/protocol/xmpp/traits/parser_backend.hpp +++ b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ +# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ # include @@ -14,7 +14,7 @@ namespace boost { namespace network { -namespace xmpp { +namespace detail { template < class Tag > @@ -33,9 +33,9 @@ template <> struct parser_backend { typedef basic_expat_parser type; }; -} // namespace xmpp +} // namespace detail } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_TRAITS_PARSER_BACKEND_INC__ +#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ diff --git a/boost/network/protocol/xmpp/details/ns.hpp b/boost/network/protocol/xmpp/detail/ns.hpp similarity index 100% rename from boost/network/protocol/xmpp/details/ns.hpp rename to boost/network/protocol/xmpp/detail/ns.hpp diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp index 22f0e3c4a..4225054eb 100644 --- a/boost/network/protocol/xmpp/element.hpp +++ b/boost/network/protocol/xmpp/element.hpp @@ -8,165 +8,7 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ -# include -# include -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag - > -class basic_element { - -public: - - struct tag {}; - struct text {}; - - typedef typename string::type string_type; - typedef typename headers_container::type headers_container_type; - typedef typename element_children::type element_children_type; - - basic_element() { - - } - - basic_element(tag, const string_type &name) - : name_(name) { - - } - - basic_element(text, const string_type &text) - : text_(text) { - - } - - basic_element(const basic_element &other) - : name_(other.name_), - attributes_(other.attributes_), - children_(other.children_), - text_(other.text_) { - - } - - basic_element &operator = (const basic_element &other) { - basic_element tmp(other); - swap(tmp); - return *this; - } - - ~basic_element() { - - } - - void swap(basic_element &other) { - std::swap(name_, other.name_); - std::swap(attributes_, other.attributes_); - std::swap(children_, other.children_); - std::swap(text_, other.text_); - } - - void set_name(const string_type &name) { - assert(!is_text()); - name_ = name; - } - - string_type get_name() const { - assert(is_tag()); - return name_; - } - - void set_text(const string_type &text) { - assert(!is_tag()); - text_ = text; - } - - boost::optional get_text() const { - assert(is_text()); - return text_.get(); - } - - bool is_tag() const { - return !name_.empty(); - } - - bool is_text() const { - return static_cast(text_); - } - - void set_attribute(const string_type &name, const string_type &value) { - assert(is_tag()); - attributes_.insert(typename headers_container_type::value_type(name, value)); - } - - boost::optional get_attribute(const string_type &name) const { - typename headers_container_type::const_iterator it = attributes_.find(name); - if (it != attributes_.end()) { - return it->second; - } - return boost::none; - } - - boost::iterator_range - get_attributes() const { - return boost::make_iterator_range(boost::begin(attributes_), - boost::end(attributes_)); - } - - boost::optional get_namespace() const { - return get_attribute("xmlns"); - } - - boost::optional get_type() const { - return get_attribute("type"); - } - - boost::optional get_lang() const { - return get_attribute("xml:lang"); - } - - boost::optional get_id() const { - return get_attribute("id"); - } - - void add_child(basic_element *element) { - assert(is_tag()); - boost::shared_ptr > shared_element(element); - children_.push_back(shared_element); - } - - boost::iterator_range - get_children() const { - return boost::make_iterator_range(boost::begin(children_), - boost::end(children_)); - } - -private: - - // if it's a tag node - string_type name_; - headers_container_type attributes_; - element_children_type children_; - - // if it's a text node - boost::optional text_; - -}; - - -typedef basic_element element; -} // namespace xmpp -} // namespace network -} // namespace boost +# include #endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp index 72924ec96..155b4fd22 100644 --- a/boost/network/protocol/xmpp/element_io.hpp +++ b/boost/network/protocol/xmpp/element_io.hpp @@ -8,50 +8,7 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag - > -std::ostream &operator << (std::ostream &os, - const basic_element &element) { - if (element.is_tag()) { - os << "<" << element.get_name(); - boost::iterator_range::headers_container_type::const_iterator> - attributes(element.get_attributes()); - - typename basic_element::headers_container_type::const_iterator - attr_it(boost::begin(attributes)), - attr_end(boost::end(attributes)); - for (; attr_it != attr_end; ++attr_it) { - os << " " << attr_it->first << "=\"" << attr_it->second << "\""; - } - os << ">"; - - boost::iterator_range::element_children_type::const_iterator> - children(element.get_children()); - - typename basic_element::element_children_type::const_iterator - child_it(boost::begin(children)), - child_end(boost::end(children)); - for (; child_it != child_end; ++child_it) { - os << **child_it; - } - os << ""; - } - else { - os << element.get_text().get(); - } - return os; -} -} // namespace xmpp -} // namespace network -} // namespace boost +# include #endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 66ff73670..2bc3b70b4 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -48,7 +48,19 @@ if (Boost_FOUND) target_link_libraries(cpp-netlib-https_localhost_tests ${OPENSSL_LIBRARIES} ) target_link_libraries(cpp-netlib-url_test ${OPENSSL_LIBRARIES} ) endif() - set_target_properties(cpp-netlib-http_incremental_parser cpp-netlib-hello_world cpp-netlib-http_1_0_test cpp-netlib-http_1_1_test cpp-netlib-message_test cpp-netlib-http_message_test cpp-netlib-message_transform_test cpp-netlib-http_localhost_tests cpp-netlib-https_localhost_tests cpp-netlib-url_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + + set_target_properties(cpp-netlib-http_incremental_parser + cpp-netlib-hello_world + cpp-netlib-http_1_0_test + cpp-netlib-http_1_1_test + cpp-netlib-message_test + cpp-netlib-http_message_test + cpp-netlib-message_transform_test + cpp-netlib-http_localhost_tests + cpp-netlib-https_localhost_tests + cpp-netlib-url_test + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-http_incremental_parser ../../../build/tests/cpp-netlib-http_incremental_parser) add_test(cpp-netlib-hello_world python httplib_acceptance.py ../../../build/tests/cpp-netlib-hello_world ../../../build/tests/cpp-netlib-hello_world.passed) add_test(cpp-netlib-http_1_0_test ../../../build/tests/cpp-netlib-http_1_0_test) @@ -59,38 +71,52 @@ if (Boost_FOUND) add_test(cpp-netlib-http_message_test ../../../build/tests/cpp-netlib-http_message_test) add_test(cpp-netlib-url_test ../../../build/tests/cpp-netlib-url_test) - add_executable(cpp-netlib-xmpp_element_tests xmpp/xmpp_element_tests.cpp) - add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) - add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) - add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) - target_link_libraries(cpp-netlib-xmpp_element_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) - add_test(cpp-netlib-xmpp_element_tests ../../../build/tests/cpp-netlib-xmpp_element_tests) - add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) - add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) - add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + add_executable(cpp-netlib-xml_element_tests xml_wrappers/xml_element_tests.cpp) + target_link_libraries(cpp-netlib-xml_element_tests ${Boost_LIBRARIES}) + add_test(cpp-netlib-xml_element_tests ../../../build/tests/cpp-netlib-xml_element_tests) + + set_target_properties(cpp-netlib-xml_element_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) - add_executable(cpp-netlib-expat_element_parser_tests xmpp/expat_element_parser_tests.cpp) - add_executable(cpp-netlib-expat_stanza_parser_tests xmpp/expat_stanza_parser_tests.cpp) + add_executable(cpp-netlib-expat_element_parser_tests xml_wrappers/expat_element_parser_tests.cpp) target_link_libraries(cpp-netlib-expat_element_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) - target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) add_test(cpp-netlib-expat_element_parser_tests ../../../build/tests/cpp-netlib-expat_element_parser_tests) - add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + # add_executable(cpp-netlib-expat_stanza_parser_tests xml_wrappers/expat_stanza_parser_tests.cpp) + # target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + # add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + set_target_properties(cpp-netlib-expat_element_parser_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() if (LIBXML2_FOUND) include_directories( ${LIBXML2_INCLUDE_DIR} ) - add_executable(cpp-netlib-libxml2_element_parser_tests xmpp/libxml2_element_parser_tests.cpp) - add_executable(cpp-netlib-libxml2_stanza_parser_tests xmpp/libxml2_stanza_parser_tests.cpp) + add_executable(cpp-netlib-libxml2_element_parser_tests xml_wrappers/libxml2_element_parser_tests.cpp) target_link_libraries(cpp-netlib-libxml2_element_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) - target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) - add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parserg_tests) - add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parserg_tests) + add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parser_tests) + + # add_executable(cpp-netlib-libxml2_stanza_parser_tests xml_wrappers/libxml2_stanza_parser_tests.cpp) + # target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) + # add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parser_tests) + set_target_properties(cpp-netlib-libxml2_element_parser_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() -endif() + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + set_target_properties(cpp-netlib-xmpp_message_tests + cpp-netlib-xmpp_presence_tests + cpp-netlib-xmpp_iq_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) +endif() diff --git a/libs/network/test/xmpp/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp similarity index 89% rename from libs/network/test/xmpp/expat_element_parser_tests.cpp rename to libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index 6b13f0505..e2a00bd51 100644 --- a/libs/network/test/xmpp/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -5,14 +5,14 @@ -#define BOOST_TEST_MODULE XMPP XML parsers +#define BOOST_TEST_MODULE expat wrapper tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; basic_expat_element_parser element_parser; diff --git a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp similarity index 89% rename from libs/network/test/xmpp/libxml2_element_parser_tests.cpp rename to libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp index 4723d8ef5..47889b3cb 100644 --- a/libs/network/test/xmpp/libxml2_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp @@ -5,14 +5,14 @@ -#define BOOST_TEST_MODULE XMPP XML parsers +#define BOOST_TEST_MODULE libxml2 wrapper tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; basic_libxml2_parser libxml2_parser; diff --git a/libs/network/test/xmpp/xmpp_element_tests.cpp b/libs/network/test/xml_wrappers/xml_element_tests.cpp similarity index 92% rename from libs/network/test/xmpp/xmpp_element_tests.cpp rename to libs/network/test/xml_wrappers/xml_element_tests.cpp index 9dcf60c41..849b49881 100644 --- a/libs/network/test/xmpp/xmpp_element_tests.cpp +++ b/libs/network/test/xml_wrappers/xml_element_tests.cpp @@ -4,14 +4,14 @@ // http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_TEST_MODULE XMPP element tests +#define BOOST_TEST_MODULE XML element tests #include -#include -#include +#include +#include -using namespace boost::network::xmpp; -using boost::network::xmpp::element; +using namespace boost::network::detail; +using boost::network::detail::element; BOOST_AUTO_TEST_CASE(default_constructor_test) { From 7d16df8420d59cdb42a8840e9a6b78099835063d Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 29 Aug 2010 13:34:02 +0200 Subject: [PATCH 009/438] Updated client comments. --- boost/network/auth/sasl.hpp | 34 ++++++ boost/network/protocol/xmpp/client.hpp | 100 ++++++++++++++++-- boost/network/protocol/xmpp/element.hpp | 14 --- boost/network/protocol/xmpp/element_io.hpp | 14 --- boost/network/tls/tls.hpp | 26 +++++ libs/network/test/xmpp/xmpp_iq_tests.cpp | 5 +- libs/network/test/xmpp/xmpp_message_tests.cpp | 15 ++- .../network/test/xmpp/xmpp_presence_tests.cpp | 5 +- libs/network/test/xmpp/xmpp_stanza_tests.cpp | 10 -- libs/network/test/xmpp/xmpp_uri_tests.cpp | 23 ---- 10 files changed, 160 insertions(+), 86 deletions(-) create mode 100644 boost/network/auth/sasl.hpp delete mode 100644 boost/network/protocol/xmpp/element.hpp delete mode 100644 boost/network/protocol/xmpp/element_io.hpp create mode 100644 boost/network/tls/tls.hpp delete mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp delete mode 100644 libs/network/test/xmpp/xmpp_uri_tests.cpp diff --git a/boost/network/auth/sasl.hpp b/boost/network/auth/sasl.hpp new file mode 100644 index 000000000..dfcc8cd26 --- /dev/null +++ b/boost/network/auth/sasl.hpp @@ -0,0 +1,34 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_AUTH_SASL_INC__ +# define __BOOST_NETWORK_AUTH_SASL_INC__ + + +# include + + +namespace boost { +namespace network { +namespace auth { +template < + class Tag + > +class basic_sasl { + +public: + + // basic_sasl(PLAIN); + + // basic_sasl(DIGEST); + +}; +} // namespace auth +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_AUTH_SASL_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 42e61f422..b099b3627 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -28,9 +28,9 @@ class basic_client : boost::noncopyable { typedef typename string::type string_type; - typedef basic_message message; - typedef basic_presence presence; - typedef basic_iq iq; + typedef basic_message message_type; + typedef basic_presence presence_type; + typedef basic_iq iq_type; explicit basic_client(Handler handler); @@ -52,30 +52,108 @@ class basic_client : boost::noncopyable { string_type jid() const; - string_type bound_jid() const; - private: + void handle_stream_start(); + void handle_stream_stanza(); + void handle_stream_end(); + // tcp socket // tls // sasl - // parameters, such as jid, bound_jid, domain, port etc. + // parameters, such as jid, domain, port etc. + string_type jid_; // io_service + boost::asio::io_service io_service_; // xml parser - // event handler + Handler handler_; + +}; - // stream open handler - // connection event handlers +template < + class Tag, + class Handler + > +basic_client::basic_client(Handler handler) { + // set the handlers +} + +template < + class Tag, + class Handler + > +basic_client::~basic_client() { - Handler handler_; +} -}; +template < + class Tag, + class Handler + > +void basic_client::connect(const string_type &proxy_host, + const string_type &proxy_port) { + // get the JID domain + // default port is 52222 + // open socket + // socket has a state + // signal connection handler +} + +template < + class Tag, + class Handler + > +void basic_client::disconnect() { + // close socket + // signal connection handler +} + +template < + class Tag, + class Handler + > +void basic_client::authenticate(const string_type &jid, + const string_type &password) { + +} + +template < + class Tag, + class Handler + > +void basic_client::send_message(const message_type &message) { + +} + +template < + class Tag, + class Handler + > +void basic_client::send_presence(const presence_type &presence) { + +} +template < + class Tag, + class Handler + > +void basic_client::send_iq(const iq_type &iq) { + +} + +template < + class Tag, + class Handler + > +basic_client::string_type +basic_client::jid() const { + return jid_; +} template < diff --git a/boost/network/protocol/xmpp/element.hpp b/boost/network/protocol/xmpp/element.hpp deleted file mode 100644 index 4225054eb..000000000 --- a/boost/network/protocol/xmpp/element.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ - - -# include - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_INC__ diff --git a/boost/network/protocol/xmpp/element_io.hpp b/boost/network/protocol/xmpp/element_io.hpp deleted file mode 100644 index 155b4fd22..000000000 --- a/boost/network/protocol/xmpp/element_io.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ - - -# include - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ELEMENT_IO_INC__ diff --git a/boost/network/tls/tls.hpp b/boost/network/tls/tls.hpp new file mode 100644 index 000000000..ed7edc4e2 --- /dev/null +++ b/boost/network/tls/tls.hpp @@ -0,0 +1,26 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_TLS_TLS_INC__ +# define __BOOST_NETWORK_TLS_TLS_INC__ + + +namespace boost { +namespace network { +class tls { +public: + + // credentials + // start + // read + // write + +}; +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_TLS_TLS_INC__ diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index 5a971a2c0..e2f527d87 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -10,18 +10,17 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::iq; BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { - iq instance; + xmpp::iq instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_iq_destination_directive_test) { - iq instance; + xmpp::iq instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp index 0098a4450..61c6811f7 100644 --- a/libs/network/test/xmpp/xmpp_message_tests.cpp +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -10,49 +10,48 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::message; BOOST_AUTO_TEST_CASE(xmpp_message_source_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_destination_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_header_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::header("type", "chat"); BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); - boost::network::headers_range::type range + boost::network::headers_range::type range = boost::network::headers(instance)["type"]; BOOST_CHECK (boost::begin(range) != boost::end(range)); } BOOST_AUTO_TEST_CASE(xmpp_message_body_directive_test) { - message instance; + xmpp::message instance; instance << boost::network::header("type", "chat") << boost::network::body("Hello world!"); } BOOST_AUTO_TEST_CASE(xmpp_message_type_accessor_test) { - message instance; + xmpp::message instance; instance.set_type("chat"); BOOST_CHECK_EQUAL("chat", instance.type()); } BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { - message instance; + xmpp::message instance; instance.set_id("t2w4qax3"); BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); } diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp index 3997bd0db..4d9428df4 100644 --- a/libs/network/test/xmpp/xmpp_presence_tests.cpp +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -10,18 +10,17 @@ namespace xmpp = boost::network::xmpp; -using boost::network::xmpp::presence; BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { - presence instance; + xmpp::presence instance; instance << boost::network::source("source@example.com"); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_presence_destination_directive_test) { - presence instance; + xmpp::presence instance; instance << boost::network::destination("dest@example.com"); BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp deleted file mode 100644 index 31288c95a..000000000 --- a/libs/network/test/xmpp/xmpp_stanza_tests.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP stanza tests -#include -#include diff --git a/libs/network/test/xmpp/xmpp_uri_tests.cpp b/libs/network/test/xmpp/xmpp_uri_tests.cpp deleted file mode 100644 index 6bd6bc36c..000000000 --- a/libs/network/test/xmpp/xmpp_uri_tests.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include - -namespace xmpp = boost::network::uri::xmpp; - - -BOOST_AUTO_TEST_CASE(simple_uri_test) { - xmpp::uri uri("node@jabber.org"); - BOOST_CHECK(uri.to_string() == "node@jabber.org"); - BOOST_CHECK(uri.node() == "node"); - BOOST_CHECK(uri.domain() == "jabber.org"); - BOOST_CHECK(uri.resource().empty()); -} From 71e9a7c5f40b44514bd3f8627b7d9b19e90691d8 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Thu, 2 Sep 2010 20:17:06 +0200 Subject: [PATCH 010/438] I moved stuff around and forgot to check it in. --- boost/network/protocol/xmpp/detail/ns.hpp | 72 ------------------- boost/network/protocol/xmpp/directives.hpp | 38 ---------- .../protocol/xmpp/directives/attribute.hpp | 22 ------ .../protocol/xmpp/directives/destination.hpp | 22 ------ .../network/protocol/xmpp/directives/from.hpp | 22 ------ boost/network/protocol/xmpp/directives/id.hpp | 22 ------ .../protocol/xmpp/directives/namespace.hpp | 22 ------ .../protocol/xmpp/directives/source.hpp | 22 ------ .../network/protocol/xmpp/directives/text.hpp | 22 ------ boost/network/protocol/xmpp/directives/to.hpp | 22 ------ .../network/protocol/xmpp/directives/type.hpp | 41 ----------- boost/network/protocol/xmpp/errors.hpp | 22 ------ boost/network/protocol/xmpp/iq.hpp | 2 +- boost/network/protocol/xmpp/message.hpp | 6 +- boost/network/protocol/xmpp/presence.hpp | 2 +- boost/network/protocol/xmpp/stanza.hpp | 26 +++---- .../test/xmpp/expat_stanza_parser_tests.cpp | 61 ---------------- .../test/xmpp/libxml2_stanza_parser_tests.cpp | 61 ---------------- 18 files changed, 18 insertions(+), 489 deletions(-) delete mode 100644 boost/network/protocol/xmpp/detail/ns.hpp delete mode 100644 boost/network/protocol/xmpp/directives.hpp delete mode 100644 boost/network/protocol/xmpp/directives/attribute.hpp delete mode 100644 boost/network/protocol/xmpp/directives/destination.hpp delete mode 100644 boost/network/protocol/xmpp/directives/from.hpp delete mode 100644 boost/network/protocol/xmpp/directives/id.hpp delete mode 100644 boost/network/protocol/xmpp/directives/namespace.hpp delete mode 100644 boost/network/protocol/xmpp/directives/source.hpp delete mode 100644 boost/network/protocol/xmpp/directives/text.hpp delete mode 100644 boost/network/protocol/xmpp/directives/to.hpp delete mode 100644 boost/network/protocol/xmpp/directives/type.hpp delete mode 100644 boost/network/protocol/xmpp/errors.hpp delete mode 100644 libs/network/test/xmpp/expat_stanza_parser_tests.cpp delete mode 100644 libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp diff --git a/boost/network/protocol/xmpp/detail/ns.hpp b/boost/network/protocol/xmpp/detail/ns.hpp deleted file mode 100644 index c58c7747e..000000000 --- a/boost/network/protocol/xmpp/detail/ns.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace details { -class namespaces { -public: - - static const char *client() { - return "jabber:client"; - } - - static const char *component() { - return "jabber:component:accept"; - } - - static const char *streams() { - return "http://etherx.jabber.org/streams"; - } - - static const char *streams_ietf() { - return "urn:ietf:params:xml:ns:xmpp-streams"; - } - - static const char *tls() { - return "urn:ietf:params:xml:ns:xmpp-tls"; - } - - static const char *sasl() { - return "urn:ietf:params:xml:ns:xmpp-sasl"; - } - - static const char *bind() { - return "urn:ietf:params:xml:ns:xmpp-bind"; - } - - static const char *session() { - return "urn:ietf:params:xml:ns:xmpp-session"; - } - - static const char *auth() { - return "jabber:iq:auth"; - } - - static const char *disco_info() { - return "http://jabber.org/protocol/disco#info"; - } - - static const char *disco_items() { - return "http://jabber.org/protocol/disco#items"; - } - - static const char *roster() { - return "jabber:iq:roster"; - } -}; -} // namespace details -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAILS_NS_INC__ diff --git a/boost/network/protocol/xmpp/directives.hpp b/boost/network/protocol/xmpp/directives.hpp deleted file mode 100644 index 4d9b54c47..000000000 --- a/boost/network/protocol/xmpp/directives.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ - - -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace xmpp { -template < - class Tag, - class Directive - > -inline -basic_stanza &operator << (basic_stanza &stanza, - const Directive &directive) { - directive(stanza); - return stanza; -} -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_INC__ diff --git a/boost/network/protocol/xmpp/directives/attribute.hpp b/boost/network/protocol/xmpp/directives/attribute.hpp deleted file mode 100644 index 528ed79a5..000000000 --- a/boost/network/protocol/xmpp/directives/attribute.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ATTRIBUTE_INC__ diff --git a/boost/network/protocol/xmpp/directives/destination.hpp b/boost/network/protocol/xmpp/directives/destination.hpp deleted file mode 100644 index 49991d230..000000000 --- a/boost/network/protocol/xmpp/directives/destination.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_DESTINATION_INC__ diff --git a/boost/network/protocol/xmpp/directives/from.hpp b/boost/network/protocol/xmpp/directives/from.hpp deleted file mode 100644 index 4bd0989a2..000000000 --- a/boost/network/protocol/xmpp/directives/from.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_FROM_INC__ diff --git a/boost/network/protocol/xmpp/directives/id.hpp b/boost/network/protocol/xmpp/directives/id.hpp deleted file mode 100644 index 59b324c7f..000000000 --- a/boost/network/protocol/xmpp/directives/id.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_ID_INC__ diff --git a/boost/network/protocol/xmpp/directives/namespace.hpp b/boost/network/protocol/xmpp/directives/namespace.hpp deleted file mode 100644 index 90723783b..000000000 --- a/boost/network/protocol/xmpp/directives/namespace.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_NAMESPACE_INC__ diff --git a/boost/network/protocol/xmpp/directives/source.hpp b/boost/network/protocol/xmpp/directives/source.hpp deleted file mode 100644 index a09c5af3f..000000000 --- a/boost/network/protocol/xmpp/directives/source.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_SOURCE_INC__ diff --git a/boost/network/protocol/xmpp/directives/text.hpp b/boost/network/protocol/xmpp/directives/text.hpp deleted file mode 100644 index d334b38e4..000000000 --- a/boost/network/protocol/xmpp/directives/text.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TEXT_INC__ diff --git a/boost/network/protocol/xmpp/directives/to.hpp b/boost/network/protocol/xmpp/directives/to.hpp deleted file mode 100644 index fa722f5f2..000000000 --- a/boost/network/protocol/xmpp/directives/to.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace directives { - -} // namespace directives -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TO_INC__ diff --git a/boost/network/protocol/xmpp/directives/type.hpp b/boost/network/protocol/xmpp/directives/type.hpp deleted file mode 100644 index 72e2f160a..000000000 --- a/boost/network/protocol/xmpp/directives/type.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -namespace details { -template < - typename T - > -struct type_directive { - - explicit type_directive(T type) - : type_(type) { - - } - - template < - class MessageTag - > - void operator () (basic_message &message) const { - message.type() = type_; - } - - T type_; - -}; -} // namespace details -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DIRECTIVES_TYPE_INC__ diff --git a/boost/network/protocol/xmpp/errors.hpp b/boost/network/protocol/xmpp/errors.hpp deleted file mode 100644 index 5acbcbc06..000000000 --- a/boost/network/protocol/xmpp/errors.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ - - -namespace boost { -namespace network { -namespace xmpp { -enum errors { - -}; -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ERRORS_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp index 7ee8a95d7..f6c55c819 100644 --- a/boost/network/protocol/xmpp/iq.hpp +++ b/boost/network/protocol/xmpp/iq.hpp @@ -29,7 +29,7 @@ class basic_iq typedef typename base_type::headers_container_type headers_container_type; basic_iq() { - + set_name("iq"); } basic_iq(const basic_iq &other) diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp index 915e9c42b..4d6b2a7dc 100644 --- a/boost/network/protocol/xmpp/message.hpp +++ b/boost/network/protocol/xmpp/message.hpp @@ -29,7 +29,7 @@ class basic_message typedef typename base_type::headers_container_type headers_container_type; basic_message() { - + set_name("message"); } basic_message(const basic_message &other) @@ -58,7 +58,7 @@ class basic_message string_type type() const { static const char *type_ = "type"; - return attribute(string_type(type_, type_ + std::strlen(type_))); + return get_attribute(string_type(type_, type_ + std::strlen(type_))); } void set_id(const string_type &id) { @@ -68,7 +68,7 @@ class basic_message string_type id() const { static const char *id_ = "id"; - return attribute(string_type(id_, id_ + std::strlen(id_))); + return get_attribute(string_type(id_, id_ + std::strlen(id_))); } }; diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp index 60ba2aa2e..4c486b0d8 100644 --- a/boost/network/protocol/xmpp/presence.hpp +++ b/boost/network/protocol/xmpp/presence.hpp @@ -29,7 +29,7 @@ class basic_presence typedef typename base_type::headers_container_type headers_container_type; basic_presence() { - + set_name("presence"); } basic_presence(const basic_presence &other) diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index b3d06ebad..aa80bab4c 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -9,6 +9,7 @@ # include +# include namespace boost { @@ -26,31 +27,30 @@ class basic_stanza typedef typename base_type::string_type string_type; + explicit basic_stanza(const string_type &name) { + + } + void set_name(const string_type &name) { - name_ = name; + element_.set_name(name); } - string_type name() const { - return name_; + string_type get_name() const { + return element_.get_name(); } void set_attribute(const string_type &key, const string_type &value) { - this->headers().insert(std::make_pair(key, value)); + element_.set_attribute(key, value); } - string_type attribute(const string_type &key) const { - typename headers_range >::type range - = this->headers().equal_range(key); - if (boost::begin(range) == boost::end(range)) { - return string_type(); - } - - return boost::begin(range)->second; + string_type get_attribute(const string_type &key) const { + boost::optional attr = element_.get_attribute(key); + return attr? *attr : string_type(); } private: - string_type name_; + detail::basic_element element_; }; diff --git a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp b/libs/network/test/xmpp/expat_stanza_parser_tests.cpp deleted file mode 100644 index cf9dafe92..000000000 --- a/libs/network/test/xmpp/expat_stanza_parser_tests.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include -#include - - -using namespace boost::network::xmpp; -using boost::network::xmpp::message; -using boost::network::xmpp::presence; -using boost::network::xmpp::iq; - - -basic_expat_stanza_parser stanza_parser; - - -namespace { -struct xml_document_fixture { - xml_document_fixture() { - stanza_parser.feed(""); - } - - ~xml_document_fixture() { - stanza_parser.feed(""); - } -}; -} // namespace - - -BOOST_GLOBAL_FIXTURE(xml_document_fixture); - - -BOOST_AUTO_TEST_CASE(parse_message_test) { - message instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("message", instance.name()); - BOOST_CHECK_EQUAL("foo", instance.attribute("to")); -} - - -BOOST_AUTO_TEST_CASE(parse_presence_test) { - presence instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("presence", instance.name()); -} - - -BOOST_AUTO_TEST_CASE(parse_iq_test) { - iq instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("iq", instance.name()); - BOOST_CHECK_EQUAL("bar", instance.attribute("to")); -} diff --git a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp b/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp deleted file mode 100644 index f2242df34..000000000 --- a/libs/network/test/xmpp/libxml2_stanza_parser_tests.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - - -#define BOOST_TEST_MODULE XMPP XML parsers -#include -#include -#include -#include -#include - - -using namespace boost::network::xmpp; -using boost::network::xmpp::message; -using boost::network::xmpp::presence; -using boost::network::xmpp::iq; - - -basic_libxml2_stanza_parser stanza_parser; - - -namespace { -struct xml_document_fixture { - xml_document_fixture() { - stanza_parser.feed(""); - } - - ~xml_document_fixture() { - stanza_parser.feed(""); - } -}; -} // namespace - - -BOOST_GLOBAL_FIXTURE(xml_document_fixture); - - -BOOST_AUTO_TEST_CASE(parse_message_test) { - message instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("message", instance.name()); - BOOST_CHECK_EQUAL("foo", instance.attribute("to")); -} - - -BOOST_AUTO_TEST_CASE(parse_presence_test) { - presence instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("presence", instance.name()); -} - - -BOOST_AUTO_TEST_CASE(parse_iq_test) { - iq instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("iq", instance.name()); - BOOST_CHECK_EQUAL("bar", instance.attribute("to")); -} From f47a62d0f4bc56ca14bc509fa8c9489ed3658662 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Mon, 13 Sep 2010 23:14:59 +0200 Subject: [PATCH 011/438] Added first test for XMPP client. --- .../xml_wrappers/traits/parser_backend.hpp | 1 - boost/network/protocol/xmpp/client.hpp | 98 +++++++++++++------ .../protocol/xmpp/detail/stanza_parser.hpp | 59 +++++++++++ boost/network/protocol/xmpp/iq.hpp | 3 +- boost/network/protocol/xmpp/message.hpp | 3 +- boost/network/protocol/xmpp/presence.hpp | 3 +- boost/network/protocol/xmpp/stanza.hpp | 10 +- libs/network/test/CMakeLists.txt | 38 ++++--- .../expat_element_parser_tests.cpp | 1 - libs/network/test/xmpp/xmpp_client_tests.cpp | 37 +++++++ libs/network/test/xmpp/xmpp_message_tests.cpp | 14 +-- .../network/test/xmpp/xmpp_presence_tests.cpp | 1 + libs/network/test/xmpp/xmpp_stanza_tests.cpp | 54 ++++++++++ 13 files changed, 265 insertions(+), 57 deletions(-) create mode 100644 boost/network/protocol/xmpp/detail/stanza_parser.hpp create mode 100644 libs/network/test/xmpp/xmpp_client_tests.cpp create mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp diff --git a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp index c33f5440b..b2e1baad2 100644 --- a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp +++ b/boost/network/detail/xml_wrappers/traits/parser_backend.hpp @@ -9,7 +9,6 @@ # include -# include namespace boost { diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index b099b3627..892bc4a1e 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -8,22 +8,30 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_CLIENT_INC__ -# include +# include # include # include +# include # include # include # include +# include +# include namespace boost { namespace network { namespace xmpp { template < - class Handler, - class Tag + class Tag, + class Handler > class basic_client : boost::noncopyable { + +private: + + typedef basic_client this_type; + public: typedef typename string::type string_type; @@ -32,7 +40,7 @@ class basic_client : boost::noncopyable { typedef basic_presence presence_type; typedef basic_iq iq_type; - explicit basic_client(Handler handler); + explicit basic_client(Handler &handler); ~basic_client(); @@ -50,28 +58,31 @@ class basic_client : boost::noncopyable { void send_iq(const iq_type &iq); - string_type jid() const; + void set_jid(const string_type &jid); + + string_type get_jid() const; private: - void handle_stream_start(); - void handle_stream_stanza(); - void handle_stream_end(); + void write_stanza(const basic_stanza &stanza); + void close_socket(); + + Handler &handler_; + + // io_service + boost::asio::io_service io_service_; // tcp socket + boost::asio::ip::tcp::socket socket_; + // tls // sasl // parameters, such as jid, domain, port etc. string_type jid_; - // io_service - boost::asio::io_service io_service_; - // xml parser - Handler handler_; - }; @@ -79,24 +90,27 @@ template < class Tag, class Handler > -basic_client::basic_client(Handler handler) { +basic_client::basic_client(Handler &handler) + : handler_(handler), socket_(io_service_) { // set the handlers } + template < class Tag, class Handler > -basic_client::~basic_client() { +basic_client::~basic_client() { } + template < class Tag, class Handler > -void basic_client::connect(const string_type &proxy_host, - const string_type &proxy_port) { +void basic_client::connect(const string_type &proxy_host, + const string_type &proxy_port) { // get the JID domain // default port is 52222 // open socket @@ -108,17 +122,19 @@ template < class Tag, class Handler > -void basic_client::disconnect() { +void basic_client::disconnect() { // close socket // signal connection handler + io_service_.post( + boost::bind(&this_type::close_socket, this)); } template < class Tag, class Handler > -void basic_client::authenticate(const string_type &jid, - const string_type &password) { +void basic_client::authenticate(const string_type &jid, + const string_type &password) { } @@ -126,42 +142,64 @@ template < class Tag, class Handler > -void basic_client::send_message(const message_type &message) { - +void basic_client::send_message(const message_type &message) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(message))); } template < class Tag, class Handler > -void basic_client::send_presence(const presence_type &presence) { - +void basic_client::send_presence(const presence_type &presence) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(presence))); } template < class Tag, class Handler > -void basic_client::send_iq(const iq_type &iq) { - +void basic_client::send_iq(const iq_type &iq) { + io_service_.post( + boost::bind(&this_type::write_stanza, this, boost::ref(iq))); } template < class Tag, class Handler > -basic_client::string_type -basic_client::jid() const { +typename basic_client::string_type +basic_client::get_jid() const { return jid_; } +template < + class Tag, + class Handler + > +void basic_client::write_stanza(const basic_stanza &stanza) { + +} + + +template < + class Tag, + class Handler + > +void basic_client::close_socket() { + socket_.close(); +} + + template < class Handler > -struct client : basic_client { +struct client : basic_client { - explicit client(Handler handler) : basic_client(handler) { + explicit client(Handler &handler) + : basic_client(handler) { } diff --git a/boost/network/protocol/xmpp/detail/stanza_parser.hpp b/boost/network/protocol/xmpp/detail/stanza_parser.hpp new file mode 100644 index 000000000..761c5ec65 --- /dev/null +++ b/boost/network/protocol/xmpp/detail/stanza_parser.hpp @@ -0,0 +1,59 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ + + +# include +# include +# include +# include + + + +namespace boost { +namespace network { +namespace xmpp { +namespace detail { +template < + class Tag + > +class basic_stanza_parser { +public: + + typedef basic_stanza stanza_type; + typedef typename string::type string_type; + typedef typename boost::network::detail::parser_backend::type parser_type; + + basic_stanza_parser() { + + } + + ~basic_stanza_parser() { + + } + + bool feed(const string_type &chunk) { + parser_.feed(chunk); + } + + bool feed(const string_type &chunk, stanza_type &stanza) { + parser_.feed(chunk, &stanza.element()); + } + +private: + + parser_type parser_; + +}; +} // namespace detail +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp index f6c55c819..c861aa8ce 100644 --- a/boost/network/protocol/xmpp/iq.hpp +++ b/boost/network/protocol/xmpp/iq.hpp @@ -29,7 +29,8 @@ class basic_iq typedef typename base_type::headers_container_type headers_container_type; basic_iq() { - set_name("iq"); + static const char name[] = {'i', 'q'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_iq(const basic_iq &other) diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp index 4d6b2a7dc..926453f13 100644 --- a/boost/network/protocol/xmpp/message.hpp +++ b/boost/network/protocol/xmpp/message.hpp @@ -29,7 +29,8 @@ class basic_message typedef typename base_type::headers_container_type headers_container_type; basic_message() { - set_name("message"); + static const char name[] = {'m', 'e', 's', 's', 'a', 'g', 'e'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_message(const basic_message &other) diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp index 4c486b0d8..f18494b5d 100644 --- a/boost/network/protocol/xmpp/presence.hpp +++ b/boost/network/protocol/xmpp/presence.hpp @@ -29,7 +29,8 @@ class basic_presence typedef typename base_type::headers_container_type headers_container_type; basic_presence() { - set_name("presence"); + static const char name[] = {'p', 'r', 'e', 's', 'e', 'n', 'c', 'e'}; + base_type::set_name(string_type(name, name + sizeof(name))); } basic_presence(const basic_presence &other) diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index aa80bab4c..ca0aa793a 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -27,10 +27,14 @@ class basic_stanza typedef typename base_type::string_type string_type; - explicit basic_stanza(const string_type &name) { + explicit basic_stanza() { } + explicit basic_stanza(const string_type &name) { + element_.set_name(name); + } + void set_name(const string_type &name) { element_.set_name(name); } @@ -48,6 +52,10 @@ class basic_stanza return attr? *attr : string_type(); } + detail::basic_element &element() { + return element_; + } + private: detail::basic_element element_; diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 2bc3b70b4..d96b5b323 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -78,6 +78,20 @@ if (Boost_FOUND) set_target_properties(cpp-netlib-xml_element_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) + add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) + add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + set_target_properties(cpp-netlib-xmpp_message_tests + cpp-netlib-xmpp_presence_tests + cpp-netlib-xmpp_iq_tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) + add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) + add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) + add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) add_executable(cpp-netlib-expat_element_parser_tests xml_wrappers/expat_element_parser_tests.cpp) @@ -87,8 +101,18 @@ if (Boost_FOUND) # add_executable(cpp-netlib-expat_stanza_parser_tests xml_wrappers/expat_stanza_parser_tests.cpp) # target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) # add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) + + add_executable(cpp-netlib-xmpp_stanza_tests xmpp/xmpp_stanza_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_stanza_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-xmpp_stanza_tests ../../../build/tests/cpp-netlib-xmpp_stanza_tests) + add_executable(cpp-netlib-xmpp_client_tests xmpp/xmpp_client_tests.cpp) + target_link_libraries(cpp-netlib-xmpp_client_tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${EXPAT_LIBRARIES}) + add_test(cpp-netlib-xmpp_client_tests ../../../build/tests/cpp-netlib-xmpp_client_tests) + set_target_properties(cpp-netlib-expat_element_parser_tests + cpp-netlib-xmpp_stanza_tests + cpp-netlib-xmpp_client_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() @@ -105,18 +129,4 @@ if (Boost_FOUND) PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() - add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) - add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) - add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) - target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) - target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) - set_target_properties(cpp-netlib-xmpp_message_tests - cpp-netlib-xmpp_presence_tests - cpp-netlib-xmpp_iq_tests - PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) - add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) - add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) - add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) - endif() diff --git a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index e2a00bd51..856e15b48 100644 --- a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -4,7 +4,6 @@ // http://www.boost.org/LICENSE_1_0.txt) - #define BOOST_TEST_MODULE expat wrapper tests #include #include diff --git a/libs/network/test/xmpp/xmpp_client_tests.cpp b/libs/network/test/xmpp/xmpp_client_tests.cpp new file mode 100644 index 000000000..b6345facc --- /dev/null +++ b/libs/network/test/xmpp/xmpp_client_tests.cpp @@ -0,0 +1,37 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP client tests +#include +#include + + +namespace xmpp = boost::network::xmpp; +struct test_handler; +typedef xmpp::client client; + + +struct test_handler { + + void handle(const client::message_type &message) { + + } + + void handle(const client::presence_type &presence) { + + } + + void handle(const client::iq_type &iq) { + + } + +}; + + +BOOST_AUTO_TEST_CASE(test_client_connection) { + test_handler handler; + client instance(handler); +} diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp index 61c6811f7..a13b9b77c 100644 --- a/libs/network/test/xmpp/xmpp_message_tests.cpp +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -57,13 +57,13 @@ BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { } -// BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { -// message instance; -// instance << xmpp::type("chat"); -// BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); -// } -// -// +BOOST_AUTO_TEST_CASE(xmpp_message_type_directive_test) { + // xmpp::message instance; + // instance << xmpp::type("chat"); + // BOOST_CHECK_EQUAL("chat", xmpp::type(instance)); +} + + // BOOST_AUTO_TEST_CASE(xmpp_message_id_directive_test) { // message instance; // instance << xmpp::id("t2w4qax3"); diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp index 4d9428df4..f373cfe38 100644 --- a/libs/network/test/xmpp/xmpp_presence_tests.cpp +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -15,6 +15,7 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { xmpp::presence instance; instance << boost::network::source("source@example.com"); + BOOST_CHECK_EQUAL("presence", instance.get_name()); BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp new file mode 100644 index 000000000..d85c08ad0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -0,0 +1,54 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP stanza tests +#include +#include +#include +#include +#include +#include +#include +#include +// #include + + +namespace xmpp = boost::network::xmpp; + + +xmpp::detail::basic_stanza_parser stanza_parser; + + +namespace { +struct xml_document_fixture { + xml_document_fixture() { + stanza_parser.feed(""); + } + + ~xml_document_fixture() { + stanza_parser.feed(""); + } +}; +} // namespace + + +BOOST_GLOBAL_FIXTURE(xml_document_fixture); + + +BOOST_AUTO_TEST_CASE(parse_message_test) { + xmpp::message instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("message", instance.get_name()); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); +} + + +BOOST_AUTO_TEST_CASE(parse_presence_test) { + xmpp::presence instance; + stanza_parser.feed("", instance); + BOOST_CHECK_EQUAL("presence", instance.get_name()); + BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); +} From 3d3e578eb5abb8e873fba3c13dc4af72d95bdbdf Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Fri, 17 Sep 2010 23:45:38 +0200 Subject: [PATCH 012/438] Updates XMPP namespaces. --- boost/network/protocol/xmpp/client.hpp | 174 ++++++++++++++---- boost/network/protocol/xmpp/namespaces.hpp | 83 +++++++++ libs/network/test/CMakeLists.txt | 4 + libs/network/test/xmpp/xmpp_iq_tests.cpp | 1 + .../test/xmpp/xmpp_namespace_tests.cpp | 35 ++++ libs/network/test/xmpp/xmpp_stanza_tests.cpp | 2 +- 6 files changed, 261 insertions(+), 38 deletions(-) create mode 100644 boost/network/protocol/xmpp/namespaces.hpp create mode 100644 libs/network/test/xmpp/xmpp_namespace_tests.cpp diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 892bc4a1e..fbbcae83e 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -12,11 +12,14 @@ # include # include # include +# include # include # include # include # include +# include # include +# include namespace boost { @@ -24,13 +27,15 @@ namespace network { namespace xmpp { template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > class basic_client : boost::noncopyable { private: - typedef basic_client this_type; + typedef basic_client this_type; public: @@ -44,13 +49,14 @@ class basic_client : boost::noncopyable { ~basic_client(); - void connect(const string_type &proxy_host, - const string_type &proxy_port); + void set_lang(const string_type &lang); - void disconnect(); + void connect(const string_type &jid, + const string_type &password); + + void run(); - void authenticate(const string_type &jid, - const string_type &password); + void disconnect(); void send_message(const message_type &message); @@ -58,14 +64,15 @@ class basic_client : boost::noncopyable { void send_iq(const iq_type &iq); - void set_jid(const string_type &jid); - string_type get_jid() const; private: - void write_stanza(const basic_stanza &stanza); - void close_socket(); + void handle_connect(const boost::system::error_code &error, + boost::asio::ip::tcp::resolver::iterator iterator); + void handle_write_stanza(const basic_stanza &stanza); + void handle_read_stanza(const boost::system::error_code &ec); + void handle_disconnect(); Handler &handler_; @@ -83,123 +90,216 @@ class basic_client : boost::noncopyable { // xml parser + // std::deque stanza_queue_; + }; template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -basic_client::basic_client(Handler &handler) +basic_client::basic_client(Handler &handler) : handler_(handler), socket_(io_service_) { - // set the handlers + } template < class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +basic_client::~basic_client() { + +} + +template < + class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -basic_client::~basic_client() { +void basic_client::set_lang(const string_type &lang) { } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::connect(const string_type &proxy_host, - const string_type &proxy_port) { +void basic_client::connect(const string_type &jid, + const string_type &password) { + using boost::asio::ip::tcp; + // get the JID domain - // default port is 52222 + // default port is 5222 // open socket // socket has a state // signal connection handler + + jid_ = jid; + + string_type host = "127.0.0.1"; + string_type port = "5222"; + + tcp::resolver resolver(io_service_); + tcp::resolver::query query(host, port); + tcp::resolver::iterator iterator = resolver.resolve(query); + socket_.async_connect(&this_type::handle_connect, + this, + boost::asio::placeholders::error, + iterator); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::disconnect() { - // close socket - // signal connection handler - io_service_.post( - boost::bind(&this_type::close_socket, this)); +void basic_client::run() { + io_service_.run(); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::authenticate(const string_type &jid, - const string_type &password) { - +void basic_client::disconnect() { + io_service_.post( + boost::bind(&this_type::handle_disconnect, this)); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_message(const message_type &message) { +void basic_client::send_message(const message_type &message) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(message))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(message))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_presence(const presence_type &presence) { +void basic_client::send_presence(const presence_type &presence) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(presence))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(presence))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::send_iq(const iq_type &iq) { +void basic_client::send_iq(const iq_type &iq) { io_service_.post( - boost::bind(&this_type::write_stanza, this, boost::ref(iq))); + boost::bind(&this_type::handle_write_stanza, this, boost::ref(iq))); } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -typename basic_client::string_type -basic_client::get_jid() const { +typename basic_client::string_type +basic_client::get_jid() const { return jid_; } +template < + class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +void basic_client::handle_connect( + const boost::system::error_code& ec, + boost::asio::ip::tcp::resolver::iterator iterator) { + if (!ec) { + + // open stream + // TODO: where does "lang" come from? + string_type s = + "" + ""; // xmpp_ns_Streams + + // boost::asio::async_read( + // socket_, + // boost::asio::buffer(read_msg_.data(), chat_message::header_length), + // boost::bind(&chat_client::handle_read_header, this, + // boost::asio::placeholders::error)); + } + else if (iterator != boost::asio::ip::tcp::resolver::iterator()) { + socket_.close(); + boost::asio::ip::tcp::endpoint endpoint = *iterator; + socket_.async_connect( + endpoint, + boost::bind(&this_type::handle_connect, + this, + boost::asio::placeholders::error, + ++iterator)); + } + else { + // unable to connect + } +} template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::write_stanza(const basic_stanza &stanza) { - +void basic_client::handle_write_stanza(const basic_stanza &stanza) { + // stanza ==> string + // socket_.async_write(socket_, + // boost::asio::buffer(stanza.string()), + // boost::bind(&this_type::handle_write...)) } template < class Tag, + unsigned version_major, + unsigned version_minor, class Handler > -void basic_client::close_socket() { +void basic_client::handle_disconnect() { + // close stream + string_type s = ""; socket_.close(); + // handler_.disconnected(); } template < class Handler > -struct client : basic_client { +struct client : basic_client { explicit client(Handler &handler) - : basic_client(handler) { + : basic_client(handler) { } diff --git a/boost/network/protocol/xmpp/namespaces.hpp b/boost/network/protocol/xmpp/namespaces.hpp new file mode 100644 index 000000000..75bfeb5e7 --- /dev/null +++ b/boost/network/protocol/xmpp/namespaces.hpp @@ -0,0 +1,83 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +namespace ns { +template < + class Tag + > +inline +typename string::type client() { + static const char client[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'l', 'i', 'e', 'n', 't'}; + return typename string::type( + client, client + sizeof(client)); +} + +template < + class Tag + > +inline +typename string::type server() { + static const char server[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 's', 'e', 'r', 'v', 'e', 'r'}; + return typename string::type( + server, server + sizeof(server)); +} + +template < + class Tag + > +inline +typename string::type component() { + static const char component[] = { + 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'o', 'm', 'p', 'o', + 'n', 'e', 'n', 't', ':', 'a', 'c', 'c', 'e', 'p', 't'}; + return typename string::type( + component, component + sizeof(component)); +} + +template < + class Tag + > +inline +typename string::type streams() { + static const char streams[] = { + 'h', 't', 't', 'p', ':', '/', '/', 'e', 't', 'h', 'e', 'r', + 'x', '.', 'j', 'a', 'b', 'b', 'e', 'r', '.', 'o', 'r', 'g', + '/', 's', 't', 'r', 'e', 'a', 'm', 's'}; + return typename string::type( + streams, streams + sizeof(streams)); +} + +template < + class Tag + > +inline +typename string::type streams_ietf() { + static const char streams_ietf[] = { + 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', + 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', + 'm', 'p', 'p', '-', 's', 't', 'r', 'e', 'a', 'm', 's'}; + return typename string::type( + streams_ietf, streams_ietf + sizeof(streams_ietf)); +} +} // namespace ns +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_NAMESPACES_INC__ diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index d96b5b323..aba260592 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -81,16 +81,20 @@ if (Boost_FOUND) add_executable(cpp-netlib-xmpp_message_tests xmpp/xmpp_message_tests.cpp) add_executable(cpp-netlib-xmpp_presence_tests xmpp/xmpp_presence_tests.cpp) add_executable(cpp-netlib-xmpp_iq_tests xmpp/xmpp_iq_tests.cpp) + add_executable(cpp-netlib-xmpp_namespace_tests xmpp/xmpp_namespace_tests.cpp) target_link_libraries(cpp-netlib-xmpp_message_tests ${Boost_LIBRARIES}) target_link_libraries(cpp-netlib-xmpp_presence_tests ${Boost_LIBRARIES}) target_link_libraries(cpp-netlib-xmpp_iq_tests ${Boost_LIBRARIES}) + target_link_libraries(cpp-netlib-xmpp_namespace_tests ${Boost_LIBRARIES}) set_target_properties(cpp-netlib-xmpp_message_tests cpp-netlib-xmpp_presence_tests cpp-netlib-xmpp_iq_tests + cpp-netlib-xmpp_namespace_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) add_test(cpp-netlib-xmpp_message_tests ../../../build/tests/cpp-netlib-xmpp_message_tests) add_test(cpp-netlib-xmpp_presence_tests ../../../build/tests/cpp-netlib-xmpp_presence_tests) add_test(cpp-netlib-xmpp_iq_tests ../../../build/tests/cpp-netlib-xmpp_iq_tests) + add_test(cpp-netlib-xmpp_namespace_tests ../../../build/tests/cpp-netlib-xmpp_namespace_tests) if (EXPAT_FOUND) include_directories( ${EXPAT_INCLUDE_DIRS} ) diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index e2f527d87..ad14bb726 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -7,6 +7,7 @@ #define BOOST_TEST_MODULE XMPP iq tests #include #include +#include namespace xmpp = boost::network::xmpp; diff --git a/libs/network/test/xmpp/xmpp_namespace_tests.cpp b/libs/network/test/xmpp/xmpp_namespace_tests.cpp new file mode 100644 index 000000000..5bb82c3f0 --- /dev/null +++ b/libs/network/test/xmpp/xmpp_namespace_tests.cpp @@ -0,0 +1,35 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE XMPP namespace tests +#include +#include +#include +#include +#include + + +namespace xmpp = boost::network::xmpp; + + +typedef boost::mpl::list< + boost::network::tags::default_string, + boost::network::tags::default_wstring + > tag_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_namespaces, T, tag_types) { + BOOST_CHECK(boost::equal(std::string("jabber:client"), + xmpp::ns::client())); + BOOST_CHECK(boost::equal(std::string("jabber:server"), + xmpp::ns::server())); + BOOST_CHECK(boost::equal(std::string("jabber:component:accept"), + xmpp::ns::component())); + BOOST_CHECK(boost::equal(std::string("http://etherx.jabber.org/streams"), + xmpp::ns::streams())); + BOOST_CHECK(boost::equal(std::string("urn:ietf:params:xml:ns:xmpp-streams"), + xmpp::ns::streams_ietf())); +} diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp index d85c08ad0..2c85f65cb 100644 --- a/libs/network/test/xmpp/xmpp_stanza_tests.cpp +++ b/libs/network/test/xmpp/xmpp_stanza_tests.cpp @@ -13,7 +13,7 @@ #include #include #include -// #include +#include namespace xmpp = boost::network::xmpp; From 18da44f2c5e642817e16100e13bceb422fce8ac6 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 26 Sep 2010 10:25:34 +0200 Subject: [PATCH 013/438] Updated failing XML parser tests. --- boost/network/auth/sasl.hpp | 10 +- .../parser_backends/expat/element_parser.hpp | 65 ++++--- .../parser_backends/expat/stanza_parser.hpp | 124 ------------- .../libxml2/element_parser.hpp | 48 +++-- .../parser_backends/libxml2/stanza_parser.hpp | 127 ------------- boost/network/protocol/xmpp/client.hpp | 170 +++++++++++++++--- boost/network/protocol/xmpp/error.hpp | 37 ++++ boost/network/protocol/xmpp/namespaces.hpp | 24 +++ .../expat_element_parser_tests.cpp | 30 +++- .../libxml2_element_parser_tests.cpp | 30 +++- libs/network/test/xmpp/xmpp_client_tests.cpp | 12 +- libs/network/test/xmpp/xmpp_iq_tests.cpp | 2 +- .../test/xmpp/xmpp_namespace_tests.cpp | 4 + 13 files changed, 351 insertions(+), 332 deletions(-) delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp create mode 100644 boost/network/protocol/xmpp/error.hpp diff --git a/boost/network/auth/sasl.hpp b/boost/network/auth/sasl.hpp index dfcc8cd26..8f85bab6c 100644 --- a/boost/network/auth/sasl.hpp +++ b/boost/network/auth/sasl.hpp @@ -19,11 +19,17 @@ template < > class basic_sasl { + struct anonymous {}; + struct plain {}; + struct digest_md5 {}; + public: - // basic_sasl(PLAIN); + explicit basic_sasl(anonymous); + + explicit basic_sasl(plain); - // basic_sasl(DIGEST); + explicit basic_sasl(digest_md5); }; } // namespace auth diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp index e73b3e536..5255c244e 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp @@ -10,8 +10,10 @@ # include # include +# include # include # include +# include namespace boost { @@ -20,19 +22,16 @@ namespace detail { template < class Tag > -class basic_expat_element_parser { +class basic_expat_element_parser : boost::noncopyable { public: typedef typename string::type string_type; typedef basic_element element_type; - basic_expat_element_parser() { - parser_ = XML_ParserCreate(NULL); - // handle the case where the parser is NULL - element_ = 0; - depth_ = 0; - + basic_expat_element_parser() + : parser_(XML_ParserCreate(NULL)), depth_(0) { + assert(parser_); XML_SetUserData(parser_, this); XML_SetElementHandler(parser_, start_element, end_element); XML_SetCharacterDataHandler(parser_, cdata); @@ -41,13 +40,22 @@ class basic_expat_element_parser { ~basic_expat_element_parser() { XML_ParserFree(parser_); } - + bool feed(const string_type &chunk) { - return feed(chunk, 0); + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(0); + depth_ = 0; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; } - bool feed(const string_type &chunk, element_type *element) { - element_ = element; + bool feed(const string_type &chunk, element_type &element) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(&element); + depth_ = 0; return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; } @@ -80,18 +88,19 @@ class basic_expat_element_parser { const XML_Char **attrs) { basic_expat_element_parser *parser = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->element_, name); - set_attributes(parser->element_, attrs); + + if (!parser->elements_.top()) { + return; } - else if (parser->depth_ > 1) { + + if (parser->depth_ > 0) { element_type *child = new element_type; - set_name(child, name); - set_attributes(child, attrs); - parser->element_->add_child(child); + parser->elements_.top()->add_child(child); + parser->elements_.push(child); } - + set_name(parser->elements_.top(), name); + set_attributes(parser->elements_.top(), attrs); + ++parser->depth_; } @@ -99,6 +108,14 @@ class basic_expat_element_parser { const XML_Char *name) { basic_expat_element_parser *parser = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + if (parser->depth_ > 0) { + parser->elements_.pop(); + } --parser->depth_; } @@ -108,13 +125,17 @@ class basic_expat_element_parser { int len) { basic_expat_element_parser *parser = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } - parser->element_->add_child( + parser->elements_.top()->add_child( new element_type(typename element_type::text(), string_type(s, s + len))); } XML_Parser parser_; - element_type *element_; + std::stack elements_; int depth_; }; diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp deleted file mode 100644 index 127d2cca7..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_expat_stanza_parser { -public: - - typedef typename string::type string_type; - - typedef basic_stanza stanza_type; - - basic_expat_stanza_parser() { - parser_ = XML_ParserCreate(NULL); - // handle the case where the parser is NULL - stanza_ = 0; - depth_ = 0; - - XML_SetUserData(parser_, this); - XML_SetElementHandler(parser_, start_element, end_element); - XML_SetCharacterDataHandler(parser_, cdata); - } - - ~basic_expat_stanza_parser() { - XML_ParserFree(parser_); - } - - bool feed(const string_type &chunk) { - stanza_ = 0; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - - bool feed(const string_type &chunk, stanza_type &stanza) { - stanza_ = &stanza; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - -private: - - static void set_name(stanza_type *stanza, const XML_Char *name) { - const XML_Char *name_begin = name; - const XML_Char *name_end = name_begin + std::strlen(name_begin); - - stanza->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(stanza_type *stanza, const XML_Char **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const XML_Char *key_begin = attrs[i]; - const XML_Char *key_end = key_begin + std::strlen(key_begin); - - const XML_Char *val_begin = attrs[i + 1]; - const XML_Char *val_end = val_begin + std::strlen(val_begin); - - stanza->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const XML_Char *name, - const XML_Char **attrs) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->stanza_, name); - set_attributes(parser->stanza_, attrs); - } - else if (parser->depth_ > 1) { - // element_type *child = new element_type; - // set_name(child, name); - // set_attributes(child, attrs); - // parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const XML_Char *name) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void cdata(void *userdata, - const XML_Char *s, - int len) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - } - - XML_Parser parser_; - stanza_type *stanza_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp index 74494bab4..5c3835e1d 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { @@ -34,7 +35,6 @@ class basic_libxml2_element_parser { handlers_.endElement = end_element; handlers_.characters = characters; depth_ = 0; - element_ = 0; context_ = xmlCreatePushParserCtxt(&handlers_, this, 0, 0, 0); @@ -46,11 +46,20 @@ class basic_libxml2_element_parser { } bool feed(const string_type &chunk) { - return feed(chunk, 0); + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(0); + depth_ = 0; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); } - bool feed(const string_type &chunk, element_type *element) { - element_ = element; + bool feed(const string_type &chunk, element_type &element) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(&element); + depth_ = 0; return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); } @@ -83,16 +92,17 @@ class basic_libxml2_element_parser { basic_libxml2_element_parser *parser = static_cast *>(userdata); - if (parser->depth_ == 1) { - set_name(parser->element_, name); - set_attributes(parser->element_, attrs); + if (!parser->elements_.top()) { + return; } - else if (parser->depth_ > 1) { + + else if (parser->depth_ > 0) { element_type *child = new element_type; - set_name(child, name); - set_attributes(child, attrs); - parser->element_->add_child(child); + parser->elements_.top()->add_child(child); + parser->elements_.push(child); } + set_name(parser->elements_.top(), name); + set_attributes(parser->elements_.top(), attrs); ++parser->depth_; } @@ -101,6 +111,14 @@ class basic_libxml2_element_parser { const xmlChar *name) { basic_libxml2_element_parser *parser = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + if (parser->depth_ > 0) { + parser->elements_.pop(); + } --parser->depth_; } @@ -110,14 +128,18 @@ class basic_libxml2_element_parser { int len) { basic_libxml2_element_parser *parser = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } - parser->element_->add_child( + parser->elements_.top()->add_child( new element_type(typename element_type::text(), string_type(s, s + len))); } xmlParserCtxtPtr context_; xmlSAXHandler handlers_; - element_type *element_; + std::stack elements_; int depth_; }; diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp deleted file mode 100644 index fc9d6e8e3..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_libxml2_stanza_parser { - -public: - - typedef typename string::type string_type; - - typedef basic_stanza stanza_type; - - basic_libxml2_stanza_parser() { - std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); - handlers_.startElement = start_element; - handlers_.endElement = end_element; - handlers_.characters = characters; - depth_ = 0; - stanza_ = 0; - - context_ = xmlCreatePushParserCtxt(&handlers_, - this, 0, 0, 0); - // assert(!context_); - } - - ~basic_libxml2_stanza_parser() { - xmlFreeParserCtxt(context_); - } - - bool feed(const string_type &chunk) { - stanza_ = 0; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - - bool feed(const string_type &chunk, stanza_type &stanza) { - stanza_ = &stanza; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - -private: - - static void set_name(stanza_type *stanza, const xmlChar *name) { - const xmlChar *name_begin = name; - const xmlChar *name_end = name_begin + xmlStrlen(name_begin); - stanza->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(basic_stanza *stanza, const xmlChar **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const xmlChar *key_begin = attrs[i]; - const xmlChar *key_end = key_begin + xmlStrlen(key_begin); - - const xmlChar *val_begin = attrs[i + 1]; - const xmlChar *val_end = val_begin + xmlStrlen(val_begin); - - stanza->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const xmlChar *name, - const xmlChar **attrs) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->stanza_, name); - set_attributes(parser->stanza_, attrs); - } - else if (parser->depth_ > 1) { - // element_type *child = new element_type; - // set_name(child, name); - // set_attributes(child, attrs); - // parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const xmlChar *name) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void characters(void *userdata, - const xmlChar *s, - int len) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - } - - xmlParserCtxtPtr context_; - xmlSAXHandler handlers_; - stanza_type *stanza_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index fbbcae83e..3cb74766e 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -16,12 +16,23 @@ # include # include # include +# include +# include +# include +# include +# include # include # include # include +# include +# include +# include # include +# include + + namespace boost { namespace network { namespace xmpp { @@ -36,6 +47,7 @@ class basic_client : boost::noncopyable { private: typedef basic_client this_type; + typedef typename detail::parser_backend::type parser_type; public: @@ -44,6 +56,7 @@ class basic_client : boost::noncopyable { typedef basic_message message_type; typedef basic_presence presence_type; typedef basic_iq iq_type; + typedef basic_error error_type; explicit basic_client(Handler &handler); @@ -70,14 +83,18 @@ class basic_client : boost::noncopyable { void handle_connect(const boost::system::error_code &error, boost::asio::ip::tcp::resolver::iterator iterator); - void handle_write_stanza(const basic_stanza &stanza); - void handle_read_stanza(const boost::system::error_code &ec); + void handle_write_open_stream(const boost::system::error_code &ec); + void handle_read_open_stream(const boost::system::error_code &ec); + void handle_read_starttls(const boost::system::error_code &ec); + void handle_write_starttls(const boost::system::error_code &ec); + // void handle_read_stanza(const boost::system::error_code &ec); void handle_disconnect(); Handler &handler_; // io_service boost::asio::io_service io_service_; + boost::asio::io_service::work work_; // tcp socket boost::asio::ip::tcp::socket socket_; @@ -89,8 +106,10 @@ class basic_client : boost::noncopyable { string_type jid_; // xml parser + parser_type parser_; // std::deque stanza_queue_; + std::string write_buffer_, read_buffer_; }; @@ -102,7 +121,7 @@ template < class Handler > basic_client::basic_client(Handler &handler) - : handler_(handler), socket_(io_service_) { + : handler_(handler), socket_(io_service_), work_(io_service_) { } @@ -147,15 +166,17 @@ void basic_client::connect(const str jid_ = jid; string_type host = "127.0.0.1"; - string_type port = "5222"; + string_type port = "5221"; tcp::resolver resolver(io_service_); tcp::resolver::query query(host, port); tcp::resolver::iterator iterator = resolver.resolve(query); - socket_.async_connect(&this_type::handle_connect, - this, - boost::asio::placeholders::error, - iterator); + socket_.async_connect( + *iterator, + boost::bind(&this_type::handle_connect, + this, + boost::asio::placeholders::error, + iterator)); } template < @@ -233,22 +254,17 @@ void basic_client::handle_connect( const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator iterator) { if (!ec) { - - // open stream - // TODO: where does "lang" come from? - string_type s = - "" - ""; // xmpp_ns_Streams - - // boost::asio::async_read( - // socket_, - // boost::asio::buffer(read_msg_.data(), chat_message::header_length), - // boost::bind(&chat_client::handle_read_header, this, - // boost::asio::placeholders::error)); + write_buffer_ = + "" + ""; + std::cout << "(C) " << write_buffer_ << std::endl; + boost::asio::async_write( + socket_, boost::asio::buffer(write_buffer_), + boost::bind(&this_type::handle_write_open_stream, this, + boost::asio::placeholders::error)); } else if (iterator != boost::asio::ip::tcp::resolver::iterator()) { socket_.close(); @@ -271,11 +287,107 @@ template < unsigned version_minor, class Handler > -void basic_client::handle_write_stanza(const basic_stanza &stanza) { - // stanza ==> string - // socket_.async_write(socket_, - // boost::asio::buffer(stanza.string()), - // boost::bind(&this_type::handle_write...)) +void basic_client::handle_write_open_stream(const boost::system::error_code &ec) { + if (!ec) { + read_buffer_.resize(512); + boost::fill(read_buffer_, 0); + socket_.read_some(boost::asio::buffer(read_buffer_)); + std::cout << "(S) " << read_buffer_ << std::endl; + + boost::fill(read_buffer_, 0); + socket_.read_some(boost::asio::buffer(read_buffer_)); + std::cout << "(S) " << read_buffer_ << std::endl; + detail::basic_element element; + parser_.feed(read_buffer_, &element); + std::cout << "(S->) " << element << std::endl; + + write_buffer_ = + ""; + boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), + boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); + std::cout << "(C) " << write_buffer_ << std::endl; + + + // boost::asio::async_read(socket_, boost::asio::buffer((char *)read_buffer_.data(), read_buffer_.size()), + // boost::bind(&this_type::handle_read_open_stream, this, + // boost::asio::placeholders::error)); + } +} + +template < + class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +void basic_client::handle_read_open_stream(const boost::system::error_code &ec) { + if (!ec) { + std::cout << "(S) " << read_buffer_ << std::endl; + read_buffer_.resize(512); + boost::fill(read_buffer_, 0); + boost::asio::async_read(socket_, boost::asio::buffer((char *)read_buffer_.data(), read_buffer_.size()), + boost::bind(&this_type::handle_read_starttls, this, + boost::asio::placeholders::error)); + } +} + +template < + class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +void basic_client::handle_read_starttls(const boost::system::error_code &ec) { + if (!ec) { + std::cout << "(S) " << read_buffer_ << std::endl; + write_buffer_ = + ""; + boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), + boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); + std::cout << "(C) " << write_buffer_ << std::endl; + } +} + +template < + class Tag, + unsigned version_major, + unsigned version_minor, + class Handler + > +void basic_client::handle_write_starttls(const boost::system::error_code &ec) { + if (!ec) { + // std::string auth = + // ""; + // std::cout << auth << std::endl; + // bytes_written = boost::asio::write(socket_, boost::asio::buffer(auth)); + // std::cout << "There were " << bytes_written << " bytes written." << std::endl; + + // boost::fill(s_, 0); + // bytes_read = socket_.read_some(boost::asio::buffer(s_)); + // std::cout << "There were " << bytes_read << " bytes read." << std::endl; + // std::cout << "(S) " << s_ << std::endl; + + // string_type es = ""; + // std::cout << es << std::endl; + // bytes_written = boost::asio::write(socket_, boost::asio::buffer(es)); + // std::cout << "There were " << bytes_written << " bytes written." << std::endl; + // + // s_.resize(512); + // boost::fill(s_, 0); + // bytes_read = socket_.read_some(boost::asio::buffer(s_)); + // std::cout << "There were " << bytes_read << " bytes read." << std::endl; + // std::cout << "(S) " << s_ << std::endl; + + + // std::string es = + // ""; + // std::cout << es << std::endl; + // bytes_written = boost::asio::write(socket_, boost::asio::buffer(es)); + // std::cout << "There were " << bytes_written << " bytes written." << std::endl; + } } diff --git a/boost/network/protocol/xmpp/error.hpp b/boost/network/protocol/xmpp/error.hpp new file mode 100644 index 000000000..138903d45 --- /dev/null +++ b/boost/network/protocol/xmpp/error.hpp @@ -0,0 +1,37 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_ERROR_INC__ +# define __BOOST_NETWORK_PROTOCOL_XMPP_ERROR_INC__ + + +# include + + +namespace boost { +namespace network { +namespace xmpp { +template < + class Tag + > +class basic_error + : public basic_stanza { +public: + + basic_error() { + + } + +}; + + +typedef basic_error error; +} // namespace xmpp +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_PROTOCOL_XMPP_ERROR_INC__ diff --git a/boost/network/protocol/xmpp/namespaces.hpp b/boost/network/protocol/xmpp/namespaces.hpp index 75bfeb5e7..cea1a231f 100644 --- a/boost/network/protocol/xmpp/namespaces.hpp +++ b/boost/network/protocol/xmpp/namespaces.hpp @@ -74,6 +74,30 @@ typename string::type streams_ietf() { return typename string::type( streams_ietf, streams_ietf + sizeof(streams_ietf)); } + +template < + class Tag + > +inline +typename string::type tls() { + static const char tls[] = { + 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', + 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', + 'm', 'p', 'p', '-', 't', 'l', 's'}; + return typename string::type(tls, tls + sizeof(tls)); +} + +template < + class Tag + > +inline +typename string::type sasl() { + static const char sasl[] = { + 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', + 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', + 'm', 'p', 'p', '-', 's', 'a', 's', 'l'}; + return typename string::type(sasl, sasl + sizeof(sasl)); +} } // namespace ns } // namespace xmpp } // namespace network diff --git a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index 856e15b48..19ad07a48 100644 --- a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using namespace boost::network::detail; @@ -20,12 +21,13 @@ basic_expat_element_parser element_parser; namespace { struct xml_document_fixture { xml_document_fixture() { - element_parser.feed(""); + element_parser.feed(""); } ~xml_document_fixture() { - element_parser.feed(""); + element_parser.feed(""); } + }; } // namespace @@ -35,7 +37,7 @@ BOOST_GLOBAL_FIXTURE(xml_document_fixture); BOOST_AUTO_TEST_CASE(parse_message_test) { element instance; - element_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("message", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); @@ -50,7 +52,7 @@ BOOST_AUTO_TEST_CASE(parse_message_test) { BOOST_AUTO_TEST_CASE(parse_presence_test) { element instance; - element_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("presence", instance.get_name()); boost::iterator_range children @@ -63,7 +65,7 @@ BOOST_AUTO_TEST_CASE(parse_presence_test) { BOOST_AUTO_TEST_CASE(parse_iq_test) { element instance; - element_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("iq", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); @@ -74,3 +76,21 @@ BOOST_AUTO_TEST_CASE(parse_iq_test) { boost::end(children)), 1); BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); } + + +BOOST_AUTO_TEST_CASE(parse_tls) { + element instance; + element_parser.feed( + "" + "" + "DIGEST-MD5PLAIN" + "" + "" + "", instance); + BOOST_CHECK_EQUAL("stream:features", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 3); +} diff --git a/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp index 47889b3cb..f42261128 100644 --- a/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp @@ -15,17 +15,17 @@ using namespace boost::network::detail; using boost::network::detail::element; -basic_libxml2_parser libxml2_parser; +basic_libxml2_parser element_parser; namespace { struct xml_document_fixture { xml_document_fixture() { - libxml2_parser.feed(""); + element_parser.feed(""); } ~xml_document_fixture() { - libxml2_parser.feed(""); + element_parser.feed(""); } }; } // namespace @@ -36,7 +36,7 @@ BOOST_GLOBAL_FIXTURE(xml_document_fixture); BOOST_AUTO_TEST_CASE(parse_message_test) { element instance; - libxml2_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("message", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(parse_message_test) { BOOST_AUTO_TEST_CASE(parse_presence_test) { element instance; - libxml2_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("presence", instance.get_name()); boost::iterator_range children @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(parse_presence_test) { BOOST_AUTO_TEST_CASE(parse_iq_test) { element instance; - libxml2_parser.feed("", &instance); + element_parser.feed("", instance); BOOST_CHECK_EQUAL("iq", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); @@ -75,3 +75,21 @@ BOOST_AUTO_TEST_CASE(parse_iq_test) { boost::end(children)), 1); BOOST_CHECK_EQUAL("query", (*boost::begin(children))->get_name()); } + + +BOOST_AUTO_TEST_CASE(parse_tls) { + element instance; + element_parser.feed( + "" + "" + "DIGEST-MD5PLAIN" + "" + "" + "", instance); + BOOST_CHECK_EQUAL("stream:features", instance.get_name()); + + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 3); +} diff --git a/libs/network/test/xmpp/xmpp_client_tests.cpp b/libs/network/test/xmpp/xmpp_client_tests.cpp index b6345facc..bf89434d7 100644 --- a/libs/network/test/xmpp/xmpp_client_tests.cpp +++ b/libs/network/test/xmpp/xmpp_client_tests.cpp @@ -16,15 +16,19 @@ typedef xmpp::client client; struct test_handler { - void handle(const client::message_type &message) { + void operator () (const client::message_type &message) { } - void handle(const client::presence_type &presence) { + void operator () (const client::presence_type &presence) { } - void handle(const client::iq_type &iq) { + void operator () (const client::iq_type &iq) { + + } + + void operator () (const client::error_type &error) { } @@ -34,4 +38,6 @@ struct test_handler { BOOST_AUTO_TEST_CASE(test_client_connection) { test_handler handler; client instance(handler); + instance.connect("glyn@lola", "xxx"); + instance.run(); } diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index ad14bb726..d8c7de0ab 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -16,7 +16,7 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { xmpp::iq instance; instance << boost::network::source("source@example.com"); - BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); + BOOST_CHECK_EQUAL("source@example.com", boost::network::source((instance))); } diff --git a/libs/network/test/xmpp/xmpp_namespace_tests.cpp b/libs/network/test/xmpp/xmpp_namespace_tests.cpp index 5bb82c3f0..140a4899a 100644 --- a/libs/network/test/xmpp/xmpp_namespace_tests.cpp +++ b/libs/network/test/xmpp/xmpp_namespace_tests.cpp @@ -32,4 +32,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_namespaces, T, tag_types) { xmpp::ns::streams())); BOOST_CHECK(boost::equal(std::string("urn:ietf:params:xml:ns:xmpp-streams"), xmpp::ns::streams_ietf())); + BOOST_CHECK(boost::equal(std::string("urn:ietf:params:xml:ns:xmpp-tls"), + xmpp::ns::tls())); + BOOST_CHECK(boost::equal(std::string("urn:ietf:params:xml:ns:xmpp-sasl"), + xmpp::ns::sasl())); } From 7240a2d387af3748e0ebd17c3b7ef22bfaa2c2da Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 26 Sep 2010 21:13:33 +0200 Subject: [PATCH 014/438] Update client, but there are still bugs in the XML parser... --- boost/network/detail/xml_wrappers/element.hpp | 18 ++- .../detail/xml_wrappers/element_io.hpp | 25 +-- .../parser_backends/expat/element_parser.hpp | 147 ----------------- .../parser_backends/expat_parser.hpp | 124 +++++++++++++- .../libxml2/element_parser.hpp | 151 ------------------ .../parser_backends/libxml2_parser.hpp | 128 ++++++++++++++- boost/network/protocol/xmpp.hpp | 8 + boost/network/protocol/xmpp/client.hpp | 147 ++++++++--------- libs/network/test/CMakeLists.txt | 12 -- .../expat_element_parser_tests.cpp | 58 +++++-- libs/network/test/xmpp/xmpp_iq_tests.cpp | 8 +- libs/network/test/xmpp/xmpp_message_tests.cpp | 30 ++-- .../network/test/xmpp/xmpp_presence_tests.cpp | 10 +- libs/network/test/xmpp/xmpp_stanza_tests.cpp | 54 ------- 14 files changed, 424 insertions(+), 496 deletions(-) delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp delete mode 100644 libs/network/test/xmpp/xmpp_stanza_tests.cpp diff --git a/boost/network/detail/xml_wrappers/element.hpp b/boost/network/detail/xml_wrappers/element.hpp index 9300c59b3..c1df42b7f 100644 --- a/boost/network/detail/xml_wrappers/element.hpp +++ b/boost/network/detail/xml_wrappers/element.hpp @@ -131,7 +131,12 @@ class basic_element { } boost::optional get_lang() const { - return get_attribute("xml:lang"); + boost::optional lang + = get_attribute("xml:lang"); + if (!lang) { + lang = get_attribute("lang"); + } + return lang; } boost::optional get_id() const { @@ -144,6 +149,17 @@ class basic_element { children_.push_back(shared_element); } + boost::optional &> get_child(const string_type &name) const { + for (typename element_children_type::const_iterator it = children_.begin(); + it != children_.end(); + ++it) { + if ((*it)->get_name() == name) { + return **it; + } + } + return boost::none; + } + boost::iterator_range get_children() const { return boost::make_iterator_range(boost::begin(children_), diff --git a/boost/network/detail/xml_wrappers/element_io.hpp b/boost/network/detail/xml_wrappers/element_io.hpp index 9590cec00..abf515e82 100644 --- a/boost/network/detail/xml_wrappers/element_io.hpp +++ b/boost/network/detail/xml_wrappers/element_io.hpp @@ -9,6 +9,8 @@ # include +# include +# include # include @@ -20,25 +22,24 @@ template < > std::ostream &operator << (std::ostream &os, const basic_element &element) { + typedef typename basic_element::headers_container_type::const_iterator header_iterator; + typedef typename basic_element::element_children_type::const_iterator children_iterator; + typedef boost::iterator_range header_range; + typedef boost::iterator_range children_range; + if (element.is_tag()) { os << "<" << element.get_name(); - boost::iterator_range::headers_container_type::const_iterator> - attributes(element.get_attributes()); - - typename basic_element::headers_container_type::const_iterator - attr_it(boost::begin(attributes)), - attr_end(boost::end(attributes)); + header_range attributes(element.get_attributes()); + + header_iterator attr_it(boost::begin(attributes)), attr_end(boost::end(attributes)); for (; attr_it != attr_end; ++attr_it) { - os << " " << attr_it->first << "=\"" << attr_it->second << "\""; + os << " " << attr_it->first << "='" << attr_it->second << "'"; } os << ">"; - boost::iterator_range::element_children_type::const_iterator> - children(element.get_children()); + children_range children(element.get_children()); - typename basic_element::element_children_type::const_iterator - child_it(boost::begin(children)), - child_end(boost::end(children)); + children_iterator child_it(boost::begin(children)), child_end(boost::end(children)); for (; child_it != child_end; ++child_it) { os << **child_it; } diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp deleted file mode 100644 index 5255c244e..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ - - -# include -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_expat_element_parser : boost::noncopyable { -public: - - typedef typename string::type string_type; - - typedef basic_element element_type; - - basic_expat_element_parser() - : parser_(XML_ParserCreate(NULL)), depth_(0) { - assert(parser_); - XML_SetUserData(parser_, this); - XML_SetElementHandler(parser_, start_element, end_element); - XML_SetCharacterDataHandler(parser_, cdata); - } - - ~basic_expat_element_parser() { - XML_ParserFree(parser_); - } - - bool feed(const string_type &chunk) { - while (!elements_.empty()) { - elements_.pop(); - } - elements_.push(0); - depth_ = 0; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - - bool feed(const string_type &chunk, element_type &element) { - while (!elements_.empty()) { - elements_.pop(); - } - elements_.push(&element); - depth_ = 0; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - -private: - - static void set_name(element_type *element, const XML_Char *name) { - const XML_Char *name_begin = name; - const XML_Char *name_end = name_begin + std::strlen(name_begin); - - element->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(element_type *element, const XML_Char **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const XML_Char *key_begin = attrs[i]; - const XML_Char *key_end = key_begin + std::strlen(key_begin); - - const XML_Char *val_begin = attrs[i + 1]; - const XML_Char *val_end = val_begin + std::strlen(val_begin); - - element->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const XML_Char *name, - const XML_Char **attrs) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - if (parser->depth_ > 0) { - element_type *child = new element_type; - parser->elements_.top()->add_child(child); - parser->elements_.push(child); - } - set_name(parser->elements_.top(), name); - set_attributes(parser->elements_.top(), attrs); - - ++parser->depth_; - } - - static void end_element(void *userdata, - const XML_Char *name) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - if (parser->depth_ > 0) { - parser->elements_.pop(); - } - - --parser->depth_; - } - - static void cdata(void *userdata, - const XML_Char *s, - int len) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - parser->elements_.top()->add_child( - new element_type(typename element_type::text(), string_type(s, s + len))); - } - - XML_Parser parser_; - std::stack elements_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp index c569f1281..2a3af43ef 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp @@ -8,7 +8,12 @@ # define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# include +# include +# include +# include +# include +# include +# include namespace boost { @@ -17,11 +22,122 @@ namespace detail { template < class Tag > -class basic_expat_parser - : public basic_expat_element_parser { - +class basic_expat_parser : boost::noncopyable { public: + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_expat_parser() + : parser_(XML_ParserCreate(NULL)), depth_(0) { + assert(parser_); + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, start_element, end_element); + XML_SetCharacterDataHandler(parser_, cdata); + } + + ~basic_expat_parser() { + XML_ParserFree(parser_); + } + + bool feed(const string_type &chunk) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(0); + depth_ = 0; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + + bool feed(const string_type &chunk, element_type &element) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(&element); + depth_ = 0; + return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; + } + +private: + + static void set_name(element_type *element, const XML_Char *name) { + const XML_Char *name_begin = name; + const XML_Char *name_end = name_begin + std::strlen(name_begin); + + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(element_type *element, const XML_Char **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const XML_Char *key_begin = attrs[i]; + const XML_Char *key_end = key_begin + std::strlen(key_begin); + + const XML_Char *val_begin = attrs[i + 1]; + const XML_Char *val_end = val_begin + std::strlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const XML_Char *name, + const XML_Char **attrs) { + basic_expat_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + if (parser->depth_ > 0) { + element_type *child = new element_type; + parser->elements_.top()->add_child(child); + parser->elements_.push(child); + } + set_name(parser->elements_.top(), name); + set_attributes(parser->elements_.top(), attrs); + + ++parser->depth_; + } + + static void end_element(void *userdata, + const XML_Char *name) { + basic_expat_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + if (parser->depth_ > 0) { + parser->elements_.pop(); + } + + --parser->depth_; + } + + static void cdata(void *userdata, + const XML_Char *s, + int len) { + basic_expat_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + parser->elements_.top()->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + XML_Parser parser_; + std::stack elements_; + int depth_; + }; } // namespace detail } // namespace network diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp deleted file mode 100644 index 5c3835e1d..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ - - -# include -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_libxml2_element_parser { - -public: - - typedef typename string::type string_type; - - typedef basic_element element_type; - - basic_libxml2_element_parser() { - std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); - handlers_.startElement = start_element; - handlers_.endElement = end_element; - handlers_.characters = characters; - depth_ = 0; - - context_ = xmlCreatePushParserCtxt(&handlers_, - this, 0, 0, 0); - // assert(!context_); - } - - ~basic_libxml2_element_parser() { - xmlFreeParserCtxt(context_); - } - - bool feed(const string_type &chunk) { - while (!elements_.empty()) { - elements_.pop(); - } - elements_.push(0); - depth_ = 0; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - - bool feed(const string_type &chunk, element_type &element) { - while (!elements_.empty()) { - elements_.pop(); - } - elements_.push(&element); - depth_ = 0; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - -private: - - static void set_name(element_type *element, const xmlChar *name) { - const xmlChar *name_begin = name; - const xmlChar *name_end = name_begin + xmlStrlen(name_begin); - element->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(basic_element *element, const xmlChar **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const xmlChar *key_begin = attrs[i]; - const xmlChar *key_end = key_begin + xmlStrlen(key_begin); - - const xmlChar *val_begin = attrs[i + 1]; - const xmlChar *val_end = val_begin + xmlStrlen(val_begin); - - element->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const xmlChar *name, - const xmlChar **attrs) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - else if (parser->depth_ > 0) { - element_type *child = new element_type; - parser->elements_.top()->add_child(child); - parser->elements_.push(child); - } - set_name(parser->elements_.top(), name); - set_attributes(parser->elements_.top(), attrs); - - ++parser->depth_; - } - - static void end_element(void *userdata, - const xmlChar *name) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - if (parser->depth_ > 0) { - parser->elements_.pop(); - } - - --parser->depth_; - } - - static void characters(void *userdata, - const xmlChar *s, - int len) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - if (!parser->elements_.top()) { - return; - } - - parser->elements_.top()->add_child( - new element_type(typename element_type::text(), string_type(s, s + len))); - } - - xmlParserCtxtPtr context_; - xmlSAXHandler handlers_; - std::stack elements_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp index b49c49091..127330691 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp +++ b/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp @@ -8,7 +8,11 @@ # define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# include +# include +# include +# include +# include +# include namespace boost { @@ -17,11 +21,127 @@ namespace detail { template < class Tag > -class basic_libxml2_parser - : public basic_libxml2_element_parser { - +class basic_libxml2_parser { + public: + typedef typename string::type string_type; + + typedef basic_element element_type; + + basic_libxml2_parser() { + std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); + handlers_.startElement = start_element; + handlers_.endElement = end_element; + handlers_.characters = characters; + depth_ = 0; + + context_ = xmlCreatePushParserCtxt(&handlers_, + this, 0, 0, 0); + // assert(!context_); + } + + ~basic_libxml2_parser() { + xmlFreeParserCtxt(context_); + } + + bool feed(const string_type &chunk) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(0); + depth_ = 0; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + + bool feed(const string_type &chunk, element_type &element) { + while (!elements_.empty()) { + elements_.pop(); + } + elements_.push(&element); + depth_ = 0; + return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); + } + +private: + + static void set_name(element_type *element, const xmlChar *name) { + const xmlChar *name_begin = name; + const xmlChar *name_end = name_begin + xmlStrlen(name_begin); + element->set_name(string_type(name_begin, name_end)); + } + + static void set_attributes(basic_element *element, const xmlChar **attrs) { + if (attrs) { + for (int i = 0; attrs[i]; i += 2) { + const xmlChar *key_begin = attrs[i]; + const xmlChar *key_end = key_begin + xmlStrlen(key_begin); + + const xmlChar *val_begin = attrs[i + 1]; + const xmlChar *val_end = val_begin + xmlStrlen(val_begin); + + element->set_attribute(string_type(key_begin, key_end), + string_type(val_begin, val_end)); + } + } + } + + static void start_element(void *userdata, + const xmlChar *name, + const xmlChar **attrs) { + basic_libxml2_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + else if (parser->depth_ > 0) { + element_type *child = new element_type; + parser->elements_.top()->add_child(child); + parser->elements_.push(child); + } + set_name(parser->elements_.top(), name); + set_attributes(parser->elements_.top(), attrs); + + ++parser->depth_; + } + + static void end_element(void *userdata, + const xmlChar *name) { + basic_libxml2_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + if (parser->depth_ > 0) { + parser->elements_.pop(); + } + + --parser->depth_; + } + + static void characters(void *userdata, + const xmlChar *s, + int len) { + basic_libxml2_parser *parser + = static_cast *>(userdata); + + if (!parser->elements_.top()) { + return; + } + + parser->elements_.top()->add_child( + new element_type(typename element_type::text(), string_type(s, s + len))); + } + + xmlParserCtxtPtr context_; + xmlSAXHandler handlers_; + std::stack elements_; + int depth_; + }; } // namespace detail } // namespace network diff --git a/boost/network/protocol/xmpp.hpp b/boost/network/protocol/xmpp.hpp index 39bd5a4c1..9b1d57c96 100644 --- a/boost/network/protocol/xmpp.hpp +++ b/boost/network/protocol/xmpp.hpp @@ -8,6 +8,14 @@ # define __BOOST_NETWORK_PROTOCOL_XMPP_INC__ +# include +# include +# include +# include +# include +# include +# include #endif // __BOOST_NETWORK_PROTOCOL_XMPP_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 3cb74766e..8c6c31e63 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -17,6 +17,7 @@ # include # include # include +# include # include # include # include @@ -28,8 +29,10 @@ # include # include # include +# include +# include # include @@ -48,7 +51,7 @@ class basic_client : boost::noncopyable { typedef basic_client this_type; typedef typename detail::parser_backend::type parser_type; - + public: typedef typename string::type string_type; @@ -87,7 +90,6 @@ class basic_client : boost::noncopyable { void handle_read_open_stream(const boost::system::error_code &ec); void handle_read_starttls(const boost::system::error_code &ec); void handle_write_starttls(const boost::system::error_code &ec); - // void handle_read_stanza(const boost::system::error_code &ec); void handle_disconnect(); Handler &handler_; @@ -207,8 +209,7 @@ template < class Handler > void basic_client::send_message(const message_type &message) { - io_service_.post( - boost::bind(&this_type::handle_write_stanza, this, boost::ref(message))); + } template < @@ -218,8 +219,7 @@ template < class Handler > void basic_client::send_presence(const presence_type &presence) { - io_service_.post( - boost::bind(&this_type::handle_write_stanza, this, boost::ref(presence))); + } template < @@ -229,8 +229,7 @@ template < class Handler > void basic_client::send_iq(const iq_type &iq) { - io_service_.post( - boost::bind(&this_type::handle_write_stanza, this, boost::ref(iq))); + } template < @@ -254,13 +253,14 @@ void basic_client::handle_connect( const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator iterator) { if (!ec) { - write_buffer_ = - "" - ""; - std::cout << "(C) " << write_buffer_ << std::endl; + std::ostringstream os; + os << + "" << + "() << "\" " << + "xmlns:stream=\"" << ns::streams() << "\">"; + write_buffer_ = os.str(); boost::asio::async_write( socket_, boost::asio::buffer(write_buffer_), boost::bind(&this_type::handle_write_open_stream, this, @@ -292,25 +292,58 @@ void basic_client::handle_write_open read_buffer_.resize(512); boost::fill(read_buffer_, 0); socket_.read_some(boost::asio::buffer(read_buffer_)); - std::cout << "(S) " << read_buffer_ << std::endl; + { + detail::basic_element element; + parser_.feed(read_buffer_, element); + std::cout << element << std::endl; + if (boost::optional &> features = + element.get_child("stream:features")) { + std::cout << "stream:features" << std::endl; + // might get starttls in here + if (boost::optional &> starttls = + features.get().get_child("starttls")) { + std::cout << "starttls" << std::endl; + write_buffer_ = + ""; + std::cout << "(C) " << write_buffer_ << std::endl; + boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), + boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); + return; + } + } + } + + read_buffer_.resize(512); boost::fill(read_buffer_, 0); socket_.read_some(boost::asio::buffer(read_buffer_)); - std::cout << "(S) " << read_buffer_ << std::endl; - detail::basic_element element; - parser_.feed(read_buffer_, &element); - std::cout << "(S->) " << element << std::endl; - write_buffer_ = - ""; - boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), - boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); - std::cout << "(C) " << write_buffer_ << std::endl; - - - // boost::asio::async_read(socket_, boost::asio::buffer((char *)read_buffer_.data(), read_buffer_.size()), - // boost::bind(&this_type::handle_read_open_stream, this, - // boost::asio::placeholders::error)); + { + detail::basic_element element; + parser_.feed(read_buffer_, element); + std::cout << "(S) " << read_buffer_ << std::endl; + if (element.get_name() == "stream:features") { + std::cout << "stream:features" << std::endl; + if (boost::optional &> starttls = + element.get_child("starttls")) { + std::cout << "starttls" << std::endl; + write_buffer_ = + ""; + boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), + boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); + std::cout << "(C) " << write_buffer_ << std::endl; + } + else { + std::cout << "no starttls" << std::endl; + } + } + else { + std::cout << "no stream:features" << std::endl; + } + } + + // detail::basic_element element; + // parser_.feed(read_buffer_, element); } } @@ -321,14 +354,7 @@ template < class Handler > void basic_client::handle_read_open_stream(const boost::system::error_code &ec) { - if (!ec) { - std::cout << "(S) " << read_buffer_ << std::endl; - read_buffer_.resize(512); - boost::fill(read_buffer_, 0); - boost::asio::async_read(socket_, boost::asio::buffer((char *)read_buffer_.data(), read_buffer_.size()), - boost::bind(&this_type::handle_read_starttls, this, - boost::asio::placeholders::error)); - } + } template < @@ -338,14 +364,7 @@ template < class Handler > void basic_client::handle_read_starttls(const boost::system::error_code &ec) { - if (!ec) { - std::cout << "(S) " << read_buffer_ << std::endl; - write_buffer_ = - ""; - boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), - boost::bind(&this_type::handle_write_starttls, this, boost::asio::placeholders::error)); - std::cout << "(C) " << write_buffer_ << std::endl; - } + } template < @@ -356,41 +375,13 @@ template < > void basic_client::handle_write_starttls(const boost::system::error_code &ec) { if (!ec) { - // std::string auth = - // ""; - // std::cout << auth << std::endl; - // bytes_written = boost::asio::write(socket_, boost::asio::buffer(auth)); - // std::cout << "There were " << bytes_written << " bytes written." << std::endl; - - // boost::fill(s_, 0); - // bytes_read = socket_.read_some(boost::asio::buffer(s_)); - // std::cout << "There were " << bytes_read << " bytes read." << std::endl; - // std::cout << "(S) " << s_ << std::endl; - - // string_type es = ""; - // std::cout << es << std::endl; - // bytes_written = boost::asio::write(socket_, boost::asio::buffer(es)); - // std::cout << "There were " << bytes_written << " bytes written." << std::endl; - // - // s_.resize(512); - // boost::fill(s_, 0); - // bytes_read = socket_.read_some(boost::asio::buffer(s_)); - // std::cout << "There were " << bytes_read << " bytes read." << std::endl; - // std::cout << "(S) " << s_ << std::endl; - - - // std::string es = - // ""; - // std::cout << es << std::endl; - // bytes_written = boost::asio::write(socket_, boost::asio::buffer(es)); - // std::cout << "There were " << bytes_written << " bytes written." << std::endl; + std::cout << "Bananas" << std::endl; + read_buffer_.resize(512); + boost::fill(read_buffer_, 0); + socket_.read_some(boost::asio::buffer(read_buffer_)); } } - template < class Tag, unsigned version_major, diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index aba260592..cf6fd7bd9 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -102,20 +102,11 @@ if (Boost_FOUND) target_link_libraries(cpp-netlib-expat_element_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) add_test(cpp-netlib-expat_element_parser_tests ../../../build/tests/cpp-netlib-expat_element_parser_tests) - # add_executable(cpp-netlib-expat_stanza_parser_tests xml_wrappers/expat_stanza_parser_tests.cpp) - # target_link_libraries(cpp-netlib-expat_stanza_parser_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) - # add_test(cpp-netlib-expat_stanza_parser_tests ../../../build/tests/cpp-netlib-expat_stanza_parser_tests) - - add_executable(cpp-netlib-xmpp_stanza_tests xmpp/xmpp_stanza_tests.cpp) - target_link_libraries(cpp-netlib-xmpp_stanza_tests ${Boost_LIBRARIES} ${EXPAT_LIBRARIES}) - add_test(cpp-netlib-xmpp_stanza_tests ../../../build/tests/cpp-netlib-xmpp_stanza_tests) - add_executable(cpp-netlib-xmpp_client_tests xmpp/xmpp_client_tests.cpp) target_link_libraries(cpp-netlib-xmpp_client_tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${EXPAT_LIBRARIES}) add_test(cpp-netlib-xmpp_client_tests ../../../build/tests/cpp-netlib-xmpp_client_tests) set_target_properties(cpp-netlib-expat_element_parser_tests - cpp-netlib-xmpp_stanza_tests cpp-netlib-xmpp_client_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() @@ -126,9 +117,6 @@ if (Boost_FOUND) target_link_libraries(cpp-netlib-libxml2_element_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) add_test(cpp-netlib-libxml2_element_parser_tests ../../../build/tests/cpp-netlib-libxml2_element_parser_tests) - # add_executable(cpp-netlib-libxml2_stanza_parser_tests xml_wrappers/libxml2_stanza_parser_tests.cpp) - # target_link_libraries(cpp-netlib-libxml2_stanza_parser_tests ${Boost_LIBRARIES} ${LIBXML2_LIBRARIES}) - # add_test(cpp-netlib-libxml2_stanza_parser_tests ../../../build/tests/cpp-netlib-libxml2_stanza_parser_tests) set_target_properties(cpp-netlib-libxml2_element_parser_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests) endif() diff --git a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index 19ad07a48..7e690cab9 100644 --- a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -6,38 +6,45 @@ #define BOOST_TEST_MODULE expat wrapper tests #include -#include +#include #include #include +#include +#include using namespace boost::network::detail; using boost::network::detail::element; -basic_expat_element_parser element_parser; +basic_expat_parser *element_parser; namespace { struct xml_document_fixture { xml_document_fixture() { - element_parser.feed(""); + element_parser = new basic_expat_parser< + boost::network::tags::default_>; + element_parser->feed(""); } ~xml_document_fixture() { - element_parser.feed(""); + element_parser->feed(""); + delete element_parser; } }; } // namespace -BOOST_GLOBAL_FIXTURE(xml_document_fixture); +// BOOST_GLOBAL_FIXTURE(xml_document_fixture); +BOOST_FIXTURE_TEST_SUITE(expat_parser_test_suite, xml_document_fixture) + BOOST_AUTO_TEST_CASE(parse_message_test) { element instance; - element_parser.feed("", instance); + element_parser->feed("", instance); BOOST_CHECK_EQUAL("message", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("foo", instance.get_attribute("to").get()); @@ -52,7 +59,7 @@ BOOST_AUTO_TEST_CASE(parse_message_test) { BOOST_AUTO_TEST_CASE(parse_presence_test) { element instance; - element_parser.feed("", instance); + element_parser->feed("", instance); BOOST_CHECK_EQUAL("presence", instance.get_name()); boost::iterator_range children @@ -65,7 +72,7 @@ BOOST_AUTO_TEST_CASE(parse_presence_test) { BOOST_AUTO_TEST_CASE(parse_iq_test) { element instance; - element_parser.feed("", instance); + element_parser->feed("", instance); BOOST_CHECK_EQUAL("iq", instance.get_name()); BOOST_CHECK(instance.get_attribute("to")); BOOST_CHECK_EQUAL("bar", instance.get_attribute("to").get()); @@ -80,7 +87,7 @@ BOOST_AUTO_TEST_CASE(parse_iq_test) { BOOST_AUTO_TEST_CASE(parse_tls) { element instance; - element_parser.feed( + element_parser->feed( "" "" "DIGEST-MD5PLAIN" @@ -94,3 +101,36 @@ BOOST_AUTO_TEST_CASE(parse_tls) { BOOST_CHECK_EQUAL(std::distance(boost::begin(children), boost::end(children)), 3); } + + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_CASE(parse_multiple_elements) { + element_parser = + new basic_expat_parser; + element instance; + element_parser->feed( + "" + "" + "" + "" + "DIGEST-MD5PLAIN" + "" + "" + "", instance); + boost::iterator_range children + (instance.get_children()); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 1); + BOOST_CHECK_EQUAL((*boost::begin(children))->get_name(), + "stream:features"); + children = (*boost::begin(children))->get_children(); + BOOST_CHECK_EQUAL(std::distance(boost::begin(children), + boost::end(children)), 3); + + element_parser->feed(""); + delete element_parser; +} diff --git a/libs/network/test/xmpp/xmpp_iq_tests.cpp b/libs/network/test/xmpp/xmpp_iq_tests.cpp index d8c7de0ab..e5849f57c 100644 --- a/libs/network/test/xmpp/xmpp_iq_tests.cpp +++ b/libs/network/test/xmpp/xmpp_iq_tests.cpp @@ -15,13 +15,13 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_iq_source_directive_test) { xmpp::iq instance; - instance << boost::network::source("source@example.com"); - BOOST_CHECK_EQUAL("source@example.com", boost::network::source((instance))); + // instance << boost::network::source("source@example.com"); + // BOOST_CHECK_EQUAL("source@example.com", boost::network::source((instance))); } BOOST_AUTO_TEST_CASE(xmpp_iq_destination_directive_test) { xmpp::iq instance; - instance << boost::network::destination("dest@example.com"); - BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); + // instance << boost::network::destination("dest@example.com"); + // BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_message_tests.cpp b/libs/network/test/xmpp/xmpp_message_tests.cpp index a13b9b77c..728b4849e 100644 --- a/libs/network/test/xmpp/xmpp_message_tests.cpp +++ b/libs/network/test/xmpp/xmpp_message_tests.cpp @@ -14,46 +14,46 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_message_source_directive_test) { xmpp::message instance; - instance << boost::network::source("source@example.com"); - BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); + // instance << boost::network::source("source@example.com"); + // BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_destination_directive_test) { xmpp::message instance; - instance << boost::network::destination("dest@example.com"); - BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); + // instance << boost::network::destination("dest@example.com"); + // BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } BOOST_AUTO_TEST_CASE(xmpp_message_header_directive_test) { xmpp::message instance; - instance << boost::network::header("type", "chat"); - BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); - boost::network::headers_range::type range - = boost::network::headers(instance)["type"]; - BOOST_CHECK (boost::begin(range) != boost::end(range)); + // instance << boost::network::header("type", "chat"); + // BOOST_CHECK_EQUAL(1, boost::network::headers(instance).count("type")); + // boost::network::headers_range::type range + // = boost::network::headers(instance)["type"]; + // BOOST_CHECK (boost::begin(range) != boost::end(range)); } BOOST_AUTO_TEST_CASE(xmpp_message_body_directive_test) { xmpp::message instance; - instance << boost::network::header("type", "chat") - << boost::network::body("Hello world!"); + // instance << boost::network::header("type", "chat") + // << boost::network::body("Hello world!"); } BOOST_AUTO_TEST_CASE(xmpp_message_type_accessor_test) { xmpp::message instance; - instance.set_type("chat"); - BOOST_CHECK_EQUAL("chat", instance.type()); + // instance.set_type("chat"); + // BOOST_CHECK_EQUAL("chat", instance.type()); } BOOST_AUTO_TEST_CASE(xmpp_message_id_accessor_test) { xmpp::message instance; - instance.set_id("t2w4qax3"); - BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); + // instance.set_id("t2w4qax3"); + // BOOST_CHECK_EQUAL("t2w4qax3", instance.id()); } diff --git a/libs/network/test/xmpp/xmpp_presence_tests.cpp b/libs/network/test/xmpp/xmpp_presence_tests.cpp index f373cfe38..8f310f8be 100644 --- a/libs/network/test/xmpp/xmpp_presence_tests.cpp +++ b/libs/network/test/xmpp/xmpp_presence_tests.cpp @@ -14,14 +14,14 @@ namespace xmpp = boost::network::xmpp; BOOST_AUTO_TEST_CASE(xmpp_presence_source_directive_test) { xmpp::presence instance; - instance << boost::network::source("source@example.com"); - BOOST_CHECK_EQUAL("presence", instance.get_name()); - BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); + // instance << boost::network::source("source@example.com"); + // BOOST_CHECK_EQUAL("presence", instance.get_name()); + // BOOST_CHECK_EQUAL("source@example.com", boost::network::source(instance)); } BOOST_AUTO_TEST_CASE(xmpp_presence_destination_directive_test) { xmpp::presence instance; - instance << boost::network::destination("dest@example.com"); - BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); + // instance << boost::network::destination("dest@example.com"); + // BOOST_CHECK_EQUAL("dest@example.com", boost::network::destination(instance)); } diff --git a/libs/network/test/xmpp/xmpp_stanza_tests.cpp b/libs/network/test/xmpp/xmpp_stanza_tests.cpp deleted file mode 100644 index 2c85f65cb..000000000 --- a/libs/network/test/xmpp/xmpp_stanza_tests.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#define BOOST_TEST_MODULE XMPP stanza tests -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace xmpp = boost::network::xmpp; - - -xmpp::detail::basic_stanza_parser stanza_parser; - - -namespace { -struct xml_document_fixture { - xml_document_fixture() { - stanza_parser.feed(""); - } - - ~xml_document_fixture() { - stanza_parser.feed(""); - } -}; -} // namespace - - -BOOST_GLOBAL_FIXTURE(xml_document_fixture); - - -BOOST_AUTO_TEST_CASE(parse_message_test) { - xmpp::message instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("message", instance.get_name()); - BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); -} - - -BOOST_AUTO_TEST_CASE(parse_presence_test) { - xmpp::presence instance; - stanza_parser.feed("", instance); - BOOST_CHECK_EQUAL("presence", instance.get_name()); - BOOST_CHECK_EQUAL("foo", instance.get_attribute("to")); -} From d414e35c5143fce79e58ab9b713b5b0bf739071f Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Fri, 1 Oct 2010 23:31:45 +0200 Subject: [PATCH 015/438] Updated XML wrappers. --- boost/network/{tls/tls.hpp => auth/md5.hpp} | 16 +-- boost/network/auth/sasl.hpp | 20 ++- .../parser_backends/expat/element_parser.hpp | 126 ----------------- .../parser_backends/expat/stanza_parser.hpp | 124 ----------------- .../libxml2/element_parser.hpp | 129 ------------------ .../parser_backends/libxml2/stanza_parser.hpp | 127 ----------------- boost/network/protocol/xmpp/client.hpp | 8 +- .../protocol/xmpp/detail/stanza_parser.hpp | 59 -------- boost/network/protocol/xmpp/stanza.hpp | 2 +- boost/network/tls/gnutls.hpp | 54 ++++++++ boost/network/tls/openssl.hpp | 20 +++ .../{detail/xml_wrappers => xml}/element.hpp | 10 +- .../xml_wrappers => xml}/element_io.hpp | 10 +- .../parser_backends/expat_parser.hpp | 8 +- .../parser_backends/libxml2_parser.hpp | 8 +- .../traits/element_children.hpp | 6 +- .../traits/parser_backend.hpp | 6 +- libs/network/test/tls/test_gnutls.cpp | 14 ++ .../expat_element_parser_tests.cpp | 6 +- .../libxml2_element_parser_tests.cpp | 4 +- .../test/xml_wrappers/xml_element_tests.cpp | 4 +- 21 files changed, 142 insertions(+), 619 deletions(-) rename boost/network/{tls/tls.hpp => auth/md5.hpp} (60%) delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp delete mode 100644 boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp delete mode 100644 boost/network/protocol/xmpp/detail/stanza_parser.hpp create mode 100644 boost/network/tls/gnutls.hpp create mode 100644 boost/network/tls/openssl.hpp rename boost/network/{detail/xml_wrappers => xml}/element.hpp (93%) rename boost/network/{detail/xml_wrappers => xml}/element_io.hpp (82%) rename boost/network/{detail/xml_wrappers => xml}/parser_backends/expat_parser.hpp (93%) rename boost/network/{detail/xml_wrappers => xml}/parser_backends/libxml2_parser.hpp (93%) rename boost/network/{detail/xml_wrappers => xml}/traits/element_children.hpp (76%) rename boost/network/{detail/xml_wrappers => xml}/traits/parser_backend.hpp (74%) create mode 100644 libs/network/test/tls/test_gnutls.cpp diff --git a/boost/network/tls/tls.hpp b/boost/network/auth/md5.hpp similarity index 60% rename from boost/network/tls/tls.hpp rename to boost/network/auth/md5.hpp index ed7edc4e2..4c2756801 100644 --- a/boost/network/tls/tls.hpp +++ b/boost/network/auth/md5.hpp @@ -4,23 +4,17 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_TLS_TLS_INC__ -# define __BOOST_NETWORK_TLS_TLS_INC__ +#ifndef __BOOST_NETWORK_AUTH_MD5_INC__ +# define __BOOST_NETWORK_AUTH_MD5_INC__ namespace boost { namespace network { -class tls { -public: +namespace auth { - // credentials - // start - // read - // write - -}; +} // namespace auth } // namespace network } // namespace boost -#endif // __BOOST_NETWORK_TLS_TLS_INC__ +#endif // __BOOST_NETWORK_AUTH_MD5_INC__ diff --git a/boost/network/auth/sasl.hpp b/boost/network/auth/sasl.hpp index 8f85bab6c..08f90ed07 100644 --- a/boost/network/auth/sasl.hpp +++ b/boost/network/auth/sasl.hpp @@ -19,17 +19,25 @@ template < > class basic_sasl { - struct anonymous {}; - struct plain {}; - struct digest_md5 {}; + // struct anonymous {}; + // struct plain {}; + // struct digest_md5 {}; public: - explicit basic_sasl(anonymous); + typedef typename string::type string_type; - explicit basic_sasl(plain); + // explicit basic_sasl(anonymous); + // + // explicit basic_sasl(plain, + // const string_type &id, const string_type &password); + // + // explicit basic_sasl(digest_md5, + // const string_type &challenge,const string_type &jid, const string_type &password); - explicit basic_sasl(digest_md5); +private: + + string_type auth_string_; }; } // namespace auth diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp deleted file mode 100644 index e73b3e536..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/expat/element_parser.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_expat_element_parser { -public: - - typedef typename string::type string_type; - - typedef basic_element element_type; - - basic_expat_element_parser() { - parser_ = XML_ParserCreate(NULL); - // handle the case where the parser is NULL - element_ = 0; - depth_ = 0; - - XML_SetUserData(parser_, this); - XML_SetElementHandler(parser_, start_element, end_element); - XML_SetCharacterDataHandler(parser_, cdata); - } - - ~basic_expat_element_parser() { - XML_ParserFree(parser_); - } - - bool feed(const string_type &chunk) { - return feed(chunk, 0); - } - - bool feed(const string_type &chunk, element_type *element) { - element_ = element; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - -private: - - static void set_name(element_type *element, const XML_Char *name) { - const XML_Char *name_begin = name; - const XML_Char *name_end = name_begin + std::strlen(name_begin); - - element->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(element_type *element, const XML_Char **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const XML_Char *key_begin = attrs[i]; - const XML_Char *key_end = key_begin + std::strlen(key_begin); - - const XML_Char *val_begin = attrs[i + 1]; - const XML_Char *val_end = val_begin + std::strlen(val_begin); - - element->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const XML_Char *name, - const XML_Char **attrs) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->element_, name); - set_attributes(parser->element_, attrs); - } - else if (parser->depth_ > 1) { - element_type *child = new element_type; - set_name(child, name); - set_attributes(child, attrs); - parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const XML_Char *name) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void cdata(void *userdata, - const XML_Char *s, - int len) { - basic_expat_element_parser *parser - = static_cast *>(userdata); - - parser->element_->add_child( - new element_type(typename element_type::text(), string_type(s, s + len))); - } - - XML_Parser parser_; - element_type *element_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp deleted file mode 100644 index 127d2cca7..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/expat/stanza_parser.hpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_expat_stanza_parser { -public: - - typedef typename string::type string_type; - - typedef basic_stanza stanza_type; - - basic_expat_stanza_parser() { - parser_ = XML_ParserCreate(NULL); - // handle the case where the parser is NULL - stanza_ = 0; - depth_ = 0; - - XML_SetUserData(parser_, this); - XML_SetElementHandler(parser_, start_element, end_element); - XML_SetCharacterDataHandler(parser_, cdata); - } - - ~basic_expat_stanza_parser() { - XML_ParserFree(parser_); - } - - bool feed(const string_type &chunk) { - stanza_ = 0; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - - bool feed(const string_type &chunk, stanza_type &stanza) { - stanza_ = &stanza; - return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; - } - -private: - - static void set_name(stanza_type *stanza, const XML_Char *name) { - const XML_Char *name_begin = name; - const XML_Char *name_end = name_begin + std::strlen(name_begin); - - stanza->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(stanza_type *stanza, const XML_Char **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const XML_Char *key_begin = attrs[i]; - const XML_Char *key_end = key_begin + std::strlen(key_begin); - - const XML_Char *val_begin = attrs[i + 1]; - const XML_Char *val_end = val_begin + std::strlen(val_begin); - - stanza->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const XML_Char *name, - const XML_Char **attrs) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->stanza_, name); - set_attributes(parser->stanza_, attrs); - } - else if (parser->depth_ > 1) { - // element_type *child = new element_type; - // set_name(child, name); - // set_attributes(child, attrs); - // parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const XML_Char *name) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void cdata(void *userdata, - const XML_Char *s, - int len) { - basic_expat_stanza_parser *parser - = static_cast *>(userdata); - } - - XML_Parser parser_; - stanza_type *stanza_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp deleted file mode 100644 index 74494bab4..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2/element_parser.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_libxml2_element_parser { - -public: - - typedef typename string::type string_type; - - typedef basic_element element_type; - - basic_libxml2_element_parser() { - std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); - handlers_.startElement = start_element; - handlers_.endElement = end_element; - handlers_.characters = characters; - depth_ = 0; - element_ = 0; - - context_ = xmlCreatePushParserCtxt(&handlers_, - this, 0, 0, 0); - // assert(!context_); - } - - ~basic_libxml2_element_parser() { - xmlFreeParserCtxt(context_); - } - - bool feed(const string_type &chunk) { - return feed(chunk, 0); - } - - bool feed(const string_type &chunk, element_type *element) { - element_ = element; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - -private: - - static void set_name(element_type *element, const xmlChar *name) { - const xmlChar *name_begin = name; - const xmlChar *name_end = name_begin + xmlStrlen(name_begin); - element->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(basic_element *element, const xmlChar **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const xmlChar *key_begin = attrs[i]; - const xmlChar *key_end = key_begin + xmlStrlen(key_begin); - - const xmlChar *val_begin = attrs[i + 1]; - const xmlChar *val_end = val_begin + xmlStrlen(val_begin); - - element->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const xmlChar *name, - const xmlChar **attrs) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->element_, name); - set_attributes(parser->element_, attrs); - } - else if (parser->depth_ > 1) { - element_type *child = new element_type; - set_name(child, name); - set_attributes(child, attrs); - parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const xmlChar *name) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void characters(void *userdata, - const xmlChar *s, - int len) { - basic_libxml2_element_parser *parser - = static_cast *>(userdata); - - parser->element_->add_child( - new element_type(typename element_type::text(), string_type(s, s + len))); - } - - xmlParserCtxtPtr context_; - xmlSAXHandler handlers_; - element_type *element_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp b/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp deleted file mode 100644 index fc9d6e8e3..000000000 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2/stanza_parser.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ - - -# include -# include -# include -# include - - -namespace boost { -namespace network { -namespace detail { -template < - class Tag - > -class basic_libxml2_stanza_parser { - -public: - - typedef typename string::type string_type; - - typedef basic_stanza stanza_type; - - basic_libxml2_stanza_parser() { - std::memset(&handlers_, 0, sizeof(xmlSAXHandler)); - handlers_.startElement = start_element; - handlers_.endElement = end_element; - handlers_.characters = characters; - depth_ = 0; - stanza_ = 0; - - context_ = xmlCreatePushParserCtxt(&handlers_, - this, 0, 0, 0); - // assert(!context_); - } - - ~basic_libxml2_stanza_parser() { - xmlFreeParserCtxt(context_); - } - - bool feed(const string_type &chunk) { - stanza_ = 0; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - - bool feed(const string_type &chunk, stanza_type &stanza) { - stanza_ = &stanza; - return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0); - } - -private: - - static void set_name(stanza_type *stanza, const xmlChar *name) { - const xmlChar *name_begin = name; - const xmlChar *name_end = name_begin + xmlStrlen(name_begin); - stanza->set_name(string_type(name_begin, name_end)); - } - - static void set_attributes(basic_stanza *stanza, const xmlChar **attrs) { - if (attrs) { - for (int i = 0; attrs[i]; i += 2) { - const xmlChar *key_begin = attrs[i]; - const xmlChar *key_end = key_begin + xmlStrlen(key_begin); - - const xmlChar *val_begin = attrs[i + 1]; - const xmlChar *val_end = val_begin + xmlStrlen(val_begin); - - stanza->set_attribute(string_type(key_begin, key_end), - string_type(val_begin, val_end)); - } - } - } - - static void start_element(void *userdata, - const xmlChar *name, - const xmlChar **attrs) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - - if (parser->depth_ == 1) { - set_name(parser->stanza_, name); - set_attributes(parser->stanza_, attrs); - } - else if (parser->depth_ > 1) { - // element_type *child = new element_type; - // set_name(child, name); - // set_attributes(child, attrs); - // parser->element_->add_child(child); - } - - ++parser->depth_; - } - - static void end_element(void *userdata, - const xmlChar *name) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - - --parser->depth_; - } - - static void characters(void *userdata, - const xmlChar *s, - int len) { - basic_libxml2_stanza_parser *parser - = static_cast *>(userdata); - } - - xmlParserCtxtPtr context_; - xmlSAXHandler handlers_; - stanza_type *stanza_; - int depth_; - -}; -} // namespace detail -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 8c6c31e63..8f846b67f 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -18,10 +18,10 @@ # include # include # include -# include -# include -# include -# include +# include +# include +# include +# include # include # include # include diff --git a/boost/network/protocol/xmpp/detail/stanza_parser.hpp b/boost/network/protocol/xmpp/detail/stanza_parser.hpp deleted file mode 100644 index 761c5ec65..000000000 --- a/boost/network/protocol/xmpp/detail/stanza_parser.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Glyn Matthews 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ -# define __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ - - -# include -# include -# include -# include - - - -namespace boost { -namespace network { -namespace xmpp { -namespace detail { -template < - class Tag - > -class basic_stanza_parser { -public: - - typedef basic_stanza stanza_type; - typedef typename string::type string_type; - typedef typename boost::network::detail::parser_backend::type parser_type; - - basic_stanza_parser() { - - } - - ~basic_stanza_parser() { - - } - - bool feed(const string_type &chunk) { - parser_.feed(chunk); - } - - bool feed(const string_type &chunk, stanza_type &stanza) { - parser_.feed(chunk, &stanza.element()); - } - -private: - - parser_type parser_; - -}; -} // namespace detail -} // namespace xmpp -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_PROTOCOL_XMPP_DETAIL_STANZA_PARSER_INC__ diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index ca0aa793a..4be13ef60 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -9,7 +9,7 @@ # include -# include +# include namespace boost { diff --git a/boost/network/tls/gnutls.hpp b/boost/network/tls/gnutls.hpp new file mode 100644 index 000000000..3a9c661ed --- /dev/null +++ b/boost/network/tls/gnutls.hpp @@ -0,0 +1,54 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_TLS_GNUTLS_INC__ +# define __BOOST_NETWORK_TLS_GNUTLS_INC__ + + +# include +# include + + +namespace boost { +namespace network { +template < + class Tag + > +basic_gnutls { +public: + + typedef typename string::type string_type; + + basic_gnutls(); + + ~basic_gnutls(); + +private: + + gnutls_session_t session_; + gnutls_certificate_credentials_t credentials_; + +}; + + +template < + class Tag + > +basic_gnutls::basic_gnutls() { + +} + +template < + class Tag + > +basic_gnutls::~basic_gnutls() { + +} +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_TLS_GNUTLS_INC__ diff --git a/boost/network/tls/openssl.hpp b/boost/network/tls/openssl.hpp new file mode 100644 index 000000000..2f9fa8d59 --- /dev/null +++ b/boost/network/tls/openssl.hpp @@ -0,0 +1,20 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef __BOOST_NETWORK_TLS_OPENSSL_INC__ +# define __BOOST_NETWORK_TLS_OPENSSL_INC__ + + +namespace boost { +namespace network { +namespace tls { + +} // namespace tls +} // namespace network +} // namespace boost + + +#endif // __BOOST_NETWORK_TLS_OPENSSL_INC__ diff --git a/boost/network/detail/xml_wrappers/element.hpp b/boost/network/xml/element.hpp similarity index 93% rename from boost/network/detail/xml_wrappers/element.hpp rename to boost/network/xml/element.hpp index c1df42b7f..e218f3344 100644 --- a/boost/network/detail/xml_wrappers/element.hpp +++ b/boost/network/xml/element.hpp @@ -4,14 +4,14 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ +#ifndef __BOOST_NETWORK_XML_ELEMENT_INC__ +# define __BOOST_NETWORK_XML_ELEMENT_INC__ # include # include -# include -# include +# include +# include # include # include # include @@ -185,4 +185,4 @@ typedef basic_element element; } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_INC__ +#endif // __BOOST_NETWORK_XML_ELEMENT_INC__ diff --git a/boost/network/detail/xml_wrappers/element_io.hpp b/boost/network/xml/element_io.hpp similarity index 82% rename from boost/network/detail/xml_wrappers/element_io.hpp rename to boost/network/xml/element_io.hpp index abf515e82..fc3a01629 100644 --- a/boost/network/detail/xml_wrappers/element_io.hpp +++ b/boost/network/xml/element_io.hpp @@ -4,13 +4,11 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ +#ifndef __BOOST_NETWORK_XML_ELEMENT_IO_INC__ +# define __BOOST_NETWORK_XML_ELEMENT_IO_INC__ -# include -# include -# include +# include # include @@ -55,4 +53,4 @@ std::ostream &operator << (std::ostream &os, } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_ELEMENT_IO_INC__ +#endif // __BOOST_NETWORK_XML_ELEMENT_IO_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp b/boost/network/xml/parser_backends/expat_parser.hpp similarity index 93% rename from boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp rename to boost/network/xml/parser_backends/expat_parser.hpp index 2a3af43ef..6bc0c16c8 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/expat_parser.hpp +++ b/boost/network/xml/parser_backends/expat_parser.hpp @@ -4,12 +4,12 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#ifndef __BOOST_NETWORK_XML_PARSER_BACKENDS_EXPAT_PARSER_INC__ +# define __BOOST_NETWORK_XML_PARSER_BACKENDS_EXPAT_PARSER_INC__ # include -# include +# include # include # include # include @@ -144,4 +144,4 @@ class basic_expat_parser : boost::noncopyable { } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_PARSER_INC__ +#endif // __BOOST_NETWORK_XML_PARSER_BACKENDS_EXPAT_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp b/boost/network/xml/parser_backends/libxml2_parser.hpp similarity index 93% rename from boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp rename to boost/network/xml/parser_backends/libxml2_parser.hpp index 127330691..33eb2b491 100644 --- a/boost/network/detail/xml_wrappers/parser_backends/libxml2_parser.hpp +++ b/boost/network/xml/parser_backends/libxml2_parser.hpp @@ -4,12 +4,12 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#ifndef __BOOST_NETWORK_XML_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +# define __BOOST_NETWORK_XML_PARSER_BACKENDS_LIBXML2_PARSER_INC__ # include -# include +# include # include # include # include @@ -148,4 +148,4 @@ class basic_libxml2_parser { } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_PARSER_INC__ +#endif // __BOOST_NETWORK_XML_PARSER_BACKENDS_LIBXML2_PARSER_INC__ diff --git a/boost/network/detail/xml_wrappers/traits/element_children.hpp b/boost/network/xml/traits/element_children.hpp similarity index 76% rename from boost/network/detail/xml_wrappers/traits/element_children.hpp rename to boost/network/xml/traits/element_children.hpp index a9164a43b..39db086a8 100644 --- a/boost/network/detail/xml_wrappers/traits/element_children.hpp +++ b/boost/network/xml/traits/element_children.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ +#ifndef __BOOST_NETWORK_XML_TRAITS_ELEMENT_CHILDREN_INC__ +# define __BOOST_NETWORK_XML_TRAITS_ELEMENT_CHILDREN_INC__ # include @@ -39,4 +39,4 @@ struct element_children { } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_ELEMENT_CHILDREN_INC__ +#endif // __BOOST_NETWORK_XML_TRAITS_ELEMENT_CHILDREN_INC__ diff --git a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp b/boost/network/xml/traits/parser_backend.hpp similarity index 74% rename from boost/network/detail/xml_wrappers/traits/parser_backend.hpp rename to boost/network/xml/traits/parser_backend.hpp index b2e1baad2..b22239e6d 100644 --- a/boost/network/detail/xml_wrappers/traits/parser_backend.hpp +++ b/boost/network/xml/traits/parser_backend.hpp @@ -4,8 +4,8 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ -# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ +#ifndef __BOOST_NETWORK_XML_TRAITS_PARSER_BACKEND_INC__ +# define __BOOST_NETWORK_XML_TRAITS_PARSER_BACKEND_INC__ # include @@ -37,4 +37,4 @@ struct parser_backend { } // namespace boost -#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_TRAITS_PARSER_BACKEND_INC__ +#endif // __BOOST_NETWORK_XML_TRAITS_PARSER_BACKEND_INC__ diff --git a/libs/network/test/tls/test_gnutls.cpp b/libs/network/test/tls/test_gnutls.cpp new file mode 100644 index 000000000..9282c963c --- /dev/null +++ b/libs/network/test/tls/test_gnutls.cpp @@ -0,0 +1,14 @@ +// Copyright (c) Glyn Matthews 2010. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_TEST_MODULE GNU TLS tests +#include +#include + + +BOOST_AUTO_TEST_CASE(test1) { + +} diff --git a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp index 3adef8e57..927142c03 100644 --- a/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/expat_element_parser_tests.cpp @@ -6,9 +6,9 @@ #define BOOST_TEST_MODULE expat wrapper tests #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp index f42261128..1bd166092 100644 --- a/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp +++ b/libs/network/test/xml_wrappers/libxml2_element_parser_tests.cpp @@ -7,8 +7,8 @@ #define BOOST_TEST_MODULE libxml2 wrapper tests #include -#include -#include +#include +#include using namespace boost::network::detail; diff --git a/libs/network/test/xml_wrappers/xml_element_tests.cpp b/libs/network/test/xml_wrappers/xml_element_tests.cpp index 849b49881..c3082a248 100644 --- a/libs/network/test/xml_wrappers/xml_element_tests.cpp +++ b/libs/network/test/xml_wrappers/xml_element_tests.cpp @@ -6,8 +6,8 @@ #define BOOST_TEST_MODULE XML element tests #include -#include -#include +#include +#include using namespace boost::network::detail; From fc8c1538eaa25a25279fbee3e097a5451e84f9a3 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Mon, 18 Oct 2010 22:28:36 +0200 Subject: [PATCH 016/438] Still need to work out what to do with TLS and XML; need to add a state machine to the XMPP client. --- boost/network/auth/sasl.hpp | 6 ++--- boost/network/protocol/xmpp/client.hpp | 26 ++++++++++++------- boost/network/protocol/xmpp/error.hpp | 4 +-- boost/network/protocol/xmpp/iq.hpp | 10 +++---- boost/network/protocol/xmpp/message.hpp | 16 ++++++------ boost/network/protocol/xmpp/namespaces.hpp | 14 +++++----- boost/network/protocol/xmpp/presence.hpp | 6 ++--- boost/network/protocol/xmpp/stanza.hpp | 6 ++--- boost/network/tags.hpp | 2 +- boost/network/tls/gnutls.hpp | 6 ++--- boost/network/xml/element.hpp | 14 +++++----- boost/network/xml/element_io.hpp | 6 ++--- .../xml/parser_backends/expat_parser.hpp | 10 +++---- .../xml/parser_backends/libxml2_parser.hpp | 14 +++++----- 14 files changed, 73 insertions(+), 67 deletions(-) diff --git a/boost/network/auth/sasl.hpp b/boost/network/auth/sasl.hpp index 08f90ed07..30db79696 100644 --- a/boost/network/auth/sasl.hpp +++ b/boost/network/auth/sasl.hpp @@ -28,17 +28,17 @@ class basic_sasl { typedef typename string::type string_type; // explicit basic_sasl(anonymous); - // + // // explicit basic_sasl(plain, // const string_type &id, const string_type &password); - // + // // explicit basic_sasl(digest_md5, // const string_type &challenge,const string_type &jid, const string_type &password); private: string_type auth_string_; - + }; } // namespace auth } // namespace network diff --git a/boost/network/protocol/xmpp/client.hpp b/boost/network/protocol/xmpp/client.hpp index 8f846b67f..6d2889118 100644 --- a/boost/network/protocol/xmpp/client.hpp +++ b/boost/network/protocol/xmpp/client.hpp @@ -49,18 +49,24 @@ class basic_client : boost::noncopyable { private: + enum connection_state { + disconnected, + processing_stream_features, + processing_starttls + }; + typedef basic_client this_type; typedef typename detail::parser_backend::type parser_type; public: typedef typename string::type string_type; - + typedef basic_message message_type; typedef basic_presence presence_type; typedef basic_iq iq_type; typedef basic_error error_type; - + explicit basic_client(Handler &handler); ~basic_client(); @@ -100,7 +106,7 @@ class basic_client : boost::noncopyable { // tcp socket boost::asio::ip::tcp::socket socket_; - + // tls // sasl @@ -112,7 +118,7 @@ class basic_client : boost::noncopyable { // std::deque stanza_queue_; std::string write_buffer_, read_buffer_; - + }; @@ -124,7 +130,7 @@ template < > basic_client::basic_client(Handler &handler) : handler_(handler), socket_(io_service_), work_(io_service_) { - + } @@ -135,7 +141,7 @@ template < class Handler > basic_client::~basic_client() { - + } template < @@ -145,7 +151,7 @@ template < class Handler > void basic_client::set_lang(const string_type &lang) { - + } @@ -158,7 +164,7 @@ template < void basic_client::connect(const string_type &jid, const string_type &password) { using boost::asio::ip::tcp; - + // get the JID domain // default port is 5222 // open socket @@ -254,7 +260,7 @@ void basic_client::handle_connect( boost::asio::ip::tcp::resolver::iterator iterator) { if (!ec) { std::ostringstream os; - os << + os << "" << " { explicit client(Handler &handler) : basic_client(handler) { - + } }; diff --git a/boost/network/protocol/xmpp/error.hpp b/boost/network/protocol/xmpp/error.hpp index 138903d45..4c0c6474d 100644 --- a/boost/network/protocol/xmpp/error.hpp +++ b/boost/network/protocol/xmpp/error.hpp @@ -22,9 +22,9 @@ class basic_error public: basic_error() { - + } - + }; diff --git a/boost/network/protocol/xmpp/iq.hpp b/boost/network/protocol/xmpp/iq.hpp index c861aa8ce..1b2ce184e 100644 --- a/boost/network/protocol/xmpp/iq.hpp +++ b/boost/network/protocol/xmpp/iq.hpp @@ -29,13 +29,13 @@ class basic_iq typedef typename base_type::headers_container_type headers_container_type; basic_iq() { - static const char name[] = {'i', 'q'}; + static const char name[] = {'i', 'q', 0}; base_type::set_name(string_type(name, name + sizeof(name))); } basic_iq(const basic_iq &other) : basic_stanza(other) { - + } basic_iq &operator = (const basic_iq &other) { @@ -45,14 +45,14 @@ class basic_iq } ~basic_iq() { - + } void swap(basic_iq &other) { base_type::swap(other); } - -}; + +}; typedef basic_iq iq; diff --git a/boost/network/protocol/xmpp/message.hpp b/boost/network/protocol/xmpp/message.hpp index 926453f13..fcb70d53a 100644 --- a/boost/network/protocol/xmpp/message.hpp +++ b/boost/network/protocol/xmpp/message.hpp @@ -29,13 +29,13 @@ class basic_message typedef typename base_type::headers_container_type headers_container_type; basic_message() { - static const char name[] = {'m', 'e', 's', 's', 'a', 'g', 'e'}; + static const char name[] = {'m', 'e', 's', 's', 'a', 'g', 'e', 0}; base_type::set_name(string_type(name, name + sizeof(name))); } basic_message(const basic_message &other) : basic_stanza(other) { - + } basic_message &operator = (const basic_message &other) { @@ -45,7 +45,7 @@ class basic_message } ~basic_message() { - + } void swap(basic_message &other) { @@ -53,25 +53,25 @@ class basic_message } void set_type(const string_type &type) { - static const char *type_ = "type"; + static const char type_[] = {'t', 'y', 'p', 'e', 0}; set_attribute(string_type(type_, type_ + std::strlen(type_)), type); } string_type type() const { - static const char *type_ = "type"; + static const char type_[] = {'t', 'y', 'p', 'e', 0}; return get_attribute(string_type(type_, type_ + std::strlen(type_))); } void set_id(const string_type &id) { - static const char *id_ = "id"; + static const char id_[] = {'i', 'd', 0}; set_attribute(string_type(id_, id_ + std::strlen(id_)), id); } string_type id() const { - static const char *id_ = "id"; + static const char id_[] = {'i', 'd', 0}; return get_attribute(string_type(id_, id_ + std::strlen(id_))); } - + }; diff --git a/boost/network/protocol/xmpp/namespaces.hpp b/boost/network/protocol/xmpp/namespaces.hpp index cea1a231f..3071f6a04 100644 --- a/boost/network/protocol/xmpp/namespaces.hpp +++ b/boost/network/protocol/xmpp/namespaces.hpp @@ -21,7 +21,7 @@ template < inline typename string::type client() { static const char client[] = { - 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'l', 'i', 'e', 'n', 't'}; + 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'l', 'i', 'e', 'n', 't', 0}; return typename string::type( client, client + sizeof(client)); } @@ -32,7 +32,7 @@ template < inline typename string::type server() { static const char server[] = { - 'j', 'a', 'b', 'b', 'e', 'r', ':', 's', 'e', 'r', 'v', 'e', 'r'}; + 'j', 'a', 'b', 'b', 'e', 'r', ':', 's', 'e', 'r', 'v', 'e', 'r', 0}; return typename string::type( server, server + sizeof(server)); } @@ -44,7 +44,7 @@ inline typename string::type component() { static const char component[] = { 'j', 'a', 'b', 'b', 'e', 'r', ':', 'c', 'o', 'm', 'p', 'o', - 'n', 'e', 'n', 't', ':', 'a', 'c', 'c', 'e', 'p', 't'}; + 'n', 'e', 'n', 't', ':', 'a', 'c', 'c', 'e', 'p', 't', 0}; return typename string::type( component, component + sizeof(component)); } @@ -57,7 +57,7 @@ typename string::type streams() { static const char streams[] = { 'h', 't', 't', 'p', ':', '/', '/', 'e', 't', 'h', 'e', 'r', 'x', '.', 'j', 'a', 'b', 'b', 'e', 'r', '.', 'o', 'r', 'g', - '/', 's', 't', 'r', 'e', 'a', 'm', 's'}; + '/', 's', 't', 'r', 'e', 'a', 'm', 's', 0}; return typename string::type( streams, streams + sizeof(streams)); } @@ -70,7 +70,7 @@ typename string::type streams_ietf() { static const char streams_ietf[] = { 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', - 'm', 'p', 'p', '-', 's', 't', 'r', 'e', 'a', 'm', 's'}; + 'm', 'p', 'p', '-', 's', 't', 'r', 'e', 'a', 'm', 's', 0}; return typename string::type( streams_ietf, streams_ietf + sizeof(streams_ietf)); } @@ -83,7 +83,7 @@ typename string::type tls() { static const char tls[] = { 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', - 'm', 'p', 'p', '-', 't', 'l', 's'}; + 'm', 'p', 'p', '-', 't', 'l', 's', 0}; return typename string::type(tls, tls + sizeof(tls)); } @@ -95,7 +95,7 @@ typename string::type sasl() { static const char sasl[] = { 'u', 'r', 'n', ':', 'i', 'e', 't', 'f', ':', 'p', 'a', 'r', 'a', 'm', 's', ':', 'x', 'm', 'l', ':', 'n', 's', ':', 'x', - 'm', 'p', 'p', '-', 's', 'a', 's', 'l'}; + 'm', 'p', 'p', '-', 's', 'a', 's', 'l', 0}; return typename string::type(sasl, sasl + sizeof(sasl)); } } // namespace ns diff --git a/boost/network/protocol/xmpp/presence.hpp b/boost/network/protocol/xmpp/presence.hpp index f18494b5d..4978ad269 100644 --- a/boost/network/protocol/xmpp/presence.hpp +++ b/boost/network/protocol/xmpp/presence.hpp @@ -29,13 +29,13 @@ class basic_presence typedef typename base_type::headers_container_type headers_container_type; basic_presence() { - static const char name[] = {'p', 'r', 'e', 's', 'e', 'n', 'c', 'e'}; + static const char name[] = {'p', 'r', 'e', 's', 'e', 'n', 'c', 'e', 0}; base_type::set_name(string_type(name, name + sizeof(name))); } basic_presence(const basic_presence &other) : basic_stanza(other) { - + } basic_presence &operator = (const basic_presence &other) { @@ -45,7 +45,7 @@ class basic_presence } ~basic_presence() { - + } void swap(basic_presence &other) { diff --git a/boost/network/protocol/xmpp/stanza.hpp b/boost/network/protocol/xmpp/stanza.hpp index 4be13ef60..657a50092 100644 --- a/boost/network/protocol/xmpp/stanza.hpp +++ b/boost/network/protocol/xmpp/stanza.hpp @@ -22,13 +22,13 @@ class basic_stanza : public boost::network::basic_message { typedef boost::network::basic_message base_type; - + public: typedef typename base_type::string_type string_type; explicit basic_stanza() { - + } explicit basic_stanza(const string_type &name) { @@ -59,7 +59,7 @@ class basic_stanza private: detail::basic_element element_; - + }; diff --git a/boost/network/tags.hpp b/boost/network/tags.hpp index 9072c404d..0148ab373 100644 --- a/boost/network/tags.hpp +++ b/boost/network/tags.hpp @@ -45,7 +45,7 @@ namespace boost { namespace network { namespace tags { name##_tags, \ mpl::inherit \ >::type name; \ - template <> struct components { typedef name##_tags type; }; + template <> struct components { typedef name##_tags type; }; BOOST_NETWORK_DEFINE_TAG(http_default_8bit_tcp_resolve); BOOST_NETWORK_DEFINE_TAG(http_default_8bit_udp_resolve); diff --git a/boost/network/tls/gnutls.hpp b/boost/network/tls/gnutls.hpp index 3a9c661ed..78850ba8b 100644 --- a/boost/network/tls/gnutls.hpp +++ b/boost/network/tls/gnutls.hpp @@ -30,7 +30,7 @@ basic_gnutls { gnutls_session_t session_; gnutls_certificate_credentials_t credentials_; - + }; @@ -38,14 +38,14 @@ template < class Tag > basic_gnutls::basic_gnutls() { - + } template < class Tag > basic_gnutls::~basic_gnutls() { - + } } // namespace network } // namespace boost diff --git a/boost/network/xml/element.hpp b/boost/network/xml/element.hpp index e218f3344..eef069f5d 100644 --- a/boost/network/xml/element.hpp +++ b/boost/network/xml/element.hpp @@ -37,17 +37,17 @@ class basic_element { typedef typename element_children::type element_children_type; basic_element() { - + } basic_element(tag, const string_type &name) : name_(name) { - + } basic_element(text, const string_type &text) : text_(text) { - + } basic_element(const basic_element &other) @@ -55,7 +55,7 @@ class basic_element { attributes_(other.attributes_), children_(other.children_), text_(other.text_) { - + } basic_element &operator = (const basic_element &other) { @@ -65,7 +65,7 @@ class basic_element { } ~basic_element() { - + } void swap(basic_element &other) { @@ -89,7 +89,7 @@ class basic_element { assert(!is_tag()); text_ = text; } - + boost::optional get_text() const { assert(is_text()); return text_.get(); @@ -146,7 +146,7 @@ class basic_element { void add_child(basic_element *element) { assert(is_tag()); boost::shared_ptr > shared_element(element); - children_.push_back(shared_element); + children_.push_back(shared_element); } boost::optional &> get_child(const string_type &name) const { diff --git a/boost/network/xml/element_io.hpp b/boost/network/xml/element_io.hpp index fc3a01629..6f7c921b5 100644 --- a/boost/network/xml/element_io.hpp +++ b/boost/network/xml/element_io.hpp @@ -24,11 +24,11 @@ std::ostream &operator << (std::ostream &os, typedef typename basic_element::element_children_type::const_iterator children_iterator; typedef boost::iterator_range header_range; typedef boost::iterator_range children_range; - + if (element.is_tag()) { os << "<" << element.get_name(); header_range attributes(element.get_attributes()); - + header_iterator attr_it(boost::begin(attributes)), attr_end(boost::end(attributes)); for (; attr_it != attr_end; ++attr_it) { os << " " << attr_it->first << "='" << attr_it->second << "'"; @@ -36,7 +36,7 @@ std::ostream &operator << (std::ostream &os, os << ">"; children_range children(element.get_children()); - + children_iterator child_it(boost::begin(children)), child_end(boost::end(children)); for (; child_it != child_end; ++child_it) { os << **child_it; diff --git a/boost/network/xml/parser_backends/expat_parser.hpp b/boost/network/xml/parser_backends/expat_parser.hpp index 6bc0c16c8..453342a0d 100644 --- a/boost/network/xml/parser_backends/expat_parser.hpp +++ b/boost/network/xml/parser_backends/expat_parser.hpp @@ -40,7 +40,7 @@ class basic_expat_parser : boost::noncopyable { ~basic_expat_parser() { XML_ParserFree(parser_); } - + bool feed(const string_type &chunk) { while (!elements_.empty()) { elements_.pop(); @@ -49,7 +49,7 @@ class basic_expat_parser : boost::noncopyable { depth_ = 0; return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0; } - + bool feed(const string_type &chunk, element_type &element) { while (!elements_.empty()) { elements_.pop(); @@ -88,7 +88,7 @@ class basic_expat_parser : boost::noncopyable { const XML_Char **attrs) { basic_expat_parser *parser = static_cast *>(userdata); - + if (!parser->elements_.top()) { return; } @@ -108,7 +108,7 @@ class basic_expat_parser : boost::noncopyable { const XML_Char *name) { basic_expat_parser *parser = static_cast *>(userdata); - + if (!parser->elements_.top()) { return; } @@ -125,7 +125,7 @@ class basic_expat_parser : boost::noncopyable { int len) { basic_expat_parser *parser = static_cast *>(userdata); - + if (!parser->elements_.top()) { return; } diff --git a/boost/network/xml/parser_backends/libxml2_parser.hpp b/boost/network/xml/parser_backends/libxml2_parser.hpp index 33eb2b491..f966208fc 100644 --- a/boost/network/xml/parser_backends/libxml2_parser.hpp +++ b/boost/network/xml/parser_backends/libxml2_parser.hpp @@ -35,8 +35,8 @@ class basic_libxml2_parser { handlers_.endElement = end_element; handlers_.characters = characters; depth_ = 0; - - context_ = xmlCreatePushParserCtxt(&handlers_, + + context_ = xmlCreatePushParserCtxt(&handlers_, this, 0, 0, 0); // assert(!context_); } @@ -103,7 +103,7 @@ class basic_libxml2_parser { } set_name(parser->elements_.top(), name); set_attributes(parser->elements_.top(), attrs); - + ++parser->depth_; } @@ -111,7 +111,7 @@ class basic_libxml2_parser { const xmlChar *name) { basic_libxml2_parser *parser = static_cast *>(userdata); - + if (!parser->elements_.top()) { return; } @@ -128,7 +128,7 @@ class basic_libxml2_parser { int len) { basic_libxml2_parser *parser = static_cast *>(userdata); - + if (!parser->elements_.top()) { return; } @@ -136,12 +136,12 @@ class basic_libxml2_parser { parser->elements_.top()->add_child( new element_type(typename element_type::text(), string_type(s, s + len))); } - + xmlParserCtxtPtr context_; xmlSAXHandler handlers_; std::stack elements_; int depth_; - + }; } // namespace detail } // namespace network From 1cc3acbf8a23003b54967992ea6d5a888a973ef2 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Mon, 25 Apr 2011 01:34:04 +1000 Subject: [PATCH 017/438] Fixes #40 : Write headers and status in one packet This commit removes the additional call to write when an HTTP response is written out from the asynchronous server that causes browsers to choke when the status line does not come with the headers in a single frame. --- .../protocol/http/server/async_connection.hpp | 96 +++++-------------- 1 file changed, 24 insertions(+), 72 deletions(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index 1f566f2ff..9d3b46aa6 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -140,9 +140,7 @@ namespace boost { namespace network { namespace http { , handler(handler) , thread_pool_(thread_pool) , headers_already_sent(false) - , first_line_already_sent(false) , headers_in_progress(false) - , first_line_in_progress(false) , headers_buffer(BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE) { new_start = read_buffer_.begin(); @@ -167,26 +165,30 @@ namespace boost { namespace network { namespace http { template void set_headers(Range headers) { lock_guard lock(headers_mutex); - if (first_line_in_progress || headers_in_progress || headers_already_sent) + if (headers_in_progress || headers_already_sent) boost::throw_exception(std::logic_error("Headers have already been sent.")); if (error_encountered) boost::throw_exception(boost::system::system_error(*error_encountered)); typedef constants consts; - headers_buffer.consume(headers_buffer.size()); - std::ostream stream(&headers_buffer); - if (!boost::empty(headers)) { - typedef typename Range::const_iterator iterator; - typedef typename string::type string_type; - boost::transform(headers, - std::ostream_iterator(stream), - linearize_header()); - } else { + { + std::ostream stream(&headers_buffer); + stream + << consts::http_slash() << 1<< consts::dot() << 1 << consts::space() + << status << consts::space() << status_message(status) + << consts::crlf(); + if (!boost::empty(headers)) { + typedef typename Range::const_iterator iterator; + typedef typename string::type string_type; + boost::transform(headers, + std::ostream_iterator(stream), + linearize_header()); + } else { + stream << consts::crlf(); + } stream << consts::crlf(); } - stream << consts::crlf(); - stream.flush(); write_headers_only( boost::bind( @@ -307,8 +309,8 @@ namespace boost { namespace network { namespace http { asio::io_service::strand strand; Handler & handler; utils::thread_pool & thread_pool_; - volatile bool headers_already_sent, first_line_already_sent, headers_in_progress, first_line_in_progress; - asio::streambuf headers_buffer, first_line_buffer; + volatile bool headers_already_sent, headers_in_progress; + asio::streambuf headers_buffer; boost::recursive_mutex headers_mutex; buffer_type read_buffer_; @@ -468,23 +470,12 @@ namespace boost { namespace network { namespace http { } void client_error() { - status = bad_request; - write_first_line( - strand.wrap( - boost::bind( - &async_connection::client_error_first_line_written - , async_connection::shared_from_this() - , asio::placeholders::error - , asio::placeholders::bytes_transferred))); - } - - void client_error_first_line_written(boost::system::error_code const & ec, std::size_t bytes_transferred) { static char const * bad_request = "HTTP/1.0 400 Bad Request\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nBad Request."; asio::async_write( socket() - , asio::buffer(bad_request, 115) + , asio::buffer(bad_request, strlen(bad_request)) , strand.wrap( boost::bind( &async_connection::client_error_sent @@ -505,60 +496,21 @@ namespace boost { namespace network { namespace http { void do_nothing() {} - template - void write_first_line(Callback callback) { - lock_guard lock(headers_mutex); - if (first_line_in_progress) return; - first_line_in_progress = true; - - typedef constants consts; - first_line_buffer.consume(first_line_buffer.size()); - std::ostream first_line_stream(&first_line_buffer); - first_line_stream - << consts::http_slash() << 1<< consts::dot() << 1 << consts::space() - << status << consts::space() << status_message(status) - << consts::crlf() - << std::flush - ; - asio::async_write( - socket() - , first_line_buffer - , callback); - } - void write_headers_only(boost::function callback) { if (headers_in_progress) return; headers_in_progress = true; - - write_first_line( - strand.wrap( + asio::async_write( + socket() + , headers_buffer + , strand.wrap( boost::bind( - &async_connection::handle_first_line_written + &async_connection::handle_write_headers , async_connection::shared_from_this() , callback , asio::placeholders::error , asio::placeholders::bytes_transferred))); } - void handle_first_line_written(boost::function callback, boost::system::error_code const & ec, std::size_t bytes_transferred) { - lock_guard lock(headers_mutex); - if (!ec) { - first_line_already_sent = true; - asio::async_write( - socket() - , headers_buffer - , strand.wrap( - boost::bind( - &async_connection::handle_write_headers - , async_connection::shared_from_this() - , callback - , asio::placeholders::error - , asio::placeholders::bytes_transferred))); - } else { - error_encountered = in_place(ec); - } - } - void handle_write_headers(boost::function callback, boost::system::error_code const & ec, std::size_t bytes_transferred) { lock_guard lock(headers_mutex); if (!ec) { From 98a44c86576d8d6d883cc8269f46e668572b6149 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Mon, 25 Apr 2011 01:36:26 +1000 Subject: [PATCH 018/438] Adding settings for clang in Jamfile. --- libs/network/test/Jamfile.v2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/network/test/Jamfile.v2 b/libs/network/test/Jamfile.v2 index 318894c6e..f9ea75977 100644 --- a/libs/network/test/Jamfile.v2 +++ b/libs/network/test/Jamfile.v2 @@ -31,6 +31,9 @@ project network_test : darwin:-lpthread darwin:-lssl darwin:-lcrypto + clang:-lpthread + clang:-lssl + clang:-lcrypto cygwin,gcc:_WIN32_WINNT=0x0501 cygwin,gcc:__USE_W32_SOCKETS cygwin,gcc:ws2_32 From 701e10100bd6697e4ba408107310181e0851806d Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Tue, 6 Sep 2011 10:19:31 +1000 Subject: [PATCH 019/438] WIP: Gutting the beast. --- boost/network/protocol/http/client.hpp | 4 + .../protocol/http/client/async_impl.hpp | 42 +-- .../http/client/connection/async_base.hpp | 7 +- .../http/client/connection/async_normal.hpp | 34 +- .../connection_delegate_factory.hpp | 35 +- .../connection/resolver_delegate_factory.hpp | 31 ++ .../http/client/connection_manager.hpp | 40 +++ boost/network/protocol/http/client/facade.hpp | 309 +++++++++--------- .../protocol/http/client/parameters.hpp | 8 +- .../http/policies/async_connection.hpp | 101 +++--- .../http/policies/async_connection.ipp | 113 +++++++ .../protocol/http/policies/async_resolver.hpp | 75 ++--- 12 files changed, 479 insertions(+), 320 deletions(-) create mode 100644 boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp create mode 100644 boost/network/protocol/http/client/connection_manager.hpp create mode 100644 boost/network/protocol/http/policies/async_connection.ipp diff --git a/boost/network/protocol/http/client.hpp b/boost/network/protocol/http/client.hpp index 78a0619bf..9fdf0eeee 100644 --- a/boost/network/protocol/http/client.hpp +++ b/boost/network/protocol/http/client.hpp @@ -62,6 +62,9 @@ namespace boost { namespace network { namespace http { // -- the name of the directory from // which the certificate authority // files can be found + // _connection_manager : shared_ptr + // -- The connection manager to use for + // this client. BOOST_PARAMETER_CONSTRUCTOR( basic_client, (base_facade_type), tag, @@ -71,6 +74,7 @@ namespace boost { namespace network { namespace http { (cache_resolved, (bool)) (openssl_certificate, (string_type)) (openssl_verify_path, (string_type)) + (connection_manager, (shared_ptr)) )) // diff --git a/boost/network/protocol/http/client/async_impl.hpp b/boost/network/protocol/http/client/async_impl.hpp index a7e178d16..2fbd5d488 100644 --- a/boost/network/protocol/http/client/async_impl.hpp +++ b/boost/network/protocol/http/client/async_impl.hpp @@ -20,15 +20,8 @@ namespace boost { namespace network { namespace http { namespace impl { template - struct async_client : - connection_policy::type + struct async_client { - typedef - typename connection_policy::type - connection_base; - typedef - typename resolver::type - resolver_type; typedef typename string::type string_type; @@ -37,17 +30,12 @@ namespace boost { namespace network { namespace http { function const &, system::error_code const &)> body_callback_function_type; - async_client(bool cache_resolved, bool follow_redirect, optional const & certificate_filename, optional const & verify_path) - : connection_base(cache_resolved, follow_redirect), - service_ptr(new boost::asio::io_service), + async_client(shared_ptr connection_manager) + : service_ptr(new boost::asio::io_service), service_(*service_ptr), - resolver_(service_), sentinel_(new boost::asio::io_service::work(service_)), - certificate_filename_(certificate_filename), - verify_path_(verify_path) + connection_manager_(connection_manager) { - connection_base::resolver_strand_.reset(new - boost::asio::io_service::strand(service_)); lifetime_thread_.reset(new boost::thread( boost::bind( &boost::asio::io_service::run, @@ -55,20 +43,19 @@ namespace boost { namespace network { namespace http { ))); } - async_client(bool cache_resolved, bool follow_redirect, boost::asio::io_service & service, optional const & certificate_filename, optional const & verify_path) - : connection_base(cache_resolved, follow_redirect), - service_ptr(0), + async_client(boost::asio::io_service & service, + shared_ptr connection_manager) + : service_ptr(0), service_(service), - resolver_(service_), sentinel_(new boost::asio::io_service::work(service_)), - certificate_filename_(certificate_filename), - verify_path_(verify_path) + connection_manager_(connection_manager) { } ~async_client() throw () { sentinel_.reset(); + connection_manager_->reset(); if (lifetime_thread_.get()) { lifetime_thread_->join(); lifetime_thread_.reset(); @@ -83,17 +70,18 @@ namespace boost { namespace network { namespace http { body_callback_function_type callback ) { - typename connection_base::connection_ptr connection_; - connection_ = connection_base::get_connection(resolver_, request_, certificate_filename_, verify_path_); - return connection_->send_request(method, request_, get_body, callback); + shared_ptr connection_; + connection_ = connection_manager_->get_connection(service_, request_); + shared_ptr response = connection_->send_request( + method, request_, get_body, callback); + return *response; } boost::asio::io_service * service_ptr; boost::asio::io_service & service_; - resolver_type resolver_; boost::shared_ptr sentinel_; boost::shared_ptr lifetime_thread_; - optional certificate_filename_, verify_path_; + shared_ptr connection_manager_; }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/async_base.hpp b/boost/network/protocol/http/client/connection/async_base.hpp index 943ca2106..1cdf85486 100644 --- a/boost/network/protocol/http/client/connection/async_base.hpp +++ b/boost/network/protocol/http/client/connection/async_base.hpp @@ -42,10 +42,13 @@ namespace boost { namespace network { namespace http { namespace impl { async_connection; typedef typename delegate_factory::type delegate_factory_type; connection_ptr temp; + typedef typename resolver_delegate_factory::type + resolver_delegate_factory_type; temp.reset( new async_connection( - resolver, - resolve, + resolver_delegate_factory_type::new_resolver_delegate( + resolve, + resolver), follow_redirect, delegate_factory_type::new_connection_delegate( resolver.get_io_service(), diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index f1d0e9e3b..0595d408c 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -59,15 +59,14 @@ namespace boost { namespace network { namespace http { namespace impl { typedef typename delegate_factory_type::connection_delegate_ptr connection_delegate_ptr; - http_async_connection(resolver_type & resolver, - resolve_function resolve, + http_async_connection(resolver_delegate_ptr resolver_delegate, + asio::io_service & io_service, bool follow_redirect, connection_delegate_ptr delegate) : follow_redirect_(follow_redirect), - resolver_(resolver), - resolve_(resolve), - request_strand_(resolver.get_io_service()), + request_strand_(io_service), + resolver_delegate_(resolver_delegate), delegate_(delegate) {} // This is the main entry point for the connection/request pipeline. We're @@ -83,17 +82,17 @@ namespace boost { namespace network { namespace http { namespace impl { std::ostreambuf_iterator::type>(&command_streambuf)); this->method = method; boost::uint16_t port_ = port(request); - resolve_(resolver_, - host(request), - port_, - request_strand_.wrap( - boost::bind(&this_type::handle_resolved, - this_type::shared_from_this(), - port_, - get_body, - callback, - _1, - _2))); + resolver_delegate_->resolve(host(request), + port_, + request_strand_.wrap( + boost::bind( + &this_type::handle_resolved, + this_type::shared_from_this(), + port_, + get_body, + callback, + _1, + _2))); return response_; } @@ -419,9 +418,8 @@ namespace boost { namespace network { namespace http { namespace impl { } bool follow_redirect_; - resolver_type & resolver_; - resolve_function resolve_; boost::asio::io_service::strand request_strand_; + resolver_delegate_ptr resolver_delegate_; connection_delegate_ptr delegate_; boost::asio::streambuf command_streambuf; string_type method; diff --git a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp index eca673666..05991c6d4 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp @@ -20,33 +20,38 @@ struct ssl_delegate; struct normal_delegate; -template struct connection_delegate_factory { typedef shared_ptr connection_delegate_ptr; - typedef typename string::type string_type; // This is the factory method that actually returns the delegate instance. // TODO Support passing in proxy settings when crafting connections. static connection_delegate_ptr new_connection_delegate( asio::io_service & service, bool https, - optional certificate_filename, - optional verify_path) { - connection_delegate_ptr delegate; - if (https) { + optional certificate_filename, + optional verify_path); +}; + +connection_delegate_factory::connection_delegate_ptr +connection_delegate_factory::new_connection_delegate( + asio::io_service & service, + bool https, + optional certificate_filename, + optional verify_path) { + connection_delegate_ptr delegate; + if (https) { #ifdef BOOST_NETWORK_ENABLE_HTTPS - delegate.reset(new ssl_delegate(service, - certificate_filename, - verify_path)); + delegate.reset(new ssl_delegate(service, + certificate_filename, + verify_path)); #else - BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported.")); + BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported.")); #endif /* BOOST_NETWORK_ENABLE_HTTPS */ - } else { - delegate.reset(new normal_delegate(service)); - } - return delegate; + } else { + delegate.reset(new normal_delegate(service)); } -}; + return delegate; +} } /* impl */ } /* http */ diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp new file mode 100644 index 000000000..e754473f6 --- /dev/null +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_HPP_20110930 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_HPP_20110930 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { namespace impl { + +struct resolver_base; + +template +struct resolver_delegate_factory; + +template +struct resolver_delegate_factory >::type> { + typedef shared_ptr resolver_delegate_ptr; + // TODO Implement this! + resolver_delegate_ptr new_resolver_delegate(...); +}; + +} /* impl */ +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_HPP_20110930 */ diff --git a/boost/network/protocol/http/client/connection_manager.hpp b/boost/network/protocol/http/client/connection_manager.hpp new file mode 100644 index 000000000..aca063ee8 --- /dev/null +++ b/boost/network/protocol/http/client/connection_manager.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_HPP_20110930 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_HPP_20110930 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { namespace http { + +struct request_base; + +struct response_base; + +struct client_connection { + typedef function const &, + system::error_code const &)> + callback_type; + virtual shared_ptr send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) = 0; + virtual void reset() = 0; + virtual ~client_connection() = 0; +}; + +struct connection_manager { + virtual shared_ptr get_connection( + asio::io_service & service, + request_base const & request) = 0; + virtual void reset() = 0; + virtual ~connection_manager() = 0; +}; + +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_HPP_20110930 */ diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index 639fb7277..a47f78c7b 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -13,160 +13,161 @@ namespace boost { namespace network { namespace http { - template - struct basic_request; - - template - struct basic_response; - - template - struct basic_client_facade { - - typedef typename string::type string_type; - typedef basic_request request; - typedef basic_response response; - typedef basic_client_impl pimpl_type; - typedef function const &,system::error_code const &)> body_callback_function_type; - - template - basic_client_facade(ArgPack const & args) - { - init_pimpl(args, - typename mpl::if_< - is_same< - typename parameter::value_type::type, - void - >, - no_io_service, - has_io_service - >::type()); - } - - BOOST_PARAMETER_MEMBER_FUNCTION((response const), head, tag, (required (request,(request const &)))) { - return pimpl->request_skeleton(request, "HEAD", false, body_callback_function_type()); - } - - BOOST_PARAMETER_MEMBER_FUNCTION((response const), get , tag, - (required - (request,(request const &)) - ) - (optional - (body_handler,(body_callback_function_type),body_callback_function_type()) - ) - ) { - return pimpl->request_skeleton(request, "GET", true, body_handler); - } - - BOOST_PARAMETER_MEMBER_FUNCTION((response const), post, tag, - (required - (request,(request)) // yes sir, we make a copy of the original request. - ) - (optional - (body,(string_type const &),string_type()) - (content_type,(string_type const &),string_type()) - (body_handler,(body_callback_function_type),body_callback_function_type()) - ) - ) { - if (body != string_type()) { - request << remove_header("Content-Length") - << header("Content-Length", boost::lexical_cast(body.size())) - << boost::network::body(body); - } - typename headers_range >::type content_type_headers = - headers(request)["Content-Type"]; - if (content_type != string_type()) { - if (!boost::empty(content_type_headers)) - request << remove_header("Content-Type"); - request << header("Content-Type", content_type); - } else { - if (boost::empty(content_type_headers)) { - typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; - request << header("Content-Type", content_type); - } - } - return pimpl->request_skeleton(request, "POST", true, body_handler); - } - - BOOST_PARAMETER_MEMBER_FUNCTION((response const), put , tag, - (required - (request,(request)) // yes sir, we make a copy of the original request. - ) - (optional - (body,(string_type const &),string_type()) - (content_type,(string_type const &),string_type()) - (body_handler,(body_callback_function_type),body_callback_function_type()) - ) - ) { - if (body != string_type()) { - request << remove_header("Content-Length") - << header("Content-Length", boost::lexical_cast(body.size())) - << boost::network::body(body); - } - typename headers_range >::type content_type_headers = - headers(request)["Content-Type"]; - if (content_type != string_type()) { - if (!boost::empty(content_type_headers)) - request << remove_header("Content-Type"); - request << header("Content-Type", content_type); - } else { - if (boost::empty(content_type_headers)) { - typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; - request << header("Content-Type", content_type); - } - } - return pimpl->request_skeleton(request, "PUT", true, body_handler); - } - - BOOST_PARAMETER_MEMBER_FUNCTION((response const), delete_, tag, - (required - (request,(request const &)) - ) - (optional - (body_handler,(body_callback_function_type),body_callback_function_type()) - ) - ) { - return pimpl->request_skeleton(request, "DELETE", true, body_handler); - } - - void clear_resolved_cache() { - pimpl->clear_resolved_cache(); - } - - protected: - - struct no_io_service {}; - struct has_io_service {}; - - boost::shared_ptr pimpl; - - template - void init_pimpl(ArgPack const & args, no_io_service) { - pimpl.reset( - new pimpl_type( - args[_cache_resolved|false] - , args[_follow_redirects|false] - , optional(args[_openssl_certificate|optional()]) - , optional(args[_openssl_verify_path|optional()]) - ) - ); - } - - template - void init_pimpl(ArgPack const & args, has_io_service) { - pimpl.reset( - new pimpl_type( - args[_cache_resolved|false] - , args[_follow_redirects|false] - , args[_io_service] - , optional(args[_openssl_certificate|optional()]) - , optional(args[_openssl_verify_path|optional()]) - ) - ); - } - - }; +template +struct basic_request; + +template +struct basic_response; + +template +struct basic_client_facade { + + typedef typename string::type string_type; + typedef basic_request request; + typedef basic_response response; + typedef basic_client_impl pimpl_type; + typedef function const &,system::error_code const &)> body_callback_function_type; + + template + basic_client_facade(ArgPack const & args) { + init_pimpl(args, + typename mpl::if_< + is_same< + typename parameter::value_type::type, + void + >, + no_io_service, + has_io_service + >::type()); + } + + BOOST_PARAMETER_MEMBER_FUNCTION((response const), head, tag, (required (request,(request const &)))) { + return pimpl->request_skeleton(request, "HEAD", false, body_callback_function_type()); + } + + BOOST_PARAMETER_MEMBER_FUNCTION((response const), get , tag, + (required + (request,(request const &)) + ) + (optional + (body_handler,(body_callback_function_type),body_callback_function_type()) + )) { + return pimpl->request_skeleton(request, "GET", true, body_handler); + } + + BOOST_PARAMETER_MEMBER_FUNCTION((response const), post, tag, + (required + (request,(request)) // yes sir, we make a copy of the original request. + ) + (optional + (body,(string_type const &),string_type()) + (content_type,(string_type const &),string_type()) + (body_handler,(body_callback_function_type),body_callback_function_type()) + )) { + if (body != string_type()) { + request << remove_header("Content-Length") + << header("Content-Length", boost::lexical_cast(body.size())) + << boost::network::body(body); + } + + typename headers_range >::type content_type_headers = + headers(request)["Content-Type"]; + if (content_type != string_type()) { + if (!boost::empty(content_type_headers)) + request << remove_header("Content-Type"); + request << header("Content-Type", content_type); + } else { + if (boost::empty(content_type_headers)) { + typedef typename char_::type char_type; + static char_type content_type[] = "x-application/octet-stream"; + request << header("Content-Type", content_type); + } + } + return pimpl->request_skeleton(request, "POST", true, body_handler); + } + + BOOST_PARAMETER_MEMBER_FUNCTION((response const), put , tag, + (required + (request,(request)) // yes sir, we make a copy of the original request. + ) + (optional + (body,(string_type const &),string_type()) + (content_type,(string_type const &),string_type()) + (body_handler,(body_callback_function_type),body_callback_function_type()) + )) { + if (body != string_type()) { + request << remove_header("Content-Length") + << header("Content-Length", boost::lexical_cast(body.size())) + << boost::network::body(body); + } + + typename headers_range >::type content_type_headers = + headers(request)["Content-Type"]; + if (content_type != string_type()) { + if (!boost::empty(content_type_headers)) + request << remove_header("Content-Type"); + request << header("Content-Type", content_type); + } else { + if (boost::empty(content_type_headers)) { + typedef typename char_::type char_type; + static char_type content_type[] = "x-application/octet-stream"; + request << header("Content-Type", content_type); + } + } + return pimpl->request_skeleton(request, "PUT", true, body_handler); + } + + BOOST_PARAMETER_MEMBER_FUNCTION((response const), delete_, tag, + (required + (request,(request const &)) + ) + (optional + (body_handler,(body_callback_function_type),body_callback_function_type()) + )) { + return pimpl->request_skeleton(request, "DELETE", true, body_handler); + } + + void clear_resolved_cache() { + pimpl->clear_resolved_cache(); + } + + protected: + + struct no_io_service {}; + struct has_io_service {}; + + boost::scoped_ptr pimpl; + + template + void init_pimpl(ArgPack const & args, no_io_service) { + pimpl.reset(new pimpl_type(this->get_connection_manager(args))); + } + + template + void init_pimpl(ArgPack const & args, has_io_service) { + pimpl.reset(new pimpl_type(args[_io_service], this->get_connection_manager(args))); + } + + private: + + template + shared_ptr get_connection_manager(ArgPack const & args) { + shared_ptr connection_manager_ = ptr; + if (!connection_manager_.get()) { + // Because there's no explicit connection manager, we use the default + // implementation as provided by the tag. + typedef typename async_connection_policy::type + default_connection_manager_type; + connection_manager_.reset( + new default_connection_manager_type(args[_cache_resolved|false], + args[_follow_redirects|false], + args[_openssl_certificate|optional()], + args[_openssl_verify_path|optional()])); + } + + return connection_manager_; + } +}; } // namespace http diff --git a/boost/network/protocol/http/client/parameters.hpp b/boost/network/protocol/http/client/parameters.hpp index dade4e756..19c213fe1 100644 --- a/boost/network/protocol/http/client/parameters.hpp +++ b/boost/network/protocol/http/client/parameters.hpp @@ -14,16 +14,16 @@ namespace boost { namespace network { namespace http { BOOST_PARAMETER_NAME(cache_resolved) BOOST_PARAMETER_NAME(openssl_certificate) BOOST_PARAMETER_NAME(openssl_verify_path) - + BOOST_PARAMETER_NAME(request) BOOST_PARAMETER_NAME(body) BOOST_PARAMETER_NAME(content_type) BOOST_PARAMETER_NAME(body_handler) - + + BOOST_PARAMETER_NAME(connection_manager) + } /* http */ - } /* network */ - } /* boost */ #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_PARAMETERS_HPP_2010127 */ diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index ea8638d6b..145aff05c 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -22,64 +23,48 @@ namespace boost { namespace network { namespace http { - template - struct async_connection_policy : resolver_policy::type { - protected: - - typedef typename string::type string_type; - typedef typename resolver_policy::type resolver_base; - typedef typename resolver_base::resolver_type resolver_type; - typedef typename resolver_base::resolve_function resolve_function; - typedef function const &, system::error_code const &)> body_callback_function_type; - - struct connection_impl { - connection_impl( - bool follow_redirect, - resolve_function resolve, - resolver_type & resolver, - bool https, - optional const & certificate_filename, - optional const & verify_path - ) - { - pimpl = impl::async_connection_base::new_connection(resolve, resolver, follow_redirect, https, certificate_filename, verify_path); - } - - basic_response send_request(string_type const & method, basic_request const & request_, bool get_body, body_callback_function_type callback) { - return pimpl->start(request_, method, get_body, callback); - } - - private: - - shared_ptr > pimpl; - - }; - - typedef boost::shared_ptr connection_ptr; - connection_ptr get_connection(resolver_type & resolver, basic_request const & request_, optional const & certificate_filename = optional(), optional const & verify_path = optional()) { - string_type protocol_ = protocol(request_); - connection_ptr connection_( - new connection_impl( - follow_redirect_ - , boost::bind( - &async_connection_policy::resolve, - this, - _1, _2, _3, _4 - ) - , resolver - , boost::iequals(protocol_, string_type("https")) - , certificate_filename - , verify_path)); - return connection_; - } - - void cleanup() { } - - async_connection_policy(bool cache_resolved, bool follow_redirect) - : resolver_base(cache_resolved), follow_redirect_(follow_redirect) {} - - bool follow_redirect_; - }; +struct simple_async_connection_manager : connection_manager { + simple_async_connection_manager(bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path); + virtual shared_ptr get_connection( + asio::io_service & service, + request_base const & request); // override + virtual void reset(); // override + virtual ~simple_async_connection_manager(); // override + protected: + bool cache_resolved_, follow_redirects_; + mutex shared_resolver_mutex; + shared_ptr shared_resolver_delegate; +}; + +struct http_1_1_async_connection_manager_pimpl; + +struct http_1_1_async_connection_manager : connection_manager { + http_1_1_async_connection_manager(bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path); + virtual shared_ptr get_connection( + asio::io_service & service, + request_base const & request); // override + virtual void reset(); // override + virtual ~http_1_1_async_connection_manager(); // override +}; + +template +struct async_connection_policy; + +template +struct async_connection_policy { // HTTP/1.0 + typedef simple_async_connection_manager type; +} + +template +struct async_connection_policy { // HTTP/1.1 + typedef http_1_1_connection_manager type; +} } // namespace http diff --git a/boost/network/protocol/http/policies/async_connection.ipp b/boost/network/protocol/http/policies/async_connection.ipp new file mode 100644 index 000000000..4fc264788 --- /dev/null +++ b/boost/network/protocol/http/policies/async_connection.ipp @@ -0,0 +1,113 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_CONNECTION_IPP_20110930 +#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_CONNECTION_IPP_20110930 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { namespace http { + +struct simple_async_client_connection : client_connection { + simple_async_client_connection(asio::io_service & service, + bool follow_redirects, + shared_ptr resolver_delegate, + shared_ptr connection_delegate); + virtual shared_ptr send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback); // override + virtual void reset(); // override + virtual ~client_connection(); // override + protected: + asio::io_service & service_; + bool follow_redirects_; + shared_ptr resolver_delegate_; + shared_ptr connection_delegate_; + shared_ptr connection_; +}; + +simple_async_client_connection::simple_async_client_connection( + asio::io_service & service, + bool follow_redirects, + shared_ptr resolver_delegate, + shared_ptr connection_delegate) +: service_(service), + follow_redirects_(follow_redirects), + resolver_delegate_(resolver_delegate), + connection_delegate_(connection_delegate), +{} + +shared_ptr send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) { + shared_ptr response; + shared_ptr connection_; + connection_.reset(new impl::async_connection(resolver_delegate_, + follow_redirects_, + connection_delegate_)) + response = connection_->start(request, method, get_body, callback); + return response +} + +} /* http */ +} /* network */ +} /* boost */ + +boost::network::http::simple_async_connection_manager(bool cache_resolved, + bool follow_redirects, + boost::optional openssl_certificate, + boost::optional openssl_verify_path) +: cache_resolved_(cache_resolved), + follow_redirects_(follow_redirects), + openssl_certificate_(openssl_certificate), + openssl_verify_path_(openssl_verify_path), +{} + +boost::shared_ptr +boost::network::http::simple_async_connection_manager::get_connection( + boost::asio::io_service & service, + request_base const & request) { + // TODO move out calls to new to a factory, taken as a parameter at + // construction time so that we are not tied to actual hard-coded + // dependencies. + shared_ptr connection; + shared_ptr resolver_delegate; + if (cache_resolved_) { + scoped_lock delegate_lock(this->resolver_mutex); + if (!this->shared_resolver_delegate.get()) + this->shared_resolver_delegate.reset( + new (std::nothrow) async_resolver_delegate(service)); + resolver_delegate = this->shared_resolver_delegate; + if (!resolver_delegate_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Insufficient memory.")); + } else { + resolver_delegate.reset(new(std::nothrow) async_resolver(service)); + if (!resolver_delegate_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Insuffucuent memory.")); + } + shared_ptr connection_delegate; + bool https = (scheme(request) == "https"); + connection_delegate = + connection_delegate_factory::new_connection_delegate( + service, openssl_certificate_, openssl_verify_path_); + connection.reset( + new(std::nothrow) simple_async_client_connection(service, + follow_redirects_, + resolver_delegate, + connection_delegate)); + if (!connection.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Insufficient memory.")); + return connection; +} + +void boost::network::http::simple_async_connection_manager::reset() { + if (cache_resolved_) { + scoped_lock delegate_lock(this->resolver_mutex); + this->shared_resolver_delegate.reset(); + } +} + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_CONNECTION_IPP_20110930 */ diff --git a/boost/network/protocol/http/policies/async_resolver.hpp b/boost/network/protocol/http/policies/async_resolver.hpp index cb49a09cc..12745c0e0 100644 --- a/boost/network/protocol/http/policies/async_resolver.hpp +++ b/boost/network/protocol/http/policies/async_resolver.hpp @@ -12,51 +12,42 @@ namespace boost { namespace network { namespace http { namespace policies { - template - struct async_resolver - : boost::enable_shared_from_this > - { - typedef typename resolver::type resolver_type; - typedef typename resolver_type::iterator resolver_iterator; - typedef typename resolver_type::query resolver_query; - typedef std::pair resolver_iterator_pair; - typedef typename string::type string_type; - typedef boost::unordered_map endpoint_cache; - typedef boost::function resolve_completion_function; - typedef boost::function resolve_function; - protected: - bool cache_resolved_; - endpoint_cache endpoint_cache_; - boost::shared_ptr service_; - boost::shared_ptr resolver_strand_; +struct async_resolver : enable_shared_from_this { + typedef asio::ip::resolver::iterator resolver_iterator; + typedef asio::ip::resolver::query resolver_query; + typedef std::pair resolver_iterator_pair; + typedef boost::unordered_map endpoint_cache; + typedef boost::function resolve_completion_function; + typedef boost::function resolve_function; + protected: + bool cache_resolved_; + endpoint_cache endpoint_cache_; + boost::shared_ptr resolver_strand_; - explicit async_resolver(bool cache_resolved) - : cache_resolved_(cache_resolved), endpoint_cache_() - { - - } + async_resolver(bool cache_resolved): + cache_resolved_(cache_resolved), + endpoint_cache_() + {} + + void resolve( + resolver_type & resolver_, + std::string const & host, + boost::uint16_t port, + resolve_completion_function once_resolved) { + if (cache_resolved_) { + typename endpoint_cache::iterator iter = + endpoint_cache_.find(boost::to_lower_copy(host)); + if (iter != endpoint_cache_.end()) { + boost::system::error_code ignored; + once_resolved(ignored, iter->second); + return; + } + } - void resolve( - resolver_type & resolver_, - string_type const & host, - boost::uint16_t port, - resolve_completion_function once_resolved - ) - { - if (cache_resolved_) { - typename endpoint_cache::iterator iter = - endpoint_cache_.find(boost::to_lower_copy(host)); - if (iter != endpoint_cache_.end()) { - boost::system::error_code ignored; - once_resolved(ignored, iter->second); - return; - } - } - typename resolver_type::query q( resolver_type::protocol_type::v4() , host - , lexical_cast(port)); + , lexical_cast(port)); resolver_.async_resolve( q, resolver_strand_->wrap( @@ -73,8 +64,8 @@ namespace boost { namespace network { namespace http { namespace policies { } void handle_resolve( - string_type const & host, - resolve_completion_function once_resolved, + std::string const & host, + resolve_completion_function once_resolved, boost::system::error_code const & ec, resolver_iterator endpoint_iterator ) From 8651d163bf737edb5abad4768b1bdaf14cc6118d Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 9 Sep 2011 14:28:48 +1000 Subject: [PATCH 020/438] Incremental changes to slowly support persistent connections in HTTP/1.1 Async mode. --- .../http/policies/async_connection.hpp | 14 ++++++-- .../http/policies/async_connection.ipp | 34 ++++++++++++------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index 145aff05c..ace3d7137 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +40,9 @@ struct simple_async_connection_manager : connection_manager { shared_ptr shared_resolver_delegate; }; -struct http_1_1_async_connection_manager_pimpl; +struct http_1_1_async_connection; -struct http_1_1_async_connection_manager : connection_manager { +struct http_1_1_async_connection_manager : connection_manager, enable_shared_from_this { http_1_1_async_connection_manager(bool cache_resolved, bool follow_redirects, optional openssl_certificate, @@ -51,6 +52,15 @@ struct http_1_1_async_connection_manager : connection_manager { request_base const & request); // override virtual void reset(); // override virtual ~http_1_1_async_connection_manager(); // override + + protected: + friend struct http_1_1_async_connection; + void add_ready_connection(shared_ptr connection_ptr); + shared_ptr get_ready_connection(std::string const & host); + bool cache_resolved, follow_redirects_; + mutex shared_resolver_mutex; + shared_ptr shared_resolver_delegate; + unordered_map > ready_connections; }; template diff --git a/boost/network/protocol/http/policies/async_connection.ipp b/boost/network/protocol/http/policies/async_connection.ipp index 4fc264788..d638688bd 100644 --- a/boost/network/protocol/http/policies/async_connection.ipp +++ b/boost/network/protocol/http/policies/async_connection.ipp @@ -10,8 +10,7 @@ namespace boost { namespace network { namespace http { struct simple_async_client_connection : client_connection { - simple_async_client_connection(asio::io_service & service, - bool follow_redirects, + simple_async_client_connection(bool follow_redirects, shared_ptr resolver_delegate, shared_ptr connection_delegate); virtual shared_ptr send_request(std::string const & method, @@ -21,7 +20,6 @@ struct simple_async_client_connection : client_connection { virtual void reset(); // override virtual ~client_connection(); // override protected: - asio::io_service & service_; bool follow_redirects_; shared_ptr resolver_delegate_; shared_ptr connection_delegate_; @@ -29,12 +27,10 @@ struct simple_async_client_connection : client_connection { }; simple_async_client_connection::simple_async_client_connection( - asio::io_service & service, bool follow_redirects, shared_ptr resolver_delegate, shared_ptr connection_delegate) -: service_(service), - follow_redirects_(follow_redirects), +: follow_redirects_(follow_redirects), resolver_delegate_(resolver_delegate), connection_delegate_(connection_delegate), {} @@ -45,9 +41,12 @@ shared_ptr send_request(std::string const & method, callback_type callback) { shared_ptr response; shared_ptr connection_; - connection_.reset(new impl::async_connection(resolver_delegate_, - follow_redirects_, - connection_delegate_)) + connection_.reset(new(std::nothrow) impl::async_connection( + resolver_delegate_, + follow_redirects_, + connection_delegate_)) + if (!connection_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Insufficient memory.")); response = connection_->start(request, method, get_body, callback); return response } @@ -86,7 +85,7 @@ boost::network::http::simple_async_connection_manager::get_connection( } else { resolver_delegate.reset(new(std::nothrow) async_resolver(service)); if (!resolver_delegate_.get()) - BOOST_THROW_EXCEPTION(std::runtime_error("Insuffucuent memory.")); + BOOST_THROW_EXCEPTION(std::runtime_error("Insuffucient memory.")); } shared_ptr connection_delegate; bool https = (scheme(request) == "https"); @@ -94,8 +93,7 @@ boost::network::http::simple_async_connection_manager::get_connection( connection_delegate_factory::new_connection_delegate( service, openssl_certificate_, openssl_verify_path_); connection.reset( - new(std::nothrow) simple_async_client_connection(service, - follow_redirects_, + new(std::nothrow) simple_async_client_connection(follow_redirects_, resolver_delegate, connection_delegate)); if (!connection.get()) @@ -110,4 +108,16 @@ void boost::network::http::simple_async_connection_manager::reset() { } } +namespace boost { namespace network { namespace http { + +struct http_1_1_async_connection : client_connection { + http_1_1_async_connection(bool follow_redirects, + shared_ptr resolver_delegate, + shared_ptr connection_delegate) +} + +} /* http */ +} /* network */ +} /* boost */ + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_CONNECTION_IPP_20110930 */ From b75493987fca84fd1df36be5c175be2b83f07fc5 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 10 Sep 2011 23:23:43 +1000 Subject: [PATCH 021/438] Gutting the Beast Part 2. In this commit I remove all traces of traits and metafunctions that can all be replaced by dynamic dispatch. This also prepares to remove the divergence between the synchronous and asynchronous implementation of the messages/client. The goal is to actually just implement the asynchronous version without bothering with a synchronous version. The rationale for this is so that the implementation can grow and be generic while at the same time require that the implementation rely on Boost.Thread in a real way. Part of this commit is the beginnings of the segmented request storage base that will use Boost.IOStreams to support a unified interface to the message implementation while making the underlying storage mechanism replaceable and optimizable as releases go forward. This all leads to simplification of the implementation while remaining source-compatible as far as the interface is concerned. Unfortunately all the interfaces will change, but hopefully majority of the users will not have to change their usage of the library. --- boost/network/constants.hpp | 2 - boost/network/message.hpp | 3 - .../directives/detail/string_directive.hpp | 2 - boost/network/message/directives/header.hpp | 3 - .../message/directives/remove_header.hpp | 3 - .../network/message/modifiers/add_header.hpp | 2 - boost/network/message/modifiers/body.hpp | 1 - .../message/modifiers/clear_headers.hpp | 2 - .../network/message/modifiers/destination.hpp | 1 - .../message/modifiers/remove_header.hpp | 2 - boost/network/message/modifiers/source.hpp | 2 - boost/network/message/traits/body.hpp | 2 - boost/network/message/traits/destination.hpp | 2 - boost/network/message/traits/headers.hpp | 4 - boost/network/message/traits/source.hpp | 2 - boost/network/message/wrappers/body.hpp | 1 - .../network/message/wrappers/destination.hpp | 3 - boost/network/message/wrappers/headers.hpp | 2 - boost/network/message/wrappers/source.hpp | 4 - boost/network/protocol/http/client.hpp | 121 +++++------- .../http/client/connection/ssl_delegate.hpp | 2 - boost/network/protocol/http/client/pimpl.hpp | 3 - boost/network/protocol/http/client_fwd.hpp | 10 +- boost/network/protocol/http/errors.hpp | 10 +- boost/network/protocol/http/impl/response.ipp | 3 - boost/network/protocol/http/message.hpp | 147 --------------- .../http/message/directives/status.hpp | 2 - .../message/directives/status_message.hpp | 1 - .../protocol/http/message/directives/uri.hpp | 1 - .../http/message/directives/version.hpp | 1 - .../network/protocol/http/message/header.hpp | 62 +++--- .../protocol/http/message/message_base.hpp | 3 - .../protocol/http/message/modifiers/body.hpp | 3 - .../http/message/modifiers/clear_headers.hpp | 3 - .../http/message/modifiers/destination.hpp | 3 - .../http/message/modifiers/headers.hpp | 1 - .../http/message/modifiers/method.hpp | 1 - .../http/message/modifiers/source.hpp | 3 - .../http/message/modifiers/status.hpp | 1 - .../http/message/modifiers/status_message.hpp | 1 - .../protocol/http/message/modifiers/uri.hpp | 1 - .../http/message/modifiers/version.hpp | 2 - .../protocol/http/message/traits/status.hpp | 2 - .../http/message/traits/status_message.hpp | 4 - .../protocol/http/message/traits/version.hpp | 4 - .../http/message/wrappers/headers.hpp | 3 - .../http/policies/async_connection.ipp | 63 ++++++- .../protocol/http/policies/async_resolver.hpp | 104 +++------- .../http/policies/pooled_connection.hpp | 177 ------------------ .../http/policies/simple_connection.hpp | 117 ------------ .../protocol/http/policies/sync_resolver.hpp | 86 --------- boost/network/protocol/http/request.hpp | 39 ++-- boost/network/protocol/http/response.hpp | 1 - .../protocol/http/support/is_client.hpp | 1 - .../protocol/http/support/is_server.hpp | 1 - boost/network/protocol/http/tags.hpp | 50 ----- boost/network/protocol/http/traits.hpp | 18 -- .../http/traits/connection_keepalive.hpp | 24 --- .../http/traits/connection_policy.hpp | 55 ------ .../protocol/http/traits/delegate_factory.hpp | 39 ---- .../protocol/http/traits/impl/chunk_cache.ipp | 36 ---- .../protocol/http/traits/impl/content.ipp | 44 ----- .../protocol/http/traits/impl/cookie_name.ipp | 26 --- .../http/traits/impl/cookie_value.ipp | 26 --- .../http/traits/impl/cookies_container.ipp | 32 ---- .../protocol/http/traits/impl/delimiters.ipp | 40 ---- .../protocol/http/traits/impl/header_name.ipp | 26 --- .../http/traits/impl/header_value.ipp | 26 --- .../protocol/http/traits/impl/headers.ipp | 85 --------- .../http/traits/impl/headers_container.ipp | 45 ----- .../protocol/http/traits/impl/method.ipp | 28 --- .../http/traits/impl/post_content.ipp | 26 --- .../http/traits/impl/query_container.ipp | 31 --- .../protocol/http/traits/impl/query_name.ipp | 26 --- .../http/traits/impl/query_string.ipp | 26 --- .../protocol/http/traits/impl/query_value.ipp | 26 --- .../http/traits/impl/request_methods.ipp | 49 ----- .../protocol/http/traits/impl/resource.ipp | 26 --- .../http/traits/impl/response_code.ipp | 42 ----- .../http/traits/impl/response_message.ipp | 80 -------- .../http/traits/impl/status_message.ipp | 27 --- .../protocol/http/traits/message_traits.hpp | 63 ------- .../protocol/http/traits/parser_traits.hpp | 70 ------- .../network/protocol/http/traits/resolver.hpp | 60 ------ .../protocol/http/traits/resolver_policy.hpp | 41 ---- boost/network/protocol/http/traits/vector.hpp | 38 ---- boost/network/support/is_async.hpp | 25 --- boost/network/support/is_default_string.hpp | 24 --- boost/network/support/is_default_wstring.hpp | 24 --- boost/network/support/is_http.hpp | 24 --- boost/network/support/is_keepalive.hpp | 24 --- boost/network/support/is_pod.hpp | 24 --- boost/network/support/is_simple.hpp | 24 --- boost/network/support/is_sync.hpp | 25 --- boost/network/support/is_tcp.hpp | 26 --- boost/network/support/is_udp.hpp | 27 --- boost/network/support/pod_or_normal.hpp | 25 --- boost/network/support/sync_only.hpp | 33 ---- boost/network/tags.hpp | 52 ----- boost/network/traits/char.hpp | 39 ---- boost/network/traits/headers_container.hpp | 28 --- boost/network/traits/istream.hpp | 42 ----- boost/network/traits/istringstream.hpp | 44 ----- boost/network/traits/ostream_iterator.hpp | 37 ---- boost/network/traits/ostringstream.hpp | 44 ----- boost/network/traits/string.hpp | 52 ----- boost/network/traits/vector.hpp | 36 ---- boost/network/uri/uri.hpp | 1 - 108 files changed, 188 insertions(+), 2753 deletions(-) delete mode 100644 boost/network/protocol/http/message.hpp delete mode 100644 boost/network/protocol/http/policies/pooled_connection.hpp delete mode 100644 boost/network/protocol/http/policies/simple_connection.hpp delete mode 100644 boost/network/protocol/http/policies/sync_resolver.hpp delete mode 100644 boost/network/protocol/http/tags.hpp delete mode 100644 boost/network/protocol/http/traits.hpp delete mode 100644 boost/network/protocol/http/traits/connection_keepalive.hpp delete mode 100644 boost/network/protocol/http/traits/connection_policy.hpp delete mode 100644 boost/network/protocol/http/traits/delegate_factory.hpp delete mode 100644 boost/network/protocol/http/traits/impl/chunk_cache.ipp delete mode 100644 boost/network/protocol/http/traits/impl/content.ipp delete mode 100644 boost/network/protocol/http/traits/impl/cookie_name.ipp delete mode 100644 boost/network/protocol/http/traits/impl/cookie_value.ipp delete mode 100644 boost/network/protocol/http/traits/impl/cookies_container.ipp delete mode 100644 boost/network/protocol/http/traits/impl/delimiters.ipp delete mode 100644 boost/network/protocol/http/traits/impl/header_name.ipp delete mode 100644 boost/network/protocol/http/traits/impl/header_value.ipp delete mode 100644 boost/network/protocol/http/traits/impl/headers.ipp delete mode 100644 boost/network/protocol/http/traits/impl/headers_container.ipp delete mode 100644 boost/network/protocol/http/traits/impl/method.ipp delete mode 100644 boost/network/protocol/http/traits/impl/post_content.ipp delete mode 100644 boost/network/protocol/http/traits/impl/query_container.ipp delete mode 100644 boost/network/protocol/http/traits/impl/query_name.ipp delete mode 100644 boost/network/protocol/http/traits/impl/query_string.ipp delete mode 100644 boost/network/protocol/http/traits/impl/query_value.ipp delete mode 100644 boost/network/protocol/http/traits/impl/request_methods.ipp delete mode 100644 boost/network/protocol/http/traits/impl/resource.ipp delete mode 100644 boost/network/protocol/http/traits/impl/response_code.ipp delete mode 100644 boost/network/protocol/http/traits/impl/response_message.ipp delete mode 100644 boost/network/protocol/http/traits/impl/status_message.ipp delete mode 100644 boost/network/protocol/http/traits/message_traits.hpp delete mode 100644 boost/network/protocol/http/traits/parser_traits.hpp delete mode 100644 boost/network/protocol/http/traits/resolver.hpp delete mode 100644 boost/network/protocol/http/traits/resolver_policy.hpp delete mode 100644 boost/network/protocol/http/traits/vector.hpp delete mode 100644 boost/network/support/is_async.hpp delete mode 100644 boost/network/support/is_default_string.hpp delete mode 100644 boost/network/support/is_default_wstring.hpp delete mode 100644 boost/network/support/is_http.hpp delete mode 100644 boost/network/support/is_keepalive.hpp delete mode 100644 boost/network/support/is_pod.hpp delete mode 100644 boost/network/support/is_simple.hpp delete mode 100644 boost/network/support/is_sync.hpp delete mode 100644 boost/network/support/is_tcp.hpp delete mode 100644 boost/network/support/is_udp.hpp delete mode 100644 boost/network/support/pod_or_normal.hpp delete mode 100644 boost/network/support/sync_only.hpp delete mode 100644 boost/network/tags.hpp delete mode 100644 boost/network/traits/char.hpp delete mode 100644 boost/network/traits/headers_container.hpp delete mode 100644 boost/network/traits/istream.hpp delete mode 100644 boost/network/traits/istringstream.hpp delete mode 100644 boost/network/traits/ostream_iterator.hpp delete mode 100644 boost/network/traits/ostringstream.hpp delete mode 100644 boost/network/traits/string.hpp delete mode 100644 boost/network/traits/vector.hpp diff --git a/boost/network/constants.hpp b/boost/network/constants.hpp index f2b100760..3f03d6d6c 100644 --- a/boost/network/constants.hpp +++ b/boost/network/constants.hpp @@ -6,8 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include namespace boost { namespace network { diff --git a/boost/network/message.hpp b/boost/network/message.hpp index 190018b67..fcddc7e1b 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -7,9 +7,6 @@ #define __NETWORK_MESSAGE_HPP__ #include -#include -#include -#include #include #include #include diff --git a/boost/network/message/directives/detail/string_directive.hpp b/boost/network/message/directives/detail/string_directive.hpp index 6f2da4430..885777da4 100644 --- a/boost/network/message/directives/detail/string_directive.hpp +++ b/boost/network/message/directives/detail/string_directive.hpp @@ -6,11 +6,9 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include -#include #include #include #include diff --git a/boost/network/message/directives/header.hpp b/boost/network/message/directives/header.hpp index e20c95cd9..182d643d3 100644 --- a/boost/network/message/directives/header.hpp +++ b/boost/network/message/directives/header.hpp @@ -7,9 +7,6 @@ #ifndef __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ #define __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ -#include -#include -#include #include #include #include diff --git a/boost/network/message/directives/remove_header.hpp b/boost/network/message/directives/remove_header.hpp index 051d35f78..16d863e15 100644 --- a/boost/network/message/directives/remove_header.hpp +++ b/boost/network/message/directives/remove_header.hpp @@ -8,9 +8,6 @@ #define NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP -#include - - namespace boost { namespace network { template diff --git a/boost/network/message/modifiers/add_header.hpp b/boost/network/message/modifiers/add_header.hpp index f92e9c21f..c93fe2edb 100644 --- a/boost/network/message/modifiers/add_header.hpp +++ b/boost/network/message/modifiers/add_header.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/modifiers/body.hpp b/boost/network/message/modifiers/body.hpp index 317264c68..f9b595818 100644 --- a/boost/network/message/modifiers/body.hpp +++ b/boost/network/message/modifiers/body.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { diff --git a/boost/network/message/modifiers/clear_headers.hpp b/boost/network/message/modifiers/clear_headers.hpp index b44ff1207..a983b695a 100644 --- a/boost/network/message/modifiers/clear_headers.hpp +++ b/boost/network/message/modifiers/clear_headers.hpp @@ -6,8 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/modifiers/destination.hpp b/boost/network/message/modifiers/destination.hpp index b04b07129..8ff362e08 100644 --- a/boost/network/message/modifiers/destination.hpp +++ b/boost/network/message/modifiers/destination.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { diff --git a/boost/network/message/modifiers/remove_header.hpp b/boost/network/message/modifiers/remove_header.hpp index c2ab29bf1..e7b098875 100644 --- a/boost/network/message/modifiers/remove_header.hpp +++ b/boost/network/message/modifiers/remove_header.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/modifiers/source.hpp b/boost/network/message/modifiers/source.hpp index fad8c00f3..11acb9071 100644 --- a/boost/network/message/modifiers/source.hpp +++ b/boost/network/message/modifiers/source.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - namespace boost { namespace network { namespace impl { diff --git a/boost/network/message/traits/body.hpp b/boost/network/message/traits/body.hpp index 25cb14961..5d539d7f4 100644 --- a/boost/network/message/traits/body.hpp +++ b/boost/network/message/traits/body.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/traits/destination.hpp b/boost/network/message/traits/destination.hpp index 92c5435ad..39da83de9 100644 --- a/boost/network/message/traits/destination.hpp +++ b/boost/network/message/traits/destination.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/traits/headers.hpp b/boost/network/message/traits/headers.hpp index e1d34abe8..a51023675 100644 --- a/boost/network/message/traits/headers.hpp +++ b/boost/network/message/traits/headers.hpp @@ -7,10 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include #include #include #include diff --git a/boost/network/message/traits/source.hpp b/boost/network/message/traits/source.hpp index 231a5e0d3..9d2237e1e 100644 --- a/boost/network/message/traits/source.hpp +++ b/boost/network/message/traits/source.hpp @@ -6,8 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index 507d87e07..b2199eca7 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -7,7 +7,6 @@ #ifndef __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ -#include #include #include diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index 935e9c101..f1c485269 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -8,9 +8,6 @@ #define __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ -#include - - namespace boost { namespace network { namespace impl { diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index 37a2e611c..ce2e0bf25 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -7,8 +7,6 @@ #ifndef __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ -#include -#include #include #include #include diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 42579895c..378e80628 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -7,10 +7,6 @@ #ifndef __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ - -#include - - namespace boost { namespace network { namespace impl { diff --git a/boost/network/protocol/http/client.hpp b/boost/network/protocol/http/client.hpp index 9fdf0eeee..2d45ff2df 100644 --- a/boost/network/protocol/http/client.hpp +++ b/boost/network/protocol/http/client.hpp @@ -7,86 +7,63 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include namespace boost { namespace network { namespace http { - template - struct basic_client - : basic_client_facade - { - private: - typedef basic_client_facade - base_facade_type; - public: - typedef basic_request request; - typedef basic_response response; - typedef typename string::type string_type; - typedef Tag tag_type; - - // Constructor - // ================================================================= - // This is a Boost.Parameter-based constructor forwarder, whose - // implementation is actually forwarded to the base type. - // - // The supported parameters are: - // _follow_redirects : bool -- whether to follow HTTP redirect - // responses (default: false) - // _cache_resolved : bool -- whether to cache the resolved - // endpoints (default: false) - // _io_service : boost::asio::io_service & - // -- supply an io_service to the - // client - // _openssl_certificate : string - // -- the name of the certificate file - // to use - // _openssl_verify_path : string - // -- the name of the directory from - // which the certificate authority - // files can be found - // _connection_manager : shared_ptr - // -- The connection manager to use for - // this client. - - BOOST_PARAMETER_CONSTRUCTOR( - basic_client, (base_facade_type), tag, - (optional - (in_out(io_service), (boost::asio::io_service&)) - (follow_redirects, (bool)) - (cache_resolved, (bool)) - (openssl_certificate, (string_type)) - (openssl_verify_path, (string_type)) - (connection_manager, (shared_ptr)) - )) - - // - // ================================================================= - - }; - -#ifndef BOOST_NETWORK_HTTP_CLIENT_DEFAULT_TAG -#define BOOST_NETWORK_HTTP_CLIENT_DEFAULT_TAG tags::http_async_8bit_udp_resolve -#endif - - typedef basic_client client; +template +struct basic_client : basic_client_facade { + private: + typedef basic_client_facade + base_facade_type; + public: + typedef basic_request request; + typedef basic_response response; + typedef String string_type; + + // Constructor + // ================================================================= + // This is a Boost.Parameter-based constructor forwarder, whose + // implementation is actually forwarded to the base type. + // + // The supported parameters are: + // _follow_redirects : bool -- whether to follow HTTP redirect + // responses (default: false) + // _cache_resolved : bool -- whether to cache the resolved + // endpoints (default: false) + // _io_service : boost::asio::io_service & + // -- supply an io_service to the + // client + // _openssl_certificate : string + // -- the name of the certificate file + // to use + // _openssl_verify_path : string + // -- the name of the directory from + // which the certificate authority + // files can be found + // _connection_manager : shared_ptr + // -- The connection manager to use for + // this client. + + BOOST_PARAMETER_CONSTRUCTOR( + basic_client, (base_facade_type), tag, + (optional + (in_out(io_service), (boost::asio::io_service&)) + (follow_redirects, (bool)) + (cache_resolved, (bool)) + (openssl_certificate, (string_type)) + (openssl_verify_path, (string_type)) + (connection_manager, (shared_ptr)) + )) + + // + // ================================================================= + +}; } // namespace http diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.hpp b/boost/network/protocol/http/client/connection/ssl_delegate.hpp index a1cb9a0c6..d07281df7 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.hpp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.hpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include namespace boost { namespace network { namespace http { namespace impl { diff --git a/boost/network/protocol/http/client/pimpl.hpp b/boost/network/protocol/http/client/pimpl.hpp index 55df10f57..2f0cab2af 100644 --- a/boost/network/protocol/http/client/pimpl.hpp +++ b/boost/network/protocol/http/client/pimpl.hpp @@ -6,14 +6,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include #include -#include #include #include diff --git a/boost/network/protocol/http/client_fwd.hpp b/boost/network/protocol/http/client_fwd.hpp index c57ad70cc..de67671f7 100644 --- a/boost/network/protocol/http/client_fwd.hpp +++ b/boost/network/protocol/http/client_fwd.hpp @@ -8,15 +8,15 @@ #define __NETWORK_PROTOCOL_HTTP_CLIENT_20080923_1_HPP__ #include -#include +#include namespace boost { namespace network { namespace http { - //! Forward declaration of basic_client template. - template - class basic_client; +//! Forward declaration of basic_client template. +template +class basic_client; - typedef basic_client client; +typedef basic_client client; } // namespace http diff --git a/boost/network/protocol/http/errors.hpp b/boost/network/protocol/http/errors.hpp index 70952e3ec..dff069d36 100644 --- a/boost/network/protocol/http/errors.hpp +++ b/boost/network/protocol/http/errors.hpp @@ -7,18 +7,14 @@ #ifndef __NETWORK_PROTOCOL_HTTP_ERRORS_20080516_HPP__ #define __NETWORK_PROTOCOL_HTTP_ERRORS_20080516_HPP__ -#include #include namespace boost { namespace network { namespace http { namespace errors { - template - struct connection_timeout_exception : - std::runtime_error - { - }; +struct connection_timeout_exception : std::runtime_error +{}; - typedef connection_timeout_exception<> connection_timeout; +typedef connection_timeout_exception connection_timeout; } // namespace errors diff --git a/boost/network/protocol/http/impl/response.ipp b/boost/network/protocol/http/impl/response.ipp index 2eb669dba..0708575e8 100644 --- a/boost/network/protocol/http/impl/response.ipp +++ b/boost/network/protocol/http/impl/response.ipp @@ -16,9 +16,6 @@ #include #include -#include -#include -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message.hpp b/boost/network/protocol/http/message.hpp deleted file mode 100644 index b7256c9d1..000000000 --- a/boost/network/protocol/http/message.hpp +++ /dev/null @@ -1,147 +0,0 @@ -// This file is part of the Boost Network library -// Based on the Pion Network Library (r421) -// Copyright Atomic Labs, Inc. 2007-2008 -// See http://cpp-netlib.sourceforge.net for library home page. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// Some changes Copyright (c) Dean Michael Berris 2008 - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - /// base class for HTTP messages (requests and responses) - template - struct message_impl : public basic_message { - - typedef typename string::type string_type; - - /// escapes URL-encoded strings (a%20value+with%20spaces) - static string_type const url_decode(string_type const & str); - - /// encodes strings so that they are safe for URLs (with%20spaces) - static string_type const url_encode(string_type const & str); - - /// builds an HTTP query string from a collection of query parameters - static string_type const make_query_string(typename query_container::type const & query_params); - - /** - * creates a "Set-Cookie" header - * - * @param name the name of the cookie - * @param value the value of the cookie - * @param path the path of the cookie - * @param has_max_age true if the max_age value should be set - * @param max_age the life of the cookie, in seconds (0 = discard) - * - * @return the new "Set-Cookie" header - */ - static string_type const make_set_cookie_header(string_type const & name, - string_type const & value, - string_type const & path, - bool const has_max_age = false, - unsigned long const max_age = 0); - - /** decodes base64-encoded strings - * - * @param input base64 encoded string - * @param output decoded string ( may include non-text chars) - * @return true if successful, false if input string contains non-base64 symbols - */ - static bool const base64_decode(string_type const &input, string_type & output); - - /** encodes strings using base64 - * - * @param input arbitrary string ( may include non-text chars) - * @param output base64 encoded string - * @return true if successful - */ - static bool const base64_encode(string_type const &input, string_type & output); - - protected: - mutable string_type version_; - mutable boost::uint16_t status_; - mutable string_type status_message_; - - private: - typedef basic_message base_type; - - public: - - message_impl() - : base_type(), version_(), status_(0u), status_message_() - {} - - message_impl(message_impl const & other) - : base_type(other), version_(other.version_), status_(other.status_), status_message_(other.status_message_) - {} - - void version(string_type const & version) const { - version_ = version; - } - - string_type const version() const { - return version_; - } - - void status(boost::uint16_t status) const { - status_ = status; - } - - boost::uint16_t const status() const { - return status_; - } - - void status_message(string_type const & status_message) const { - status_message_ = status_message; - } - - string_type const status_message() const { - return status_message_; - } - - message_impl & operator=(message_impl rhs) { - rhs.swap(*this); - return *this; - } - - void swap(message_impl & other) { - base_type & base_ref(other), - & this_ref(*this); - std::swap(this_ref, base_ref); - std::swap(status_, other.status_); - std::swap(status_message_, other.status_message_); - std::swap(version_, other.version_); - } - - }; - - template - inline void swap(message_impl & lhs, message_impl & rhs) { - lhs.swap(rhs); - } - - typedef message_impl message; - -} // namespace http - -} // namespace network - -} // namespace boost - -// import implementation file -#include - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP diff --git a/boost/network/protocol/http/message/directives/status.hpp b/boost/network/protocol/http/message/directives/status.hpp index 2f3b3916c..bfd68354c 100644 --- a/boost/network/protocol/http/message/directives/status.hpp +++ b/boost/network/protocol/http/message/directives/status.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include diff --git a/boost/network/protocol/http/message/directives/status_message.hpp b/boost/network/protocol/http/message/directives/status_message.hpp index 93463990b..3ac16d06b 100644 --- a/boost/network/protocol/http/message/directives/status_message.hpp +++ b/boost/network/protocol/http/message/directives/status_message.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/directives/uri.hpp b/boost/network/protocol/http/message/directives/uri.hpp index f5fe4a7d1..1ae91a53e 100644 --- a/boost/network/protocol/http/message/directives/uri.hpp +++ b/boost/network/protocol/http/message/directives/uri.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/directives/version.hpp b/boost/network/protocol/http/message/directives/version.hpp index f3eedf0ef..88f2d1c5a 100644 --- a/boost/network/protocol/http/message/directives/version.hpp +++ b/boost/network/protocol/http/message/directives/version.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/header.hpp b/boost/network/protocol/http/message/header.hpp index 22de2a728..052ece94b 100644 --- a/boost/network/protocol/http/message/header.hpp +++ b/boost/network/protocol/http/message/header.hpp @@ -13,16 +13,16 @@ #ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 #define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 -#include +#include +#include +#include #include #include -#include -#include namespace boost { namespace network { namespace http { - template - struct unsupported_tag; + template + struct unsupported_string; struct request_header_narrow { typedef std::string string_type; @@ -34,18 +34,20 @@ namespace boost { namespace network { namespace http { std::wstring name, value; }; - template - struct request_header - : mpl::if_< - is_default_string, - request_header_narrow, - typename mpl::if_< - is_default_wstring, - request_header_wide, - unsupported_tag - >::type - > - {}; + template + struct request_header { + typedef unsupported_string type; + }; + + template + struct request_header >::type> { + typedef request_header_narrow type; + }; + + template + struct request_header >::type> { + typedef request_header_wide type; + }; inline void swap(request_header_narrow & l, request_header_narrow & r) { swap(l.name, r.name); @@ -67,18 +69,20 @@ namespace boost { namespace network { namespace http { std::wstring name, value; }; - template - struct response_header - : mpl::if_< - is_default_string, - response_header_narrow, - typename mpl::if_< - is_default_wstring, - response_header_wide, - unsupported_tag - >::type - > - {}; + template + struct response_header { + typedef unsupported_string type; + }; + + template + struct response_header >::type> { + typedef response_header_wide type; + }; + + template + struct response_header >::type> { + typedef response_header_narrow type; + }; inline void swap(response_header_narrow & l, response_header_narrow & r) { std::swap(l.name, r.name); diff --git a/boost/network/protocol/http/message/message_base.hpp b/boost/network/protocol/http/message/message_base.hpp index 885d74dbb..bc27bd03c 100644 --- a/boost/network/protocol/http/message/message_base.hpp +++ b/boost/network/protocol/http/message/message_base.hpp @@ -7,9 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include - namespace boost { namespace network { namespace http { template diff --git a/boost/network/protocol/http/message/modifiers/body.hpp b/boost/network/protocol/http/message/modifiers/body.hpp index d88961dd3..40523b4ea 100644 --- a/boost/network/protocol/http/message/modifiers/body.hpp +++ b/boost/network/protocol/http/message/modifiers/body.hpp @@ -6,9 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include #include #include #include diff --git a/boost/network/protocol/http/message/modifiers/clear_headers.hpp b/boost/network/protocol/http/message/modifiers/clear_headers.hpp index 33e9f5854..8cf2806aa 100644 --- a/boost/network/protocol/http/message/modifiers/clear_headers.hpp +++ b/boost/network/protocol/http/message/modifiers/clear_headers.hpp @@ -6,9 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/destination.hpp b/boost/network/protocol/http/message/modifiers/destination.hpp index f0532abba..d67958653 100644 --- a/boost/network/protocol/http/message/modifiers/destination.hpp +++ b/boost/network/protocol/http/message/modifiers/destination.hpp @@ -6,9 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include #include #include diff --git a/boost/network/protocol/http/message/modifiers/headers.hpp b/boost/network/protocol/http/message/modifiers/headers.hpp index d789a7452..9bfcec4fc 100644 --- a/boost/network/protocol/http/message/modifiers/headers.hpp +++ b/boost/network/protocol/http/message/modifiers/headers.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include diff --git a/boost/network/protocol/http/message/modifiers/method.hpp b/boost/network/protocol/http/message/modifiers/method.hpp index 52afe2696..bc23dc78d 100644 --- a/boost/network/protocol/http/message/modifiers/method.hpp +++ b/boost/network/protocol/http/message/modifiers/method.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/source.hpp b/boost/network/protocol/http/message/modifiers/source.hpp index 0f4df485d..4fa537b6a 100644 --- a/boost/network/protocol/http/message/modifiers/source.hpp +++ b/boost/network/protocol/http/message/modifiers/source.hpp @@ -6,11 +6,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/status.hpp b/boost/network/protocol/http/message/modifiers/status.hpp index 5e541f95f..dfcd305e8 100644 --- a/boost/network/protocol/http/message/modifiers/status.hpp +++ b/boost/network/protocol/http/message/modifiers/status.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/status_message.hpp b/boost/network/protocol/http/message/modifiers/status_message.hpp index 8149e6575..bcd92bcb8 100644 --- a/boost/network/protocol/http/message/modifiers/status_message.hpp +++ b/boost/network/protocol/http/message/modifiers/status_message.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/uri.hpp b/boost/network/protocol/http/message/modifiers/uri.hpp index aaa198ea3..e96525df5 100644 --- a/boost/network/protocol/http/message/modifiers/uri.hpp +++ b/boost/network/protocol/http/message/modifiers/uri.hpp @@ -7,7 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/version.hpp b/boost/network/protocol/http/message/modifiers/version.hpp index e0b267c71..0077ca4f6 100644 --- a/boost/network/protocol/http/message/modifiers/version.hpp +++ b/boost/network/protocol/http/message/modifiers/version.hpp @@ -7,8 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include diff --git a/boost/network/protocol/http/message/traits/status.hpp b/boost/network/protocol/http/message/traits/status.hpp index 2eabedea8..2ff22dcae 100644 --- a/boost/network/protocol/http/message/traits/status.hpp +++ b/boost/network/protocol/http/message/traits/status.hpp @@ -6,9 +6,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include -#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/traits/status_message.hpp b/boost/network/protocol/http/message/traits/status_message.hpp index 8469c01ff..9b0a47ccf 100644 --- a/boost/network/protocol/http/message/traits/status_message.hpp +++ b/boost/network/protocol/http/message/traits/status_message.hpp @@ -6,10 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include - namespace boost { namespace network { namespace http { namespace traits { diff --git a/boost/network/protocol/http/message/traits/version.hpp b/boost/network/protocol/http/message/traits/version.hpp index 15ac4e848..748bb71c6 100644 --- a/boost/network/protocol/http/message/traits/version.hpp +++ b/boost/network/protocol/http/message/traits/version.hpp @@ -6,10 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include #include #include diff --git a/boost/network/protocol/http/message/wrappers/headers.hpp b/boost/network/protocol/http/message/wrappers/headers.hpp index 69447d30b..0b9a13b13 100644 --- a/boost/network/protocol/http/message/wrappers/headers.hpp +++ b/boost/network/protocol/http/message/wrappers/headers.hpp @@ -7,9 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include - namespace boost { namespace network { namespace http { template diff --git a/boost/network/protocol/http/policies/async_connection.ipp b/boost/network/protocol/http/policies/async_connection.ipp index d638688bd..2fbc15f31 100644 --- a/boost/network/protocol/http/policies/async_connection.ipp +++ b/boost/network/protocol/http/policies/async_connection.ipp @@ -18,12 +18,11 @@ struct simple_async_client_connection : client_connection { bool get_body, callback_type callback); // override virtual void reset(); // override - virtual ~client_connection(); // override + virtual ~simple_async_client_connection(); // override protected: bool follow_redirects_; shared_ptr resolver_delegate_; shared_ptr connection_delegate_; - shared_ptr connection_; }; simple_async_client_connection::simple_async_client_connection( @@ -35,10 +34,11 @@ simple_async_client_connection::simple_async_client_connection( connection_delegate_(connection_delegate), {} -shared_ptr send_request(std::string const & method, - request_base const & request, - bool get_body, - callback_type callback) { +shared_ptr simple_async_client_connection::send_request( + std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) { shared_ptr response; shared_ptr connection_; connection_.reset(new(std::nothrow) impl::async_connection( @@ -51,6 +51,12 @@ shared_ptr send_request(std::string const & method, return response } +void simple_async_client_connection::reset() { + // Do nothing here +} + +simple_async_client_connection::~simple_async_client_connection() {} + } /* http */ } /* network */ } /* boost */ @@ -113,9 +119,52 @@ namespace boost { namespace network { namespace http { struct http_1_1_async_connection : client_connection { http_1_1_async_connection(bool follow_redirects, shared_ptr resolver_delegate, - shared_ptr connection_delegate) + shared_ptr connection_delegate); + virtual shared_ptr send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback); //override + virtual void reset(); // override + virtual ~http_1_1_async_connection(); // override + protected: + bool follow_redirects_; + shared_ptr resolver_delegate_; + shared_ptr connection_delegate_; + shared_ptr connection_; +}; + +http_1_1_async_connection::http_1_1_async_connection( + bool follow_redirects, + shared_ptr resolver_delegate, + shared_ptr connection_delegate) +: follow_redirects_(follow_redirects), + resolver_delegate_(resolver_delegate), + connection_delegate_(connection_delegate) +{ + connection_.reset(new(std::nothrow) impl::async_connection( + resolver_delegate_, + follow_redirects_, + connection_delegate_)) +} + +shared_ptr http_1_1_async_connection::send_request( + std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) { + if (!connection_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Insufficient memory.")); + response = connection_->start(request, method, get_body, callback); + return response; } +void http_1_1_async_connection::reset() { + connection_.reset(); +} + +http_1_1_async_connection::~http_1_1_async_connection() +{} + } /* http */ } /* network */ } /* boost */ diff --git a/boost/network/protocol/http/policies/async_resolver.hpp b/boost/network/protocol/http/policies/async_resolver.hpp index 12745c0e0..c7cacfbdf 100644 --- a/boost/network/protocol/http/policies/async_resolver.hpp +++ b/boost/network/protocol/http/policies/async_resolver.hpp @@ -1,95 +1,37 @@ #ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 #define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 -// Copyright Dean Michael Berris 2010. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include +#include +#include +#include namespace boost { namespace network { namespace http { namespace policies { -struct async_resolver : enable_shared_from_this { - typedef asio::ip::resolver::iterator resolver_iterator; - typedef asio::ip::resolver::query resolver_query; - typedef std::pair resolver_iterator_pair; - typedef boost::unordered_map endpoint_cache; - typedef boost::function resolve_completion_function; - typedef boost::function resolve_function; - protected: - bool cache_resolved_; - endpoint_cache endpoint_cache_; - boost::shared_ptr resolver_strand_; - - async_resolver(bool cache_resolved): - cache_resolved_(cache_resolved), - endpoint_cache_() - {} - - void resolve( - resolver_type & resolver_, - std::string const & host, - boost::uint16_t port, - resolve_completion_function once_resolved) { - if (cache_resolved_) { - typename endpoint_cache::iterator iter = - endpoint_cache_.find(boost::to_lower_copy(host)); - if (iter != endpoint_cache_.end()) { - boost::system::error_code ignored; - once_resolved(ignored, iter->second); - return; - } - } +struct async_resolver_pimpl; - typename resolver_type::query q( - resolver_type::protocol_type::v4() - , host - , lexical_cast(port)); - resolver_.async_resolve( - q, - resolver_strand_->wrap( - boost::bind( - &async_resolver::handle_resolve, - async_resolver::shared_from_this(), - boost::to_lower_copy(host), - once_resolved, - boost::asio::placeholders::error, - boost::asio::placeholders::iterator - ) - ) - ); - } +struct async_resolver { + typedef asio::ip::udp::resolver::iterator resolver_iterator; + typedef std::pair + iterator_pair; + typedef function + resolve_completion_function; - void handle_resolve( - std::string const & host, - resolve_completion_function once_resolved, - boost::system::error_code const & ec, - resolver_iterator endpoint_iterator - ) - { - typename endpoint_cache::iterator iter; - bool inserted = false; - if (!ec && cache_resolved_) { - boost::fusion::tie(iter, inserted) = - endpoint_cache_.insert( - std::make_pair( - host, - std::make_pair( - endpoint_iterator, - resolver_iterator() - ) - ) - ); - once_resolved(ec, iter->second); - } else { - once_resolved(ec, std::make_pair(endpoint_iterator,resolver_iterator())); - } - } + explicit async_resolver(asio::io_service & service); + void resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved); + void clear_resolved_cache(); + ~async_resolver(); - }; + protected: + shared_ptr pimpl; +}; } // namespace policies @@ -99,4 +41,8 @@ struct async_resolver : enable_shared_from_this { } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 diff --git a/boost/network/protocol/http/policies/pooled_connection.hpp b/boost/network/protocol/http/policies/pooled_connection.hpp deleted file mode 100644 index 31be06f8e..000000000 --- a/boost/network/protocol/http/policies/pooled_connection.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT -#define BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT 5 -#endif // BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT - -namespace boost { namespace network { namespace http { - - template - struct pooled_connection_policy : resolver_policy::type { - protected: - - typedef typename string::type string_type; - typedef typename resolver_policy::type resolver_base; - typedef typename resolver_base::resolver_type resolver_type; - typedef function resolver_function_type; - typedef function const &, system::error_code const &)> body_callback_function_type; - - void cleanup() { - host_connection_map().swap(host_connections); - } - - struct connection_impl { - typedef function(resolver_type &,basic_request const &,optional const &, optional const &)> get_connection_function; - - connection_impl(resolver_type & resolver, bool follow_redirect, string_type const & host, string_type const & port, resolver_function_type resolve, get_connection_function get_connection, bool https, optional const & certificate_file=optional(), optional const & verify_path=optional()) - : pimpl(impl::sync_connection_base::new_connection(resolver, resolve, https, certificate_file, verify_path)) - , resolver_(resolver) - , connection_follow_redirect_(follow_redirect) - , get_connection_(get_connection) - , certificate_filename_(certificate_file) - , verify_path_(verify_path) - {} - - basic_response send_request(string_type const & method, basic_request request_, bool get_body, body_callback_function_type callback) { - return send_request_impl(method, request_, get_body); - } - - private: - - basic_response send_request_impl(string_type const & method, basic_request request_, bool get_body) { - boost::uint8_t count = 0; - bool retry = false; - do { - if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT) - boost::throw_exception(std::runtime_error("Redirection exceeds maximum redirect count.")); - - basic_response response_; - // check if the socket is open first - if (!pimpl->is_open()) { - pimpl->init_socket(request_.host(), lexical_cast(request_.port())); - } - response_ = basic_response(); - response_ << ::boost::network::source(request_.host()); - - pimpl->send_request_impl(method, request_); - boost::asio::streambuf response_buffer; - - try { - pimpl->read_status(response_, response_buffer); - } catch (boost::system::system_error & e) { - if (!retry && e.code() == boost::asio::error::eof) { - retry = true; - pimpl->init_socket(request_.host(), lexical_cast(request_.port())); - continue; - } - throw; // it's a retry, and there's something wrong. - } - - pimpl->read_headers(response_, response_buffer); - - if ( - get_body && response_.status() != 304 - && (response_.status() != 204) - && !(response_.status() >= 100 && response_.status() <= 199) - ) { - pimpl->read_body(response_, response_buffer); - } - - typename headers_range >::type connection_range = headers(response_)["Connection"]; - if (version_major == 1 && version_minor == 1 && !empty(connection_range) && boost::begin(connection_range)->second == string_type("close")) { - pimpl->close_socket(); - } else if (version_major == 1 && version_minor == 0) { - pimpl->close_socket(); - } - - if (connection_follow_redirect_) { - boost::uint16_t status = response_.status(); - if (status >= 300 && status <= 307) { - typename headers_range >::type location_range = headers(response_)["Location"]; - typename range_iterator >::type>::type location_header = boost::begin(location_range); - if (location_header != boost::end(location_range)) { - request_.uri(location_header->second); - connection_ptr connection_; - connection_ = get_connection_(resolver_, request_, certificate_filename_, verify_path_); - ++count; - continue; - } else boost::throw_exception(std::runtime_error("Location header not defined in redirect response.")); - } - } - return response_; - } while(true); - } - - shared_ptr > pimpl; - resolver_type & resolver_; - bool connection_follow_redirect_; - get_connection_function get_connection_; - optional certificate_filename_, verify_path_; - }; - - typedef shared_ptr connection_ptr; - - typedef unordered_map host_connection_map; - host_connection_map host_connections; - bool follow_redirect_; - - connection_ptr get_connection(resolver_type & resolver, basic_request const & request_, optional const & certificate_filename = optional(), optional const & verify_path = optional()) { - string_type index = (request_.host() + ':') + lexical_cast(request_.port()); - connection_ptr connection_; - typename host_connection_map::iterator it = - host_connections.find(index); - if (it == host_connections.end()) { - connection_.reset(new connection_impl( - resolver - , follow_redirect_ - , request_.host() - , lexical_cast(request_.port()) - , boost::bind( - &pooled_connection_policy::resolve, - this, - _1, _2, _3 - ) - , boost::bind( - &pooled_connection_policy::get_connection, - this, - _1, _2, _3, _4 - ) - , boost::iequals(request_.protocol(), string_type("https")) - , certificate_filename - , verify_path - ) - ); - host_connections.insert(std::make_pair(index, connection_)); - return connection_; - } - return it->second; - } - - pooled_connection_policy(bool cache_resolved, bool follow_redirect) - : resolver_base(cache_resolved), host_connections(), follow_redirect_(follow_redirect) {} - - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 - diff --git a/boost/network/protocol/http/policies/simple_connection.hpp b/boost/network/protocol/http/policies/simple_connection.hpp deleted file mode 100644 index 16d9fd1a8..000000000 --- a/boost/network/protocol/http/policies/simple_connection.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct simple_connection_policy : resolver_policy::type { - protected: - - typedef typename string::type string_type; - typedef typename resolver_policy::type resolver_base; - typedef typename resolver_base::resolver_type resolver_type; - typedef function resolver_function_type; - typedef function const &, system::error_code const &)> body_callback_function_type; - - struct connection_impl { - connection_impl(resolver_type & resolver, bool follow_redirect, string_type const & hostname, string_type const & port, resolver_function_type resolve, bool https, optional const & certificate_filename = optional(), optional const & verify_path = optional()) - : pimpl() - , follow_redirect_(follow_redirect) - { - pimpl.reset(impl::sync_connection_base::new_connection(resolver, resolve, https, certificate_filename, verify_path)); - } - - basic_response send_request(string_type const & method, basic_request request_, bool get_body, body_callback_function_type callback) { - basic_response response_; - do { - pimpl->init_socket(request_.host(), lexical_cast(request_.port())); - pimpl->send_request_impl(method, request_); - - response_ = basic_response(); - response_ << network::source(request_.host()); - - boost::asio::streambuf response_buffer; - pimpl->read_status(response_, response_buffer); - pimpl->read_headers(response_, response_buffer); - if (get_body) pimpl->read_body(response_, response_buffer); - - if (follow_redirect_) { - boost::uint16_t status = response_.status(); - if (status >= 300 && status <= 307) { - typename headers_range >::type location_range = headers(response_)["Location"]; - typename range_iterator >::type>::type location_header = boost::begin(location_range); - if (location_header != boost::end(location_range)) { - request_.uri(location_header->second); - } else throw std::runtime_error("Location header not defined in redirect response."); - } else break; - } else break; - } while(true); - return response_; - } - - private: - - shared_ptr > pimpl; - bool follow_redirect_; - - }; - - typedef boost::shared_ptr connection_ptr; - connection_ptr get_connection(resolver_type & resolver, basic_request const & request_ - , optional const & certificate_file = optional() - , optional const & verify_file = optional() - ) { - connection_ptr connection_( - new connection_impl( - resolver - , follow_redirect_ - , request_.host() - , lexical_cast(request_.port()) - , boost::bind( - &simple_connection_policy::resolve, - this, - _1, _2, _3 - ) - , boost::iequals(request_.protocol(), string_type("https")) - , certificate_file - , verify_file - ) - ); - return connection_; - } - - void cleanup() { } - - simple_connection_policy(bool cache_resolved, bool follow_redirect) - : resolver_base(cache_resolved), follow_redirect_(follow_redirect) {} - - // member variables - bool follow_redirect_; - - }; - -} // namespace http - -} // namespace network - -} // namespace boost - - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 - diff --git a/boost/network/protocol/http/policies/sync_resolver.hpp b/boost/network/protocol/http/policies/sync_resolver.hpp deleted file mode 100644 index 9702425e9..000000000 --- a/boost/network/protocol/http/policies/sync_resolver.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { namespace policies { - - template - struct sync_resolver { - - typedef typename resolver::type resolver_type; - typedef typename resolver_type::iterator resolver_iterator; - typedef typename resolver_type::query resolver_query; - typedef std::pair resolver_iterator_pair; - - protected: - - typedef typename string::type string_type; - typedef boost::unordered_map resolved_cache; - resolved_cache endpoint_cache_; - bool cache_resolved_; - - sync_resolver(bool cache_resolved) : cache_resolved_(cache_resolved) {} - - resolver_iterator_pair resolve(resolver_type & resolver_, string_type const & hostname, string_type const & port) { - if (cache_resolved_) { - typename resolved_cache::iterator cached_iterator = - endpoint_cache_.find(hostname); - if (cached_iterator == endpoint_cache_.end()) { - bool inserted = false; - boost::fusion::tie(cached_iterator, inserted) = - endpoint_cache_.insert( - std::make_pair( - boost::to_lower_copy(hostname), - std::make_pair( - resolver_.resolve( - resolver_query( - hostname, - port, - resolver_query::numeric_service - ) - ) - , resolver_iterator() - ) - ) - ); - }; - return cached_iterator->second; - }; - - return std::make_pair( - resolver_.resolve( - resolver_query( - hostname, - port, - resolver_query::numeric_service - ) - ) - , - resolver_iterator() - ); - }; - - }; - -} // namespace policies - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 - diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index 7ac1fa412..ef5927ba5 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -1,22 +1,18 @@ - -// Copyright Dean Michael Berris 2007. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - #ifndef __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ #define __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ -// Implement the HTTP Request Object +// Copyright Dean Michael Berris 2007. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include #include #include #include - #include #include #include @@ -49,8 +45,10 @@ // forward declarations namespace boost { namespace network { namespace http { - template - struct basic_request; +struct request_base; + +template +struct basic_request; } // namespace http @@ -58,19 +56,16 @@ namespace boost { namespace network { namespace http { } // namespace boost -#include +#include namespace boost { namespace network { namespace http { - template - basic_request & operator<<( - basic_request & message, - Directive const & directive - ) - { - directive(message); - return message; - } +template +request_base & operator<< (request_base & request, + Directive const & directive) { + directive(request); + return request; +} } // namespace http diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index cf36cceb0..459f938b8 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/boost/network/protocol/http/support/is_client.hpp b/boost/network/protocol/http/support/is_client.hpp index e15b89603..0958401e8 100644 --- a/boost/network/protocol/http/support/is_client.hpp +++ b/boost/network/protocol/http/support/is_client.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/support/is_server.hpp b/boost/network/protocol/http/support/is_server.hpp index 067e16c08..934e36a07 100644 --- a/boost/network/protocol/http/support/is_server.hpp +++ b/boost/network/protocol/http/support/is_server.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/tags.hpp b/boost/network/protocol/http/tags.hpp deleted file mode 100644 index 93db37a69..000000000 --- a/boost/network/protocol/http/tags.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 -#define BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { namespace tags { - - struct http { typedef mpl::true_::type is_http; }; - struct keepalive { typedef mpl::true_::type is_keepalive; }; - struct simple { typedef mpl::true_::type is_simple; }; - struct server { typedef mpl::true_::type is_server; }; - struct client { typedef mpl::true_::type is_client; }; - - using namespace boost::network::tags; - - template - struct components; - - typedef mpl::vector http_default_8bit_tcp_resolve_tags; - typedef mpl::vector http_default_8bit_udp_resolve_tags; - typedef mpl::vector http_keepalive_8bit_tcp_resolve_tags; - typedef mpl::vector http_keepalive_8bit_udp_resolve_tags; - typedef mpl::vector http_async_8bit_udp_resolve_tags; - typedef mpl::vector http_async_8bit_tcp_resolve_tags; - typedef mpl::vector http_server_tags; - typedef mpl::vector http_async_server_tags; - - BOOST_NETWORK_DEFINE_TAG(http_default_8bit_tcp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_default_8bit_udp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_keepalive_8bit_tcp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_keepalive_8bit_udp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_async_8bit_udp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_async_8bit_tcp_resolve); - BOOST_NETWORK_DEFINE_TAG(http_server); - BOOST_NETWORK_DEFINE_TAG(http_async_server); - -} /* tags */ - -} /* http */ - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 */ diff --git a/boost/network/protocol/http/traits.hpp b/boost/network/protocol/http/traits.hpp deleted file mode 100644 index b527a31cf..000000000 --- a/boost/network/protocol/http/traits.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// This file is part of the Boost Network library -// Based on the Pion Network Library (r421) -// Copyright Atomic Labs, Inc. 2007-2008 -// See http://cpp-netlib.sourceforge.net for library home page. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP - -// Convenience header for including different traits implementations. -#include -//#include -#include - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP diff --git a/boost/network/protocol/http/traits/connection_keepalive.hpp b/boost/network/protocol/http/traits/connection_keepalive.hpp deleted file mode 100644 index 55d929020..000000000 --- a/boost/network/protocol/http/traits/connection_keepalive.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 - -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct connection_keepalive : is_keepalive {}; - -} /* http */ - -} /* network */ - -} /* boost */ - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 - diff --git a/boost/network/protocol/http/traits/connection_policy.hpp b/boost/network/protocol/http/traits/connection_policy.hpp deleted file mode 100644 index 6e35570cd..000000000 --- a/boost/network/protocol/http/traits/connection_policy.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct unsupported_tag; - - template - struct connection_policy - { - typedef unsupported_tag type; - }; - - template - struct connection_policy >::type> - { - typedef async_connection_policy type; - }; - - template - struct connection_policy, mpl::not_ > > >::type> - { - typedef simple_connection_policy type; - }; - - template - struct connection_policy, mpl::not_ > > >::type> - { - typedef pooled_connection_policy type; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 - diff --git a/boost/network/protocol/http/traits/delegate_factory.hpp b/boost/network/protocol/http/traits/delegate_factory.hpp deleted file mode 100644 index 714fc590e..000000000 --- a/boost/network/protocol/http/traits/delegate_factory.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 - -// Copyright 2011 Dean Michael Berris (dberris@google.com). -// Copyright 2011 Google, Inc. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { - -namespace impl { - -template -struct connection_delegate_factory; - -} /* impl */ - -template struct unsupported_tag; - -template -struct delegate_factory { - typedef unsupported_tag type; -}; - -template -struct delegate_factory >::type> { - typedef impl::connection_delegate_factory type; -}; - -} /* http */ -} /* network */ -} /* boost */ - - - -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 */ diff --git a/boost/network/protocol/http/traits/impl/chunk_cache.ipp b/boost/network/protocol/http/traits/impl/chunk_cache.ipp deleted file mode 100644 index 724b13011..000000000 --- a/boost/network/protocol/http/traits/impl/chunk_cache.ipp +++ /dev/null @@ -1,36 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP - -#include -#include - -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct chunk_cache { - // TODO define the allocator using an allocator_traits? - typedef std::list< - std::vector< - typename char_::type - > - > type; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP - - diff --git a/boost/network/protocol/http/traits/impl/content.ipp b/boost/network/protocol/http/traits/impl/content.ipp deleted file mode 100644 index 2af19b58f..000000000 --- a/boost/network/protocol/http/traits/impl/content.ipp +++ /dev/null @@ -1,44 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct content { - static char const * const type_html() { - static char const * const TYPE_HTML = "text/html"; - return TYPE_HTML; - }; - - static char const * const type_text() { - static char const * const TYPE_TEXT = "text/plain"; - return TYPE_TEXT; - }; - - static char const * const type_xml() { - static char const * const TYPE_XML = "text/xml"; - return TYPE_XML; - }; - - static char const * const type_urlencoded() { - static char const * const TYPE_URLENCODED = "application/x-www-form-urlencoded"; - return TYPE_URLENCODED; - }; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP - diff --git a/boost/network/protocol/http/traits/impl/cookie_name.ipp b/boost/network/protocol/http/traits/impl/cookie_name.ipp deleted file mode 100644 index 5389b5a67..000000000 --- a/boost/network/protocol/http/traits/impl/cookie_name.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct cookie_name { - static boost::uint32_t const MAX = 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP - diff --git a/boost/network/protocol/http/traits/impl/cookie_value.ipp b/boost/network/protocol/http/traits/impl/cookie_value.ipp deleted file mode 100644 index 9905b67b4..000000000 --- a/boost/network/protocol/http/traits/impl/cookie_value.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct cookie_value { - static boost::uint32_t const MAX = 1024u * 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP - diff --git a/boost/network/protocol/http/traits/impl/cookies_container.ipp b/boost/network/protocol/http/traits/impl/cookies_container.ipp deleted file mode 100644 index d6dbe74f1..000000000 --- a/boost/network/protocol/http/traits/impl/cookies_container.ipp +++ /dev/null @@ -1,32 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP - -#include - -#include - -namespace boost { namespace network { namespace http { - - template - struct cookies_container { - typedef std::multimap< - typename string::type, - typename string::type - > type; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP - - diff --git a/boost/network/protocol/http/traits/impl/delimiters.ipp b/boost/network/protocol/http/traits/impl/delimiters.ipp deleted file mode 100644 index 621f02433..000000000 --- a/boost/network/protocol/http/traits/impl/delimiters.ipp +++ /dev/null @@ -1,40 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP - -#include - -namespace boost { namespace network { namespace http { - - // specialize on the tags::http_default_8bit_tcp_resolve type - template <> - struct delimiters { - static char const * const string_crlf() { - static char const * const CRLF = "\x0D\x0A"; - return CRLF; - }; - - static char const * const string_http_version() { - static char const * const HTTP_VERSION = "HTTP/1.1"; - return HTTP_VERSION; - }; - - static char const * const header_name_value_delimiter() { - static char const * const HEADER_NAME_VALUE_DELIMITER = ": "; - return HEADER_NAME_VALUE_DELIMITER; - }; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP - diff --git a/boost/network/protocol/http/traits/impl/header_name.ipp b/boost/network/protocol/http/traits/impl/header_name.ipp deleted file mode 100644 index 66b502753..000000000 --- a/boost/network/protocol/http/traits/impl/header_name.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct header_name { - static boost::uint32_t const MAX = 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP - diff --git a/boost/network/protocol/http/traits/impl/header_value.ipp b/boost/network/protocol/http/traits/impl/header_value.ipp deleted file mode 100644 index 2dfce49b6..000000000 --- a/boost/network/protocol/http/traits/impl/header_value.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct header_value { - static boost::uint32_t const MAX = 1024u * 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP - diff --git a/boost/network/protocol/http/traits/impl/headers.ipp b/boost/network/protocol/http/traits/impl/headers.ipp deleted file mode 100644 index d13831118..000000000 --- a/boost/network/protocol/http/traits/impl/headers.ipp +++ /dev/null @@ -1,85 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct headers_ { - static char const * const host() { - static char const * const HOST = "Host"; - return HOST; - }; - - static char const * const cookie() { - static char const * const COOKIE = "Cookie"; - return COOKIE; - }; - - static char const * const set_cookie() { - static char const * const SET_COOKIE = "Set-Cookie"; - return SET_COOKIE; - }; - - static char const * const connection() { - static char const * const CONNECTION = "Connection"; - return CONNECTION; - }; - - static char const * const content_type() { - static char const * const CONTENT_TYPE = "Content-Type"; - return CONTENT_TYPE; - }; - - static char const * const content_length() { - static char const * const CONTENT_LENGTH = "Content-Length"; - return CONTENT_LENGTH; - }; - - static char const * const content_location() { - static char const * const CONTENT_LOCATION = "Content-Location"; - return CONTENT_LOCATION; - }; - - static char const * const last_modified() { - static char const * const LAST_MODIFIED = "Last-Modified"; - return LAST_MODIFIED; - }; - - static char const * const if_modified_since() { - static char const * const IF_MODIFIED_SINCE = "If-Modified-Since"; - return IF_MODIFIED_SINCE; - }; - - static char const * const transfer_encoding() { - static char const * const TRANSFER_ENCODING = "Transfer-Encoding"; - return TRANSFER_ENCODING; - }; - - static char const * const location() { - static char const * const LOCATION = "Location"; - return LOCATION; - }; - - static char const * const authorization() { - static char const * const AUTHORIZATION = "Authorization"; - return AUTHORIZATION; - }; - - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP - diff --git a/boost/network/protocol/http/traits/impl/headers_container.ipp b/boost/network/protocol/http/traits/impl/headers_container.ipp deleted file mode 100644 index 42f455da7..000000000 --- a/boost/network/protocol/http/traits/impl/headers_container.ipp +++ /dev/null @@ -1,45 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP - -#include -#include -#include -#include -#include - -namespace boost { namespace network { - - template <> - struct headers_container { - - // Moving implementation from original - // message_traits implementation by - // Atomic Labs, Inc. - // -- - // returns true if str1 < str2 (ignoring case) - struct is_less_ignore_case { - inline bool operator() ( - string::type const & str1, - string::type const & str2) const { - return to_lower_copy(str1) < to_lower_copy(str2); - }; - }; - - typedef std::multimap< - string::type, - string::type, - is_less_ignore_case> type; - }; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP - diff --git a/boost/network/protocol/http/traits/impl/method.ipp b/boost/network/protocol/http/traits/impl/method.ipp deleted file mode 100644 index 52af0d19d..000000000 --- a/boost/network/protocol/http/traits/impl/method.ipp +++ /dev/null @@ -1,28 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct method { - static boost::uint32_t const MAX = 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP - - - diff --git a/boost/network/protocol/http/traits/impl/post_content.ipp b/boost/network/protocol/http/traits/impl/post_content.ipp deleted file mode 100644 index 1a02c38c7..000000000 --- a/boost/network/protocol/http/traits/impl/post_content.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct post_content { - static boost::uint32_t const MAX = 1024u * 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP - diff --git a/boost/network/protocol/http/traits/impl/query_container.ipp b/boost/network/protocol/http/traits/impl/query_container.ipp deleted file mode 100644 index deefc7e7c..000000000 --- a/boost/network/protocol/http/traits/impl/query_container.ipp +++ /dev/null @@ -1,31 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP - -#include - -#include - -namespace boost { namespace network { namespace http { - - template - struct query_container { - typedef std::multimap< - typename string::type, - typename string::type - > type; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP - diff --git a/boost/network/protocol/http/traits/impl/query_name.ipp b/boost/network/protocol/http/traits/impl/query_name.ipp deleted file mode 100644 index 35a12ac4f..000000000 --- a/boost/network/protocol/http/traits/impl/query_name.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct query_name { - static boost::uint32_t const MAX = 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP - diff --git a/boost/network/protocol/http/traits/impl/query_string.ipp b/boost/network/protocol/http/traits/impl/query_string.ipp deleted file mode 100644 index 98e1b3cee..000000000 --- a/boost/network/protocol/http/traits/impl/query_string.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct query_string { - static boost::uint32_t const MAX = 1024u * 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP - diff --git a/boost/network/protocol/http/traits/impl/query_value.ipp b/boost/network/protocol/http/traits/impl/query_value.ipp deleted file mode 100644 index 64343be0c..000000000 --- a/boost/network/protocol/http/traits/impl/query_value.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct query_value { - static boost::uint32_t const MAX = 1024u * 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP - diff --git a/boost/network/protocol/http/traits/impl/request_methods.ipp b/boost/network/protocol/http/traits/impl/request_methods.ipp deleted file mode 100644 index 50a4acff8..000000000 --- a/boost/network/protocol/http/traits/impl/request_methods.ipp +++ /dev/null @@ -1,49 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct request_methods { - static char const * const head() { - static char const * const HEAD = "HEAD"; - return HEAD; - }; - - static char const * const get() { - static char const * const GET = "GET"; - return GET; - }; - - static char const * const put() { - static char const * const PUT = "PUT"; - return PUT; - }; - - static char const * const post() { - static char const * const POST = "POST"; - return POST; - }; - - static char const * const delete_() { - static char const * const DELETE_ = "DELETE"; - return DELETE_; - }; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP - diff --git a/boost/network/protocol/http/traits/impl/resource.ipp b/boost/network/protocol/http/traits/impl/resource.ipp deleted file mode 100644 index 897cbf3b3..000000000 --- a/boost/network/protocol/http/traits/impl/resource.ipp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct resource { - static boost::uint32_t const MAX = 1024u * 256u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP - diff --git a/boost/network/protocol/http/traits/impl/response_code.ipp b/boost/network/protocol/http/traits/impl/response_code.ipp deleted file mode 100644 index 42f7815ae..000000000 --- a/boost/network/protocol/http/traits/impl/response_code.ipp +++ /dev/null @@ -1,42 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP - -#include -#include - -namespace boost { namespace network { namespace http { - - /* This glob doesn't have a specialization on the tags::http_default_8bit_tcp_resolve - * yet because it doesn't need to define different behaviour/types - * on different message tags -- for example, it doesn't need to - * determine the type or change the values of the data no matter - * what the tag type is provided. - */ - template - struct response_code { - static boost::uint16_t const OK = 200u; - static boost::uint16_t const CREATED = 201u; - static boost::uint16_t const NO_CONTENT = 204u; - static boost::uint16_t const UNAUTHORIZED = 401u; - static boost::uint16_t const FORBIDDEN = 403u; - static boost::uint16_t const NOT_FOUND = 404u; - static boost::uint16_t const METHOD_NOT_ALLOWED = 405u; - static boost::uint16_t const NOT_MODIFIED = 304u; - static boost::uint16_t const BAD_REQUEST = 400u; - static boost::uint16_t const SERVER_ERROR = 500u; - static boost::uint16_t const NOT_IMPLEMENTED = 501u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP diff --git a/boost/network/protocol/http/traits/impl/response_message.ipp b/boost/network/protocol/http/traits/impl/response_message.ipp deleted file mode 100644 index de031276e..000000000 --- a/boost/network/protocol/http/traits/impl/response_message.ipp +++ /dev/null @@ -1,80 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct response_message { - static char const * const ok() { - static char const * const OK = "OK"; - return OK; - }; - - static char const * const created() { - static char const * const CREATED = "Created"; - return CREATED; - }; - - static char const * const no_content() { - static char const * const NO_CONTENT = "NO Content"; - return NO_CONTENT; - }; - - static char const * const unauthorized() { - static char const * const UNAUTHORIZED = "Unauthorized"; - return UNAUTHORIZED; - }; - - static char const * const forbidden() { - static char const * const FORBIDDEN = "Fobidden"; - return FORBIDDEN; - }; - - static char const * const not_found() { - static char const * const NOT_FOUND = "Not Found"; - return NOT_FOUND; - }; - - static char const * const method_not_allowed() { - static char const * const METHOD_NOT_ALLOWED = "Method Not Allowed"; - return METHOD_NOT_ALLOWED; - }; - - static char const * const not_modified() { - static char const * const NOT_MODIFIED = "Not Modified"; - return NOT_MODIFIED; - }; - - static char const * const bad_request() { - static char const * const BAD_REQUEST = "Bad Request"; - return BAD_REQUEST; - }; - - static char const * const server_error() { - static char const * const SERVER_ERROR = "Server Error"; - return SERVER_ERROR; - }; - - static char const * const not_implemented() { - static char const * const NOT_IMPLEMENTED = "Not Implemented"; - return NOT_IMPLEMENTED; - }; - - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP - diff --git a/boost/network/protocol/http/traits/impl/status_message.ipp b/boost/network/protocol/http/traits/impl/status_message.ipp deleted file mode 100644 index 71c77d462..000000000 --- a/boost/network/protocol/http/traits/impl/status_message.ipp +++ /dev/null @@ -1,27 +0,0 @@ - -// Copyright Dean Michael Berris 2008. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP - -#include - -namespace boost { namespace network { namespace http { - - template <> - struct status_message_text { - static boost::uint32_t const MAX = 1024u; - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP - - diff --git a/boost/network/protocol/http/traits/message_traits.hpp b/boost/network/protocol/http/traits/message_traits.hpp deleted file mode 100644 index deb41df42..000000000 --- a/boost/network/protocol/http/traits/message_traits.hpp +++ /dev/null @@ -1,63 +0,0 @@ - -// This file is part of the Boost Network library -// Based on the Pion Network Library (r421) -// Copyright Atomic Labs, Inc. 2007-2008 -// See http://cpp-netlib.sourceforge.net for library home page. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// Some changes Copyright (c) Dean Michael Berris 2008 - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HPP -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HPP - -namespace boost { namespace network { namespace http { - - template - struct delimiters; - - template - struct headers_; - - template - struct content; - - template - struct request_methods; - - template - struct response_message; - - template - struct response_code; - - template - struct query_container; - - template - struct cookies_container; - - template - struct chunk_cache; - -} // namespace http - -} // namespace network - -} // namespace boost - -// Defer definition in implementation files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP diff --git a/boost/network/protocol/http/traits/parser_traits.hpp b/boost/network/protocol/http/traits/parser_traits.hpp deleted file mode 100644 index c5465e544..000000000 --- a/boost/network/protocol/http/traits/parser_traits.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// This file is part of the Boost Network library -// Based on the Pion Network Library (r421) -// Copyright Atomic Labs, Inc. 2007-2008 -// See http://cpp-netlib.sourceforge.net for library home page. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// Some changes Copyright 2008 (c) Dean Michael Berris - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP -#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP - -namespace boost { namespace network { namespace http { - - template - struct status_message_text; - - template - struct method; - - template - struct resource; - - template - struct query_string; - - template - struct header_name; - - template - struct header_value; - - template - struct query_name; - - template - struct query_value; - - template - struct cookie_name; - - template - struct cookie_value; - - template - struct post_content; - -} // namespace http - -} // namespace network - -} // namespace boost - -// Include implementation files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP - diff --git a/boost/network/protocol/http/traits/resolver.hpp b/boost/network/protocol/http/traits/resolver.hpp deleted file mode 100644 index c2a31fe68..000000000 --- a/boost/network/protocol/http/traits/resolver.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct unsupported_tag; - - template - struct resolver : - mpl::if_< - mpl::and_< - is_tcp, - is_http - >, - boost::asio::ip::tcp::resolver, - typename mpl::if_< - mpl::and_< - is_udp, - is_http - >, - boost::asio::ip::udp::resolver, - unsupported_tag - >::type - > - { - BOOST_STATIC_ASSERT(( - mpl::not_< - mpl::and_< - is_udp, - is_tcp - > - >::value - )); - }; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 - diff --git a/boost/network/protocol/http/traits/resolver_policy.hpp b/boost/network/protocol/http/traits/resolver_policy.hpp deleted file mode 100644 index 50359a90a..000000000 --- a/boost/network/protocol/http/traits/resolver_policy.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 -#define BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 - -// Copyright Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct unsupported_tag; - - template - struct resolver_policy : - mpl::if_< - mpl::and_< is_async,is_http >, - policies::async_resolver, - typename mpl::if_, - policies::sync_resolver, - unsupported_tag - >::type - > - {}; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 - diff --git a/boost/network/protocol/http/traits/vector.hpp b/boost/network/protocol/http/traits/vector.hpp deleted file mode 100644 index 61b2f5b2f..000000000 --- a/boost/network/protocol/http/traits/vector.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 -#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 - -// Copyright (c) Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template <> - struct vector { - - template - struct apply { - typedef std::vector type; - }; - - }; - - template <> - struct vector { - - template - struct apply { - typedef std::vector type; - }; - - }; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 */ diff --git a/boost/network/support/is_async.hpp b/boost/network/support/is_async.hpp deleted file mode 100644 index d6e1f99f5..000000000 --- a/boost/network/support/is_async.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_20100608 -#define BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_20100608 - -// Copyright 2010 (c) Dean Michael Berris -// Copyright 2010 (c) Sinefunc, Inc. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_async : mpl::false_ {}; - - template - struct is_async::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif //BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_2010608 diff --git a/boost/network/support/is_default_string.hpp b/boost/network/support/is_default_string.hpp deleted file mode 100644 index 2a0fd824e..000000000 --- a/boost/network/support/is_default_string.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright Dean Michael Berris 2010 -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 -#define BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 - -#include -#include - -namespace boost { namespace network { - - template - struct is_default_string : mpl::false_ {}; - - template - struct is_default_string::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 diff --git a/boost/network/support/is_default_wstring.hpp b/boost/network/support/is_default_wstring.hpp deleted file mode 100644 index c414353e1..000000000 --- a/boost/network/support/is_default_wstring.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright Dean Michael Berris 2010 -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_SUPPORT_WSTRING_CHECK_20100808 -#define BOOST_NETWORK_SUPPORT_WSTRING_CHECK_20100808 - -#include -#include - -namespace boost { namespace network { - - template - struct is_default_wstring : mpl::false_ {}; - - template - struct is_default_wstring::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 diff --git a/boost/network/support/is_http.hpp b/boost/network/support/is_http.hpp deleted file mode 100644 index c104e7b42..000000000 --- a/boost/network/support/is_http.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 -#define BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_http : mpl::false_ {}; - - template - struct is_http::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 diff --git a/boost/network/support/is_keepalive.hpp b/boost/network/support/is_keepalive.hpp deleted file mode 100644 index 6607cd10f..000000000 --- a/boost/network/support/is_keepalive.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 -#define BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_keepalive : mpl::false_ {}; - - template - struct is_keepalive::type> : mpl::true_ {}; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 */ diff --git a/boost/network/support/is_pod.hpp b/boost/network/support/is_pod.hpp deleted file mode 100644 index 5c1e1065c..000000000 --- a/boost/network/support/is_pod.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 -#define BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 - -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_pod : mpl::false_ {}; - - template - struct is_pod::type> : mpl::true_ {}; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 */ diff --git a/boost/network/support/is_simple.hpp b/boost/network/support/is_simple.hpp deleted file mode 100644 index 98406d41a..000000000 --- a/boost/network/support/is_simple.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 -#define BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_simple : mpl::false_ {}; - - template - struct is_simple::type> : mpl::true_ {}; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 */ diff --git a/boost/network/support/is_sync.hpp b/boost/network/support/is_sync.hpp deleted file mode 100644 index 0ff0f7130..000000000 --- a/boost/network/support/is_sync.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 -#define BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { - - template - struct is_sync : mpl::false_ {}; - - template - struct is_sync::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 - diff --git a/boost/network/support/is_tcp.hpp b/boost/network/support/is_tcp.hpp deleted file mode 100644 index c041f125f..000000000 --- a/boost/network/support/is_tcp.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 -#define BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace network { - - template - struct is_tcp : mpl::false_ {}; - - template - struct is_tcp::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 \ No newline at end of file diff --git a/boost/network/support/is_udp.hpp b/boost/network/support/is_udp.hpp deleted file mode 100644 index cacbc5e0e..000000000 --- a/boost/network/support/is_udp.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 -#define BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -namespace boost { namespace network { - - template - struct is_udp : mpl::false_ {}; - - template - struct is_udp::type> : mpl::true_ {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 \ No newline at end of file diff --git a/boost/network/support/pod_or_normal.hpp b/boost/network/support/pod_or_normal.hpp deleted file mode 100644 index fdfcf4c12..000000000 --- a/boost/network/support/pod_or_normal.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 -#define BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 - -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { - - template - struct pod_or_normal { typedef tags::normal type; }; - - template - struct pod_or_normal::type> : tags::pod {}; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 */ diff --git a/boost/network/support/sync_only.hpp b/boost/network/support/sync_only.hpp deleted file mode 100644 index 4fbdde818..000000000 --- a/boost/network/support/sync_only.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 -#define BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -namespace boost { namespace network { - - template - struct sync_only : - mpl::inherit_linearly< - typename mpl::replace_if< - typename tags::components::type, - is_same, - tags::sync - >::type - , mpl::inherit - > - {}; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 */ diff --git a/boost/network/tags.hpp b/boost/network/tags.hpp deleted file mode 100644 index df74703a3..000000000 --- a/boost/network/tags.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright Dean Michael Berris 2008, 2009. -// Glyn Matthews 2009 -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef BOOST_NETWORK_TAG_INCLUDED_20100808 -#define BOOST_NETWORK_TAG_INCLUDED_20100808 - -#include -#include -#include -#include - -namespace boost { namespace network { namespace tags { - - struct pod { typedef mpl::true_::type is_pod; }; - struct normal { typedef mpl::true_::type is_normal; }; - struct async { typedef mpl::true_::type is_async; }; - struct tcp { typedef mpl::true_::type is_tcp; }; - struct udp { typedef mpl::true_::type is_udp; }; - struct sync { typedef mpl::true_::type is_sync; }; - struct default_string - { typedef mpl::true_::type is_default_string; }; - struct default_wstring - { typedef mpl::true_::type is_default_wstring; }; - - template - struct components; - - // Tag Definition Macro Helper -#ifndef BOOST_NETWORK_DEFINE_TAG -#define BOOST_NETWORK_DEFINE_TAG(name) \ - struct name : mpl::inherit_linearly< \ - name##_tags, \ - mpl::inherit \ - >::type {}; \ - template <> struct components { \ - typedef name##_tags type; \ - }; -#endif // BOOST_NETWORK_DEFINE_TAG - - typedef default_string default_; - -} // namespace tags - -} // namespace network - -} // namespace boost - -#endif // __BOOST_NETWORK_TAGS_INC__ diff --git a/boost/network/traits/char.hpp b/boost/network/traits/char.hpp deleted file mode 100644 index 79e73441d..000000000 --- a/boost/network/traits/char.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Dean Michael Berris 2008, 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_TRAITS_CHAR_HPP -#define BOOST_NETWORK_TRAITS_CHAR_HPP - -#include -#include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct char_ - { - typedef unsupported_tag type; - }; - - template - struct char_ >::type> - { - typedef char type; - }; - - template - struct char_ >::type> - { - typedef wchar_t type; - }; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_TRAITS_CHAR_HPP diff --git a/boost/network/traits/headers_container.hpp b/boost/network/traits/headers_container.hpp deleted file mode 100644 index f852312d2..000000000 --- a/boost/network/traits/headers_container.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Glyn Matthews 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef __BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC__ -# define __BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC__ - -# include -# include -# include - -namespace boost { namespace network { - - template - struct headers_container { - typedef std::multimap< - typename string::type, - typename string::type - > type; - }; - -} // namespace network -} // namespace boost - - -#endif // __BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC__ diff --git a/boost/network/traits/istream.hpp b/boost/network/traits/istream.hpp deleted file mode 100644 index 7f50bb291..000000000 --- a/boost/network/traits/istream.hpp +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 -#define BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct istream - { - typedef unsupported_tag type; - }; - - template - struct istream >::type> - { - typedef std::istream type; - }; - - template - struct istream >::type> - { - typedef std::wistream type; - }; - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 */ diff --git a/boost/network/traits/istringstream.hpp b/boost/network/traits/istringstream.hpp deleted file mode 100644 index 776385b2a..000000000 --- a/boost/network/traits/istringstream.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Glyn Matthews 2009. -// Copyright (c) Dean Michael Berris 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC -# define BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC - -# include -# include -#include -#include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct istringstream - { - typedef unsupported_tag type; - }; - - template - struct istringstream >::type> - { - typedef std::istringstream type; - }; - - template - struct istringstream >::type> - { - typedef std::basic_istringstream type; - }; - -} // namespace network - -} // namespace boost - - -#endif // BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC - diff --git a/boost/network/traits/ostream_iterator.hpp b/boost/network/traits/ostream_iterator.hpp deleted file mode 100644 index 1f40a7129..000000000 --- a/boost/network/traits/ostream_iterator.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 -#define BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct ostream_iterator; - - template - struct ostream_iterator : mpl::if_< - is_default_string, - std::ostream_iterator, - typename mpl::if_< - is_default_wstring, - std::ostream_iterator, - unsupported_tag - >::type - > {}; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 diff --git a/boost/network/traits/ostringstream.hpp b/boost/network/traits/ostringstream.hpp deleted file mode 100644 index 58e09a638..000000000 --- a/boost/network/traits/ostringstream.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Glyn Matthews 2009. -// Copyright (c) Dean Michael Berris 2009, 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC -# define BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC - -# include -# include -# include -# include -# include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct ostringstream - { - typedef unsupported_tag type; - }; - - template - struct ostringstream >::type> - { - typedef std::ostringstream type; - }; - - template - struct ostringstream >::type> - { - typedef std::wostringstream type; - }; - -} // namespace network - -} // namespace boost - - -#endif // BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC diff --git a/boost/network/traits/string.hpp b/boost/network/traits/string.hpp deleted file mode 100644 index 92cd88e6d..000000000 --- a/boost/network/traits/string.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) Dean Michael Berris 2008, 2009. -// Glyn Matthews 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef BOOST_NETWORK_TRAITS_STRING_INC -#define BOOST_NETWORK_TRAITS_STRING_INC - -# include -# include -# include -# include - -#ifndef BOOST_NETWORK_DEFAULT_STRING -#define BOOST_NETWORK_DEFAULT_STRING std::string -#endif - -#ifndef BOOST_NETWORK_DEFAULT_WSTRING -#define BOOST_NETWORK_DEFAULT_WSTRING std::wstring -#endif - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct string - { - typedef unsupported_tag type; - }; - - template - struct string >::type> - { - typedef BOOST_NETWORK_DEFAULT_STRING type; - }; - - template - struct string >::type> - { - typedef BOOST_NETWORK_DEFAULT_WSTRING type; - }; - -} // namespace network - -} // namespace boost - - -#endif // BOOST_NETWORK_TRAITS_STRING_INC diff --git a/boost/network/traits/vector.hpp b/boost/network/traits/vector.hpp deleted file mode 100644 index 210a13c68..000000000 --- a/boost/network/traits/vector.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Dean Michael Berris 2008, 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_TRAITS_VECTOR_HPP -#define BOOST_NETWORK_TRAITS_VECTOR_HPP - -#include -#include - -namespace boost { namespace network { - - template - struct unsupported_tag; - - template - struct vector { - - template - struct apply : - mpl::if_< - is_default_string - , std::vector - , unsupported_tag - > - {}; - - }; - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_TRAITS_VECTOR_HPP - diff --git a/boost/network/uri/uri.hpp b/boost/network/uri/uri.hpp index 0e5768794..0ddecf0d4 100644 --- a/boost/network/uri/uri.hpp +++ b/boost/network/uri/uri.hpp @@ -8,7 +8,6 @@ # define __BOOST_NETWORK_URI_INC__ -# include # include # include # ifdef BOOST_NETWORK_NO_LIB From 158004fb8d89ed8eae5bf79a42d9fbd4e46accea Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 11 Sep 2011 00:44:38 +1000 Subject: [PATCH 022/438] WIP: Working on wrapper implementations. --- boost/network/message/directives/header.hpp | 94 ++++--------- boost/network/message/wrappers/headers.hpp | 120 ++++++----------- boost/network/message/wrappers/headers.ipp | 69 ++++++++++ boost/network/message_base.hpp | 39 ++++++ .../protocol/http/policies/async_resolver.ipp | 124 ++++++++++++++++++ boost/network/protocol/http/request.ipp | 78 +++++++++++ 6 files changed, 381 insertions(+), 143 deletions(-) create mode 100644 boost/network/message/wrappers/headers.ipp create mode 100644 boost/network/message_base.hpp create mode 100644 boost/network/protocol/http/policies/async_resolver.ipp create mode 100644 boost/network/protocol/http/request.ipp diff --git a/boost/network/message/directives/header.hpp b/boost/network/message/directives/header.hpp index 182d643d3..af3fcf91f 100644 --- a/boost/network/message/directives/header.hpp +++ b/boost/network/message/directives/header.hpp @@ -1,82 +1,44 @@ - -// Copyright Dean Michael Berris 2007-2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - #ifndef __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ #define __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { - - namespace impl { +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) - template - struct header_directive { +#include - explicit header_directive(KeyType const & header_name, - ValueType const & header_value) : - _header_name(header_name), - _header_value(header_value) - { }; +namespace boost { namespace network { - template - struct pod_directive { - template - static void eval(Message const & message, T1 const & key, T2 const & value) { - typedef typename Message::headers_container_type::value_type value_type; - value_type value_ = { key, value }; - message.headers.insert(message.headers.end(), value_); - } - }; +namespace impl { - template - struct normal_directive { - template - static void eval(Message const & message, T1 const & key, T2 const & value) { - typedef typename Message::headers_container_type::value_type value_type; - message.add_header(value_type(key, value)); - } - }; +template +struct header_directive { - template - struct directive_impl : - mpl::if_< - is_base_of< - tags::pod, - typename Message::tag - >, - pod_directive, - normal_directive - >::type - {}; + explicit header_directive(KeyType const & header_name, + ValueType const & header_value) : + _header_name(header_name), + _header_value(header_value) + { }; - template - void operator() (Message const & msg) const { - typedef typename Message::headers_container_type::value_type value_type; - directive_impl::eval(msg, _header_name, _header_value); - } + void operator() (message_base & msg) const { + msg.append_header(_header_name, _header_value); + } - private: + private: - KeyType const & _header_name; - ValueType const & _header_value; - }; + KeyType const & _header_name; + ValueType const & _header_value; +}; - } // namespace impl +} // namespace impl - template - inline impl::header_directive - header(T1 const & header_name, T2 const & header_value) { - return impl::header_directive(header_name, header_value); - } +template +inline impl::header_directive +header(T1 const & header_name, T2 const & header_value) { + return impl::header_directive(header_name, header_value); +} } // namespace network } // namespace boost diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index ce2e0bf25..93f3ba68a 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -13,87 +13,53 @@ namespace boost { namespace network { - /// Template metaprogram to get the range type for a message - template - struct headers_range { - typedef typename headers_container::type headers_container_type; - typedef typename - boost::iterator_range - type; - }; - - template - struct basic_message; - - /** headers wrapper for messages. - * - * This exposes an interface similar to a map, indexable - * using operator[] taking a string as the index and returns - * a range of iterators (std::pair) - * whose keys are all equal to the index string. - * - * This type is also convertible to a - * headers_range >::type - * Which allows for full range support. - * - * The type is also convertible to a - * headers_container::type - * Which copies the headers from the wrapped message. - * - */ - namespace impl { - template - struct headers_wrapper : public detail::wrapper_base_const > { - typedef Tag tag; - typedef basic_message message_type; - typedef typename string::type string_type; - typedef typename headers_range::type range_type; - typedef typename headers_container::type headers_container_type; - typedef typename headers_container_type::const_iterator const_iterator; - typedef typename headers_container_type::iterator iterator; - typedef detail::wrapper_base_const > wrapper_base; - - explicit headers_wrapper(basic_message const & message_) - : wrapper_base(message_) - { }; - - range_type operator[] (string_type const & key) const { - return headers_wrapper::_message.headers().equal_range(key); - }; - - typename message_type::headers_container_type::size_type count(string_type const & key) const { - return headers_wrapper::_message.headers().count(key); - }; - - const_iterator begin() const { - return headers_wrapper::_message.headers().begin(); - }; - - const_iterator end() const { - return headers_wrapper::_message.headers().end(); - }; - - operator range_type () { - return make_iterator_range(headers_wrapper::_message.headers().begin(), headers_wrapper::_message.headers().end()); - }; - - operator headers_container_type () { - return headers_wrapper::_message.headers(); - } - - }; - } // namespace impl - - /// Factory method to create the right wrapper object - template - inline impl::headers_wrapper - headers(basic_message const & message_) { - return impl::headers_wrapper(message_); - } +namespace impl { + +/** headers wrapper for messages. + * + * This exposes an interface similar to a map, indexable + * using operator[] taking a string as the index and returns + * a range of iterators (std::pair) + * whose keys are all equal to the index string. + * + * This type is also convertible to a + * headers_range >::type + * Which allows for full range support. + * + * The type is also convertible to a + * headers_container::type + * Which copies the headers from the wrapped message. + * + */ +struct headers_wrapper { + typedef std::multimap container_type; + typedef shared_container_iterator iterator; + typedef iterator_range > + range_type; + + explicit headers_wrapper(message_base & message); + range_type operator[] (std::string const & key) const; + container_type::size_type count() const; + private: + void init_cache_all(); + mutable shared_ptr cache_; +}; + +} // namespace impl + +/// Factory method to create the right wrapper object +inline impl::headers_wrapper +headers(message_base & message_) { + return impl::headers_wrapper(message_); +} } // namespace network } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif // __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ diff --git a/boost/network/message/wrappers/headers.ipp b/boost/network/message/wrappers/headers.ipp new file mode 100644 index 000000000..b2afc7751 --- /dev/null +++ b/boost/network/message/wrappers/headers.ipp @@ -0,0 +1,69 @@ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { + +headers_wrapper::headers_wrapper(message_base & message) +: message_(message) +{} + +range_type headers_wrapper::operator[] (std::string const & key) const { + cache_.reset(new (std::nothrow) container_type); + if (!cache_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error( + "Cannot allocate cache multimap for headers wrapper.")); + message_.get_headers( + key, + std::inserter(*cache_, cache_->end())); + return make_shared_container_range(cache_); +} + +headers_wrapper::container_type::size_type +headers_wrapper::count(string_type const & key) const { + this->init_cache_all(); + return cache_->size(); +} + +headers_wrapper::iterator headers_wrapper::begin() const { + this->init_cache_all(); + return make_shared_container_iterator(cache_->begin()); +} + +headers_wrapper::iterator headers_wrapper::end() const { + this->init_cache_all(); + return make_shared_container_iterator(cache_->end()); +}; + +headers_wrapper::operator headers_wrapper::range_type () { + this->init_cache_all(); + return make_shared_container_range(cache_); +}; + +headers_wrapper::operator headers_wrapper::container_type () { + this->init_cache_all(); + return *cache_; +} + +void headers_wrapper::init_cache_all() { + if (!cache_.get()) { + cache_.reset(new (std::nothrow) container_type); + if (!cache_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error( + "Cannot allocate cache multimap for headers wrapper.")); + message_.get_headers(std::inserter(*cache_, cache_->end())); + } +} + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_WRAPPERS_HEADERS_IPP_20110911 */ diff --git a/boost/network/message_base.hpp b/boost/network/message_base.hpp new file mode 100644 index 000000000..3dff437e5 --- /dev/null +++ b/boost/network/message_base.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_NETWORK_MESSAGE_BASE_HPP_20110910 +#define BOOST_NETWORK_MESSAGE_BASE_HPP_20110910 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { + +struct message_base { + // Mutators + virtual void set_destination(std::string const & destination) = 0; + virtual void set_source(std::string const & source) = 0; + virtual void append_header(std::string const & name, + std::string const & value) = 0; + virtual void remove_headers(std::string const & name) = 0; + virtual void set_body(std::string const & body) = 0; + virtual void append_body(std::string const & data) = 0; + + // Retrievers + virtual void get_destination(std::string & destination) = 0; + virtual void get_source(std::string & source) = 0; + virtual void get_headers(function inserter) = 0; + virtual void get_headers(std::string const & name, function inserter) = 0; + virtual void get_headers(function predicate, function inserter) = 0; + virtual void get_body(std::string const & body) = 0; + virtual void get_body(function)> chunk_reader, size_t size) = 0; + + // Destructor + virtual ~message_base() = 0; // pure virtual +}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_BASE_HPP_20110910 */ diff --git a/boost/network/protocol/http/policies/async_resolver.ipp b/boost/network/protocol/http/policies/async_resolver.ipp new file mode 100644 index 000000000..d7082efad --- /dev/null +++ b/boost/network/protocol/http/policies/async_resolver.ipp @@ -0,0 +1,124 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 +#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +async_resolver::async_resolver(asio::io_service & service) +: pimpl(new (std::nothrow) async_resolver_pimpl(service)) +{} + +void async_resolver::resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved) { + BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); + pimpl->resolve(host, port, once_resolved); +} + +void async_resolver::clear_resolved_cache() { + BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); + pimpl->clear_resolved_cache(); +} + +async_resolver::~async_resolver() { + // Do nothing +} + +struct async_resolver_pimpl : enable_shared_from_this { + explicit async_resolver_pimpl(asio::io_service & service); + void resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved); + void clear_resolved_cache(); + private: + asio::ip::udp::resolver resolver_; + bool cache_resolved_; + typedef asio::ip::udp::resolver::iterator + resolver_iterator; + typedef unordered_map > + endpoint_cache; + endpoint_cache endpoint_cache_; + scoped_ptr resolver_strand_; +}; + +async_resolver_pimpl::async_resolver_pimpl(asio::io_service & service) + : resolver_(service), + cache_resolved(cache_resolved), + endpoint_cache_(), + resolver_strand_(new(std::nothrow) asio::io_service::strand(service)) +{ + // Do nothing +} + +void async_resolver_pimpl::resolve(std::string const & host, + boost::uint16_t port, + resolve_completion_function once_resolved) { + if (!resolver_strand_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error( + "Uninitialized resolver strand, ran out of memory.")); + + if (cache_resolved_) { + endpoint_cache::iterator iter = + endpoint_cache_.find(boost::to_lower_copy(host)); + if (iter != endpoint_cache_.end()) { + boost::system::error_code ignored; + once_resolved(ignored, iter->second); + return; + } + } + + std::string port_str = lexical_cast(port); + asio::ip::udp::resolver::query query(host, port_str); + resolver_.async_resolve( + query, + resolver_strand_->wrap( + boost::bind( + &async_resolver_pimpl::handle_resolve, + async_resolver_pimpl::shared_from_this(), + boost::to_lower_copy(host), + once_resolved, + boost::asio::placeholders::error, + boost::asio::placeholders::iterator))); +} + +void handle_resolve(std::string const & host, + resolve_completion_function once_resolved, + boost::system::error_code const & ec, + resolver_iterator endpoint_iterator) { + endpoint_cache::iterator iter; + bool inserted = false; + if (!ec && cache_resolved_) { + boost::fusion::tie(iter, inserted) = + endpoint_cache_.insert( + std::make_pair(host, + std::make_pair(endpoint_iterator, + resolver_iterator()))); + once_resolved(ec, iter->second); + } else { + once_resolved(ec, std::make_pair(endpoint_iterator,resolver_iterator())); + } +} + +} /* http */ + +} /* network */ + +} /* boost */ + + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 */ diff --git a/boost/network/protocol/http/request.ipp b/boost/network/protocol/http/request.ipp new file mode 100644 index 000000000..55e2d9fca --- /dev/null +++ b/boost/network/protocol/http/request.ipp @@ -0,0 +1,78 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_IPP_20110910 +#define BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_IPP_20110910 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_NETWORK_BUFFER_CHUNK +#define BOOST_NETWORK_BUFFER_CHUNK 1024 // We want 1KiB worth of data at least. +#endif + +namespace boost { namespace network { namespace http { + +struct body_source : iostreams::source { + virtual std::streamsize read(char * buffer, std::streamsize size); + virtual ~body_source(); +}; + +struct request_storage_base { + typedef iostreams::stream body_stream; + protected: + // TODO Implement a segmented storage base which efficiently supports + // efficient memory usage that makes sense for HTTP payload. The idea is + // to expose the internal (segmented) storage to the client implementation + // so that raw buffers of formatted HTTP request data (which may or may not + // support delegated streams from user input -- i.e. for the body contents) + // can be efficiently sent out to the wire. This also implies that all + // thread-safety guarantees are handled by the storage base as well. + request_storage_base(size_t hint = BOOST_NETWORK_BUFFER_CHUNK); + virtual void set_status_line(std::string const &status_line); + virtual void append_header(std::string const &name, std::string const &value); +}; + +struct request_base : request_storage_base { + protected: + using request_storage_base::body_stream; + request_base(); + // Setters + virtual void set_method(std::string const & method); + virtual void set_status(std::string const & status); + virtual void set_status_message(std::string const & status_message); + virtual void append_header(std::string const &name, std::string const &value); + virtual void set_body_stream(shared_ptr stream); + + // Getters + virtual void get_method(std::string & method); + virtual void get_status(std::string & status); + virtual void get_status_message(std::string & status_message); + virtual void get_headers(function +struct basic_request : request_base { + basic_request(); + basic_request(basic_request const &); // valid copy constructor + // TODO implement a conditional move constructor + basic_request & operator=(basic_request); // valid assigment operator + String const method(); + void method(String const &); + + String const status(); + void status(String const &); + + std::multimap const & headers(); + + String const body(); + body_stream & body_stream(); +}; + + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_IPP_20110910 */ From 7a009269d7a85ff50617d5de01c29d4163c4c500 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 11 Sep 2011 01:14:58 +1000 Subject: [PATCH 023/438] WIP: Converted all modifiers and wrappers to use message_base interface. --- .../network/message/modifiers/add_header.hpp | 50 +------- boost/network/message/modifiers/body.hpp | 21 +--- .../message/modifiers/clear_headers.hpp | 51 +------- .../network/message/modifiers/destination.hpp | 26 +--- .../message/modifiers/remove_header.hpp | 70 +---------- boost/network/message/modifiers/source.hpp | 21 +--- boost/network/message/wrappers/body.hpp | 114 +++++------------- .../network/message/wrappers/destination.hpp | 53 ++++---- boost/network/message/wrappers/headers.hpp | 2 + boost/network/message/wrappers/source.hpp | 54 ++++----- boost/network/message_base.hpp | 4 + 11 files changed, 113 insertions(+), 353 deletions(-) diff --git a/boost/network/message/modifiers/add_header.hpp b/boost/network/message/modifiers/add_header.hpp index c93fe2edb..baeddb6d9 100644 --- a/boost/network/message/modifiers/add_header.hpp +++ b/boost/network/message/modifiers/add_header.hpp @@ -1,8 +1,8 @@ - #ifndef BOOST_NETWORK_MESSAGE_MODIFIER_ADD_HEADER_HPP_20100824 #define BOOST_NETWORK_MESSAGE_MODIFIER_ADD_HEADER_HPP_20100824 -// Copyright 2010 (c) Dean Michael Berris +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -13,48 +13,10 @@ namespace boost { namespace network { - namespace impl { - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , mpl::not_ > - > - , void - >::type - add_header(Message & message, KeyType const & key, ValueType const & value, Tag) { - message.headers().insert(std::make_pair(key, value)); - } - - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , is_async - > - , void - >::type - add_header(Message & message, KeyType const & key, ValueType const & value, Tag) { - typedef typename Message::header_type header_type; - message.add_header(header_type(key,value)); - } - - template - inline typename enable_if< - is_pod - , void - >::type - add_header(Message & message, KeyType const & key, ValueType const & value, Tag) { - typename Message::header_type header = { key, value }; - message.headers.insert(message.headers.end(), header); - } - - } - - template class Message, class KeyType, class ValueType> - inline void add_header(Message & message, KeyType const & key, ValueType const & value) { - impl::add_header(message, key, value, Tag()); - } +inline +void add_header(message_base & message, std::string const & key, std::string const & value) { + message.append_header(key, value); +} } // namespace network diff --git a/boost/network/message/modifiers/body.hpp b/boost/network/message/modifiers/body.hpp index f9b595818..fcd5b1422 100644 --- a/boost/network/message/modifiers/body.hpp +++ b/boost/network/message/modifiers/body.hpp @@ -6,24 +6,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - namespace boost { namespace network { - template class Message, class ValueType> - inline void body_impl(Message & message, ValueType const & body, tags::pod) { - message.body = body; - } - - template class Message, class ValueType> - inline void body_impl(Message & message, ValueType const & body, tags::normal) { - message.body(body); - } +inline void body(message_base & message, std::string const & body_) { + message.set_body(body_); +} - template class Message, class ValueType> - inline void body(Message & message, ValueType const & body_) { - body_impl(message, body_, typename pod_or_normal::type()); - } +inline void append_body(message_base & message, std::string const & data) { + message.append_body(data); +} } // namespace network diff --git a/boost/network/message/modifiers/clear_headers.hpp b/boost/network/message/modifiers/clear_headers.hpp index a983b695a..077337e7c 100644 --- a/boost/network/message/modifiers/clear_headers.hpp +++ b/boost/network/message/modifiers/clear_headers.hpp @@ -1,58 +1,19 @@ #ifndef BOOST_NETWORK_MESSAGE_MODIFIER_CLEAR_HEADERS_HPP_20100824 #define BOOST_NETWORK_MESSAGE_MODIFIER_CLEAR_HEADERS_HPP_20100824 -// Copyright 2010 (c) Dean Michael Berris +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include +#include namespace boost { namespace network { - namespace impl { - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , mpl::not_ > - > - , void - >::type - clear_headers(Message const & message, Tag const &) { - (typename Message::headers_container_type()).swap(message.headers()); - } - - template - inline typename enable_if, void>::type - clear_headers(Message const & message, Tag const &) { - (typename Message::headers_container_type()).swap(message.headers); - } - - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , is_async - > - , void - >::type - clear_headers(Message const & message, Tag const &) { - boost::promise header_promise; - boost::shared_future headers_future(header_promise.get_future()); - message.headers(headers_future); - header_promise.set_value(typename Message::headers_container_type()); - } - - } // namespace impl - - template class Message> - inline void clear_headers(Message const & message) { - impl::clear_headers(message, Tag()); - } +inline void clear_headers(message_base & message) { + message.remove_headers(); +} } // namespace network diff --git a/boost/network/message/modifiers/destination.hpp b/boost/network/message/modifiers/destination.hpp index 8ff362e08..5704bd008 100644 --- a/boost/network/message/modifiers/destination.hpp +++ b/boost/network/message/modifiers/destination.hpp @@ -2,33 +2,17 @@ #ifndef BOOST_NETWORK_MESSAGE_MODIFIER_DESTINATION_HPP_20100824 #define BOOST_NETWORK_MESSAGE_MODIFIER_DESTINATION_HPP_20100824 -// Copyright 2010 (c) Dean Michael Berris +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - namespace boost { namespace network { - namespace impl { - - template - inline void destination(Message const & message, ValueType const & destination_, Tag const &, mpl::false_ const &){ - message.destination(destination_); - } - - template - inline void destination(Message const & message, ValueType const & destination_, Tag const &, mpl::true_ const &) { - message.destination(destination_); - } - - } - - template class Message, class ValueType> - inline void destination(Message const & message, ValueType const & destination_) { - impl::destination(message, destination_, Tag(), is_async()); - } +inline void destination(message_base & message, std::string const & destination_) { + message.set_destination(destination_); +} } // namespace network diff --git a/boost/network/message/modifiers/remove_header.hpp b/boost/network/message/modifiers/remove_header.hpp index e7b098875..fbbc12170 100644 --- a/boost/network/message/modifiers/remove_header.hpp +++ b/boost/network/message/modifiers/remove_header.hpp @@ -7,73 +7,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include +#include +#include namespace boost { namespace network { - namespace impl { - - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , mpl::not_ > - > - , void - >::type - remove_header(Message & message, KeyType const & key, Tag) { - message.headers().erase(key); - } - - template - inline typename enable_if< - mpl::and_< - mpl::not_ > - , is_async - > - , void - >::type - remove_header(Message & message, KeyType const & key, Tag) { - message.remove_header(key); - } - - template - struct iequals_pred { - KeyType const & key; - iequals_pred(KeyType const & key) - : key(key) {} - template - bool operator()(Header & other) const { - return boost::iequals(key, name(other)); - } - }; - - template - inline typename enable_if< - is_pod - , void - >::type - remove_header(Message & message, KeyType const & key, Tag) { - typedef typename Message::headers_container_type headers; - message.headers.erase( - boost::remove_if( - message.headers, - iequals_pred(key) - ) - , message.headers.end() - ); - } - - - } // namespace impl - - template class Message, class KeyType> - inline void remove_header(Message & message, KeyType const & key) { - impl::remove_header(message, key, Tag()); - } +inline +void remove_header(message_base & message, std::string const & key) { + message.remove_headers(key); +} } // namespace network diff --git a/boost/network/message/modifiers/source.hpp b/boost/network/message/modifiers/source.hpp index 11acb9071..f39131181 100644 --- a/boost/network/message/modifiers/source.hpp +++ b/boost/network/message/modifiers/source.hpp @@ -9,24 +9,9 @@ namespace boost { namespace network { - namespace impl { - - template - inline void source(Message const & message, ValueType const & source_, Tag const &, mpl::false_ const &) { - message.source(source_); - } - - template - inline void source(Message const & message, ValueType const & source_, Tag const &, mpl::true_ const &) { - message.source(source_); - } - - } // namespace impl - - template class Message, class ValueType> - inline void source(Message const & message, ValueType const & source_) { - impl::source(message, source_, Tag(), is_async()); - } +inline void source(message_base & message, std::string const & source_) { + message.set_source(source_); +} } // namespace network diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index b2199eca7..b5c89aa1a 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -7,105 +7,45 @@ #ifndef __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ -#include #include +#include +#include namespace boost { namespace network { - template - struct body_range { - typedef typename boost::iterator_range type; - }; +namespace impl { - namespace impl { - template - struct body_wrapper : public detail::wrapper_base > { - typedef basic_message message_type; - typedef typename string::type string_type; - typedef detail::wrapper_base > wrapper_base; - - explicit body_wrapper(basic_message & message_) - : wrapper_base(message_) - { }; +struct body_wrapper { + explicit body_wrapper(message_base & message_); + operator std::string () const; + std::size_t size() const; + operator iterator_range () const; + std::string::const_iterator begin() const; + std::string::const_iterator end() const; + private: + message_base & message_; + mutable optional cache_; +}; - operator string_type () const { - return string_type(wrapper_base::_message.body()); - }; +inline std::ostream & operator<<(std::ostream & os, body_wrapper const & body) { + os << static_cast(body); + return os; +} - std::size_t size() const { - return wrapper_base::_message.body().size(); - } +} // namespace impl - operator boost::iterator_range< - typename boost::range_iterator::type - > () const { - return boost::make_iterator_range(wrapper_base::_message.body()); - } - - typename string_type::const_iterator - begin() const { - return wrapper_base::_message.body().begin(); - } - - typename string_type::const_iterator - end() const { - return wrapper_base::_message.body().end(); - } - - }; - - template - struct body_wrapper_const : public detail::wrapper_base_const > { - typedef basic_message message_type; - typedef typename string::type string_type; - typedef detail::wrapper_base_const > wrapper_base; - - explicit body_wrapper_const(basic_message const & message_) - : wrapper_base(message_) - {}; - - operator string_type () const { - return string_type(wrapper_base::_message.body()); - } - - std::size_t size() const { - return wrapper_base::_message.body().size(); - } - - operator boost::range_iterator () const { - return boost::make_iterator_range(wrapper_base::_message.body()); - } - }; - - template - inline std::ostream & operator<<(std::ostream & os, body_wrapper const & body) { - os << static_cast::string_type>(body); - return os; - } - - template - inline std::ostream & operator<<(std::ostream & os, body_wrapper_const const & body) { - os << static_cast::string_type>(body); - return os; - } - - } // namespace impl - - template - inline impl::body_wrapper const - body(basic_message & message_) { - return impl::body_wrapper(message_); - } - - template - inline impl::body_wrapper_const const - body(basic_message const & message_) { - return impl::body_wrapper_const(message_); - } +inline impl::body_wrapper const +body(message_base & message_) { + return impl::body_wrapper(message_); +} } // namespace network } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif // __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index f1c485269..f4e94764e 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -1,42 +1,37 @@ - -// Copyright Dean Michael Berris 2007. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - #ifndef __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include namespace boost { namespace network { - namespace impl { - template - struct destination_wrapper : public detail::wrapper_base > { - typedef Tag tag; - typedef basic_message message_type; - typedef typename string::type string_type; - typedef detail::wrapper_base > wrapper_base; - - explicit destination_wrapper(message_type & message_) - : wrapper_base(message_) - { }; - - operator string_type () const { - return string_type(wrapper_base::_message.destination()); - }; - }; - } // namespace impl - - template - inline typename string::type - destination(basic_message & message_) { - return impl::destination_wrapper(message_); - } +namespace impl { + +struct destination_wrapper { + explicit destination_wrapper(message_base & message_); + operator std::string () const; +}; + +} // namespace impl + +inline std::string const +destination(message_base & message_) { + return impl::destination_wrapper(message_); +} } // namespace network } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif // __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index 93f3ba68a..5c217ddca 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -7,6 +7,8 @@ #ifndef __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ #define __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ +#include +#include #include #include #include diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 378e80628..8a139de17 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -1,42 +1,36 @@ +#ifndef __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ -// Copyright Dean Michael Berris 2007. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#ifndef __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ -#define __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ +#include namespace boost { namespace network { - namespace impl { - template - struct source_wrapper : public detail::wrapper_base > { - typedef Tag tag; - typedef basic_message message_type; - typedef typename string::type string_type; - typedef detail::wrapper_base > wrapper_base; - - explicit source_wrapper(basic_message & message_) - : wrapper_base(message_) - { }; - - operator string_type () const { - return string_type(wrapper_base::_message.source()); - }; - }; - } // namespace impl - - template - inline typename string::type - source(basic_message & message_) { - return impl::source_wrapper(message_); - } +namespace impl { + +struct source_wrapper { + explicit source_wrapper(message_base & message_); + operator std::string () const; +}; + +} // namespace impl + +inline std::string const +source(message_base & message_) { + return impl::source_wrapper(message_); +} } // namespace network } // namespace boost -#endif // __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ - +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif +#endif // __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ diff --git a/boost/network/message_base.hpp b/boost/network/message_base.hpp index 3dff437e5..c96a666bc 100644 --- a/boost/network/message_base.hpp +++ b/boost/network/message_base.hpp @@ -7,6 +7,9 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include +#include + namespace boost { namespace network { struct message_base { @@ -16,6 +19,7 @@ struct message_base { virtual void append_header(std::string const & name, std::string const & value) = 0; virtual void remove_headers(std::string const & name) = 0; + virtual void remove_headers() = 0; virtual void set_body(std::string const & body) = 0; virtual void append_body(std::string const & data) = 0; From 6c3696feb856309eca59263ac2906a09dd5a9f3f Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 11 Sep 2011 09:39:47 -0700 Subject: [PATCH 024/438] More Gutting. The direction this commit takes is to have the message type more expansive and transition the interface to a more object-oriented design that still adheres to the generic programming interfaces. Note, the builds still aren't complete. This is a WIP commit. --- boost/network/message.hpp | 84 ++++++------- boost/network/message/basic_message.hpp | 52 ++++++++ boost/network/message/basic_message.ipp | 112 ++++++++++++++++++ boost/network/message/message_concept.hpp | 16 +-- boost/network/message/traits/body.hpp | 46 ------- boost/network/message/traits/destination.hpp | 45 ------- boost/network/message/traits/headers.hpp | 62 ---------- boost/network/message/traits/source.hpp | 45 ------- .../protocol/http/message/traits/status.hpp | 38 ------ .../http/message/traits/status_message.hpp | 40 ------- .../protocol/http/message/traits/version.hpp | 51 -------- boost/network/protocol/http/response.hpp | 2 - .../protocol/http/response_concept.hpp | 3 - 13 files changed, 205 insertions(+), 391 deletions(-) create mode 100644 boost/network/message/basic_message.hpp create mode 100644 boost/network/message/basic_message.ipp delete mode 100644 boost/network/message/traits/body.hpp delete mode 100644 boost/network/message/traits/destination.hpp delete mode 100644 boost/network/message/traits/headers.hpp delete mode 100644 boost/network/message/traits/source.hpp delete mode 100644 boost/network/protocol/http/message/traits/status.hpp delete mode 100644 boost/network/protocol/http/message/traits/status_message.hpp delete mode 100644 boost/network/protocol/http/message/traits/version.hpp diff --git a/boost/network/message.hpp b/boost/network/message.hpp index fcddc7e1b..e46a2707c 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -20,7 +20,11 @@ #include #include +#ifdef BOOST_NETWORK_DEBUG #include +#endif + +#include /** message.hpp * @@ -34,114 +38,98 @@ namespace boost { namespace network { /** The common message type. */ - template - struct basic_message { - public: - - typedef Tag tag; - - typedef typename headers_container::type headers_container_type; - typedef typename headers_container_type::value_type header_type; - typedef typename string::type string_type; + template + struct basic_message : basic_storage_base { + typedef std::pair header_type; + typedef std::multimap headers_container_type; + typedef String string_type; basic_message() - : _headers(), _body(), _source(), _destination() - { } + : basic_storage_base() + {} basic_message(const basic_message & other) - : _headers(other._headers), _body(other._body), _source(other._source), _destination(other._destination) - { } + : basic_storage_base(other) + {} - basic_message & operator=(basic_message rhs) { + basic_message & operator=(basic_message rhs) { rhs.swap(*this); return *this; } - void swap(basic_message & other) { - std::swap(other._headers, _headers); - std::swap(other._body, _body); - std::swap(other._source, _source); - std::swap(other._destination, _destination); + void swap(basic_message & other) { + basic_storage_base & this_ = *this, + & other_ = other; + swap(this_, other_); } headers_container_type & headers() { - return _headers; + return pimpl->headers_; } void headers(headers_container_type const & headers_) const { - _headers = headers_; + pimpl->headers_ = headers_; } void add_header(typename headers_container_type::value_type const & pair_) const { - _headers.insert(pair_); + this->append_header(pair_.first, pair_.second); } void remove_header(typename headers_container_type::key_type const & key) const { - _headers.erase(key); + this->remove_headers(key); } headers_container_type const & headers() const { - return _headers; + return pimpl->headers_; } string_type & body() { - return _body; + return pimpl->body_; } void body(string_type const & body_) const { - _body = body_; + this->set_body(body_); } string_type const & body() const { - return _body; + return pimpl->body_; } string_type & source() { - return _source; + return pimpl->source_; } void source(string_type const & source_) const { - _source = source_; + this->set_source(source_); } string_type const & source() const { - return _source; + return pimpl->source_; } string_type & destination() { - return _destination; + return pimpl->destination_; } void destination(string_type const & destination_) const { - _destination = destination_; + this->set_destination(destination_); } string_type const & destination() const { - return _destination; + return pimpl->destination_; } - - private: - - friend struct detail::directive_base ; - friend struct detail::wrapper_base > ; - - mutable headers_container_type _headers; - mutable string_type _body; - mutable string_type _source; - mutable string_type _destination; }; - template - inline void swap(basic_message & left, basic_message & right) { - // swap for ADL + template + inline void swap(basic_message & left, basic_message & right) { left.swap(right); } // Commenting this out as we don't need to do this anymore. // BOOST_CONCEPT_ASSERT((Message >)); // BOOST_CONCEPT_ASSERT((Message >)); - typedef basic_message message; - typedef basic_message wmessage; + typedef basic_message message; + typedef basic_message wmessage; } // namespace network } // namespace boost diff --git a/boost/network/message/basic_message.hpp b/boost/network/message/basic_message.hpp new file mode 100644 index 000000000..3bf44db93 --- /dev/null +++ b/boost/network/message/basic_message.hpp @@ -0,0 +1,52 @@ +#ifndef BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_HPP_20110911 +#define BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_HPP_20110911 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { + +struct basic_storage_pimpl; + +struct basic_storage_base : message_base { + basic_storage_base(); + basic_storage_base(basic_storage_base const &); + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_body(std::string & body); + virtual void get_body(function)> chunk_reader, size_t size); + + void swap(basic_storage_base & other); + + virtual ~basic_storage_base(); + protected: + scoped_ptr pimpl; +}; + +void swap(basic_storage_base & l, basic_storage_base & r); + +} /* network */ +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_HPP_20110911 */ diff --git a/boost/network/message/basic_message.ipp b/boost/network/message/basic_message.ipp new file mode 100644 index 000000000..bd9a94d92 --- /dev/null +++ b/boost/network/message/basic_message.ipp @@ -0,0 +1,112 @@ +#ifndef BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_IPP_20110911 +#define BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_IPP_20110911 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { + +struct basic_storage_pimpl { + basic_storage_pimpl(); + basic_storage_pimpl(basic_storage_pimpl const &); + + virtual basic_storage_pimpl* clone(); + protected: + friend struct basic_storage_base; + std::string source_, destination_; + typedef std::multimap headers_container_type; + headers_container_type headers_; + std::string body_; +}; + +basic_storage_base::basic_storage_base() +: pimpl(new (std::nothrow) basic_storage_pimpl()) +{} + +basic_storage_base::basic_storage_base(basic_storage_base const & other) +: pimpl(other.clone()) +{} + +void basic_storage_base::set_destination(std::string const & destination) { + pimpl->destination_ = destination; +} + +void basic_storage_base::set_source(std::string const & source) { + pimpl->source_ = source; +} + +void basic_storage_base::append_header(std::string const & name, + std::string const & value) { + pimpl->headers_.insert(std::make_pair(name, value)); +} + +void basic_storage_base::remove_headers(std::string const & name) { + pimpl->headers_.erase(name); +} + +void basic_storage_base::remove_headers() { + basic_storage_pimpl::headers_container_type().swap(pimpl->headers_); +} + +void basic_storage_base::set_body(std::string const & body) { + pimpl->body = body; +} + +void basic_storage_base::append_body(std::string const & data) { + pimpl->body.append(data); +} + +void basic_storage_base::get_destination(std::string & destination) { + destination = pimpl->destination; +} + +void basic_storage_base::get_source(std::string & source) { + source = pimpl->source; +} + +void basic_storage_base::get_headers(function inserter) { + copy(pimpl->headers_, inserter); +} + +void basic_storage_base::get_headers(std::string const & name, function inserter) { + basic_storage_pimpl::headers_container_type::const_iterator + it = pimpl->headers_.find(name), + pe = pimpl->headers_.end(); + for (; it != pe; ++it) + inserter(it->first, it->second); +} + +void basic_storage_base::get_body(std::string & body) { + // TODO use iostreams! + body = pimpl_->body; +} + +void basic_storage_base::get_body(function)> chunk_reader, size_t size) { + // TODO use iostreams! + std::string::const_iterator it = pimpl->body.begin(), + pe = pimpl->body.end(); + std::advance(it, size); + chunk_reader(make_iterator_range(it, pe)); + pimpl->body.assign(it, pe); +} + +basic_storage_base::~basic_storage_base() { + pimpl->reset(); +} + +void basic_storage_base::swap(basic_storage_base & other) { + std::swap(pimpl, other.pimpl); +} + +void swap(basic_storage_base & l, basic_storage_base & r) { + l.swap(r); +} + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_BASIC_MESSAGE_IPP_20110911 */ diff --git a/boost/network/message/message_concept.hpp b/boost/network/message/message_concept.hpp index 91ac07960..2016c806f 100644 --- a/boost/network/message/message_concept.hpp +++ b/boost/network/message/message_concept.hpp @@ -10,10 +10,6 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include -#include -#include #include #include #include @@ -29,13 +25,11 @@ namespace boost { namespace network { BOOST_CONCEPT_USAGE(Message) { M message_; swap(message, message_); - - typedef typename traits::body::type body_type; - typedef typename traits::source::type source_type; - typedef typename traits::destination::type destination_type; - - typedef typename traits::header_key::type header_key_type; - typedef typename traits::header_value::type header_value_type; + typedef std::string source_type; + typedef std::string destination_type; + typedef std::string body_type; + typedef std::string header_key_type; + typedef std::string header_value_type; headers_container_type headers_ = headers(message); string_type body_ = body(message); diff --git a/boost/network/message/traits/body.hpp b/boost/network/message/traits/body.hpp deleted file mode 100644 index 5d539d7f4..000000000 --- a/boost/network/message/traits/body.hpp +++ /dev/null @@ -1,46 +0,0 @@ - -#ifndef BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 -#define BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace network { - - namespace traits { - - template - struct unsupported_tag; - - template - struct body : - mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - } // namespace traits - -} /* network */ - -} /* boost */ - -#endif // BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 - diff --git a/boost/network/message/traits/destination.hpp b/boost/network/message/traits/destination.hpp deleted file mode 100644 index 39da83de9..000000000 --- a/boost/network/message/traits/destination.hpp +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 -#define BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { - - namespace traits { - - template - struct unsupported_tag; - - template - struct destination : - mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - } // namespace traits - -} /* network */ - -} /* boost */ - -#endif // BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 - diff --git a/boost/network/message/traits/headers.hpp b/boost/network/message/traits/headers.hpp deleted file mode 100644 index a51023675..000000000 --- a/boost/network/message/traits/headers.hpp +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 -#define BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { - - namespace traits { - - template - struct unsupported_tag; - - template - struct header_key : - mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - template - struct header_value : - mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - } // namespace traits - -} /* network */ - -} /* boost */ - -#endif // BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 - diff --git a/boost/network/message/traits/source.hpp b/boost/network/message/traits/source.hpp deleted file mode 100644 index 9d2237e1e..000000000 --- a/boost/network/message/traits/source.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 -#define BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { - - namespace traits { - - template - struct unsupported_tag; - - template - struct source : - mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - } // namespace traits - -} /* network */ - -} /* boost */ - -#endif // BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 - - diff --git a/boost/network/protocol/http/message/traits/status.hpp b/boost/network/protocol/http/message/traits/status.hpp deleted file mode 100644 index 2ff22dcae..000000000 --- a/boost/network/protocol/http/message/traits/status.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_HPP_20100903 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { - - namespace traits { - - template - struct unsupported_tag; - - template - struct status - : mpl::if_< - is_async, - boost::shared_future, - typename mpl::if_< - is_sync, - boost::uint16_t, - unsupported_tag - >::type - > - {}; - - } /* traits */ - -} /* http */ -} /* network */ -} /* boost */ - -#endif - diff --git a/boost/network/protocol/http/message/traits/status_message.hpp b/boost/network/protocol/http/message/traits/status_message.hpp deleted file mode 100644 index 9b0a47ccf..000000000 --- a/boost/network/protocol/http/message/traits/status_message.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_MESSAGE_HPP_20100903 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_MESSAGE_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -namespace boost { namespace network { namespace http { - - namespace traits { - - template - struct unsupported_tag; - - template - struct status_message - : mpl::if_< - is_async, - boost::shared_future::type>, - typename mpl::if_< - mpl::or_< - is_sync, - is_same, - is_same - >, - typename string::type, - unsupported_tag - >::type - > - {}; - - } /* traits */ - -} /* http */ -} /* network */ -} /* boost */ - -#endif - diff --git a/boost/network/protocol/http/message/traits/version.hpp b/boost/network/protocol/http/message/traits/version.hpp deleted file mode 100644 index 748bb71c6..000000000 --- a/boost/network/protocol/http/message/traits/version.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_VERSION_HPP_20100903 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_VERSION_HPP_20100903 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { namespace http { - - namespace traits { - - template - struct unsupported_tag; - - template - struct version - { - typedef unsupported_tag type; - }; - - template - struct version >::type> - { - typedef boost::shared_future::type> type; - }; - - template - struct version, - is_default_string, - is_default_wstring - > - >::type - > - { - typedef typename string::type type; - }; - - } /* traits */ - -} /* http */ -} /* network */ -} /* boost */ - -#endif diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index 459f938b8..bf9a00005 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -9,8 +9,6 @@ #include -#include - #include #include #include diff --git a/boost/network/protocol/http/response_concept.hpp b/boost/network/protocol/http/response_concept.hpp index ef6bf0f62..9d067532d 100644 --- a/boost/network/protocol/http/response_concept.hpp +++ b/boost/network/protocol/http/response_concept.hpp @@ -9,9 +9,6 @@ #include #include -#include -#include -#include #include namespace boost { namespace network { namespace http { From 0e521d02e2b1f667278a46b86d3b7ea2dd1f381c Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 30 Sep 2011 16:44:19 +1000 Subject: [PATCH 025/438] WIP: Gutting the message implementation. --- boost/network/message.hpp | 55 +++++++++++--- .../http/message/directives/status.hpp | 72 +++++-------------- boost/network/protocol/http/request.ipp | 2 +- 3 files changed, 65 insertions(+), 64 deletions(-) diff --git a/boost/network/message.hpp b/boost/network/message.hpp index e46a2707c..32b3f68f0 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -64,11 +64,15 @@ namespace boost { namespace network { } headers_container_type & headers() { - return pimpl->headers_; + if (!headers_) { + headers_ = headers_container_type(); + this->get_headers(*headers_); + } + return *headers_; } void headers(headers_container_type const & headers_) const { - pimpl->headers_ = headers_; + this->set_headers(headers_); } void add_header(typename headers_container_type::value_type const & pair_) const { @@ -80,11 +84,19 @@ namespace boost { namespace network { } headers_container_type const & headers() const { - return pimpl->headers_; + if (!headers_) { + headers_ = headers_container_type(); + this->get_headers(*headers_); + } + return *headers_; } string_type & body() { - return pimpl->body_; + if (!body_) { + body_ = String(); + this->get_body(*body_); + } + return *body_; } void body(string_type const & body_) const { @@ -92,11 +104,19 @@ namespace boost { namespace network { } string_type const & body() const { - return pimpl->body_; + if (!body_) { + body_ = String(); + this->get_body(*body_); + } + return *body_; } string_type & source() { - return pimpl->source_; + if (!source_) { + source_ = String(); + this->get_source(*source_); + } + return *source_; } void source(string_type const & source_) const { @@ -104,11 +124,19 @@ namespace boost { namespace network { } string_type const & source() const { - return pimpl->source_; + if (!source_) { + source_ = String(); + this->get_source(*source_); + } + return *source_; } string_type & destination() { - return pimpl->destination_; + if (!destination_) { + destination_ = String(); + this->get_destination(*destination_); + } + return *destination_; } void destination(string_type const & destination_) const { @@ -116,8 +144,17 @@ namespace boost { namespace network { } string_type const & destination() const { - return pimpl->destination_; + if (!destination_) { + destination_ = String(); + this->get_destination(*destination_); + } + return *destination_; } + + protected: + optional source_, destination_; + optional headers_; + optional body_; }; template diff --git a/boost/network/protocol/http/message/directives/status.hpp b/boost/network/protocol/http/message/directives/status.hpp index bfd68354c..6595658b7 100644 --- a/boost/network/protocol/http/message/directives/status.hpp +++ b/boost/network/protocol/http/message/directives/status.hpp @@ -1,76 +1,40 @@ #ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_HPP_20100603 #define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_HPP_20100603 -// Copyright 2010 (c) Dean Michael Berris // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include -#include -#include -#include #include namespace boost { namespace network { namespace http { - template - struct basic_response; - - struct status_directive { +template +struct status_directive { - boost::variant< - boost::uint16_t, - boost::shared_future - > status_; + status_directive(String const & s) + : status_(s) + {} - explicit status_directive(boost::uint16_t status) - : status_(status) {} + void operator()(response_base & response) { + response.set_status(status_); + } - explicit status_directive(boost::shared_future const & status) - : status_(status) {} + protected: + + String status_; - status_directive(status_directive const & other) - : status_(other.status_) {} +}; - template - struct value - : mpl::if_< - is_async, - boost::shared_future, - boost::uint16_t - > - {}; - - template - struct status_visitor : boost::static_visitor<> { - basic_response const & response; - status_visitor(basic_response const & response) - : response(response) {} - - void operator()(typename value::type const & status_) const { - response.status(status_); - } - - template - void operator()(T const &) const { - // FIXME fail here! - } - }; - - template basic_response const & operator() (basic_response const & response) const { - apply_visitor(status_visitor(response), status_); - return response; - } - - }; - - template - inline status_directive const status(T const & status_) { - return status_directive(status_); - } +template +inline status_directive status(String const & response) { + return status_directive(response); +} } // namespace http diff --git a/boost/network/protocol/http/request.ipp b/boost/network/protocol/http/request.ipp index 55e2d9fca..cace3fccb 100644 --- a/boost/network/protocol/http/request.ipp +++ b/boost/network/protocol/http/request.ipp @@ -33,7 +33,7 @@ struct request_storage_base { virtual void append_header(std::string const &name, std::string const &value); }; -struct request_base : request_storage_base { +struct request_base : message_base, request_storage_base { protected: using request_storage_base::body_stream; request_base(); From ddbfba25cd76189bae46bc73ada7b444d8c37c78 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 30 Sep 2011 17:36:47 +1000 Subject: [PATCH 026/438] WIP: Gutting the message implementation... --- boost/network/message/wrappers/body.hpp | 7 +- boost/network/message/wrappers/source.hpp | 2 + boost/network/protocol/http/impl/response.ipp | 570 +++++++++--------- .../http/message/directives/status.hpp | 1 + .../network/protocol/http/message/header.hpp | 79 +-- .../protocol/http/message/message_base.hpp | 33 - .../protocol/http/message/modifiers/body.hpp | 74 --- .../http/message/modifiers/destination.hpp | 90 --- .../http/message/modifiers/headers.hpp | 57 -- .../http/message/modifiers/source.hpp | 82 --- .../http/message/modifiers/status.hpp | 26 +- .../http/message/modifiers/status_message.hpp | 26 +- .../http/message/modifiers/version.hpp | 27 +- .../http/message/wrappers/destination.hpp | 33 - .../protocol/http/message/wrappers/source.hpp | 27 - .../protocol/http/message/wrappers/status.hpp | 49 +- .../http/message/wrappers/status_message.hpp | 47 +- .../protocol/http/message/wrappers/uri.hpp | 42 +- .../http/message/wrappers/version.hpp | 53 +- boost/network/protocol/http/request.hpp | 6 - boost/network/protocol/http/response.hpp | 47 +- .../protocol/http/response_concept.hpp | 6 +- .../protocol/http/server/impl/parsers.ipp | 2 +- 23 files changed, 387 insertions(+), 999 deletions(-) delete mode 100644 boost/network/protocol/http/message/message_base.hpp delete mode 100644 boost/network/protocol/http/message/modifiers/body.hpp delete mode 100644 boost/network/protocol/http/message/modifiers/destination.hpp delete mode 100644 boost/network/protocol/http/message/modifiers/headers.hpp delete mode 100644 boost/network/protocol/http/message/modifiers/source.hpp delete mode 100644 boost/network/protocol/http/message/wrappers/destination.hpp delete mode 100644 boost/network/protocol/http/message/wrappers/source.hpp diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index b5c89aa1a..ce19f8d0b 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -1,11 +1,12 @@ -// Copyright Dean Michael Berris 2007. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ -#define __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 #include #include diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 8a139de17..7485f6b73 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -16,6 +16,8 @@ namespace impl { struct source_wrapper { explicit source_wrapper(message_base & message_); operator std::string () const; + private: + message_base & message_; }; } // namespace impl diff --git a/boost/network/protocol/http/impl/response.ipp b/boost/network/protocol/http/impl/response.ipp index 0708575e8..5780ef24e 100644 --- a/boost/network/protocol/http/impl/response.ipp +++ b/boost/network/protocol/http/impl/response.ipp @@ -20,305 +20,299 @@ namespace boost { namespace network { namespace http { - /// A reply to be sent to a client. - template <> - struct basic_response { - typedef tags::http_server tag; - typedef response_header::type header_type; +/// A reply to be sent to a client. +template class Vector = std::vector> +struct basic_response : response_base { - /// The status of the reply. - enum status_type { - ok = 200, - created = 201, - accepted = 202, - no_content = 204, - multiple_choices = 300, - moved_permanently = 301, - moved_temporarily = 302, - not_modified = 304, - bad_request = 400, - unauthorized = 401, - forbidden = 403, - not_found = 404, - not_supported = 405, - not_acceptable = 406, - internal_server_error = 500, - not_implemented = 501, - bad_gateway = 502, - service_unavailable = 503 - } status; - - /// The headers to be included in the reply. - typedef vector::apply::type headers_vector; - headers_vector headers; - - /// The content to be sent in the reply. - typedef string::type string_type; - string_type content; + /// The status of the reply. + enum status_type { + ok = 200, + created = 201, + accepted = 202, + no_content = 204, + multiple_choices = 300, + moved_permanently = 301, + moved_temporarily = 302, + not_modified = 304, + bad_request = 400, + unauthorized = 401, + forbidden = 403, + not_found = 404, + not_supported = 405, + not_acceptable = 406, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503 + } status; + + /// The headers to be included in the reply. + typedef Vector > headers_vector; + headers_vector headers; - /// Convert the reply into a vector of buffers. The buffers do not own the - /// underlying memory blocks, therefore the reply object must remain valid and - /// not be changed until the write operation has completed. - std::vector to_buffers() { - using boost::asio::const_buffer; - using boost::asio::buffer; - static const char name_value_separator[] = { ':', ' ' }; - static const char crlf[] = { '\r', '\n' }; - std::vector buffers; - buffers.push_back(to_buffer(status)); - for (std::size_t i = 0; i < headers.size(); ++i) { - header_type & h = headers[i]; - buffers.push_back(buffer(h.name)); - buffers.push_back(buffer(name_value_separator)); - buffers.push_back(buffer(h.value)); - buffers.push_back(buffer(crlf)); - } + /// Convert the reply into a vector of buffers. The buffers do not own the + /// underlying memory blocks, therefore the reply object must remain valid and + /// not be changed until the write operation has completed. + std::vector to_buffers() { + // FIXME: Rethink this and do this asynchronously. + using boost::asio::const_buffer; + using boost::asio::buffer; + static const char name_value_separator[] = { ':', ' ' }; + static const char crlf[] = { '\r', '\n' }; + std::vector buffers; + buffers.push_back(to_buffer(status)); + for (std::size_t i = 0; i < headers.size(); ++i) { + response_header & h = headers[i]; + buffers.push_back(buffer(h.name)); + buffers.push_back(buffer(name_value_separator)); + buffers.push_back(buffer(h.value)); buffers.push_back(buffer(crlf)); - buffers.push_back(buffer(content)); - return buffers; } + buffers.push_back(buffer(crlf)); + return buffers; + } - /// Get a stock reply. - static basic_response stock_reply(status_type status) { - return stock_reply(status, to_string(status)); - } + /// Get a stock reply. + static basic_response stock_reply(status_type status) { + return stock_reply(status, to_string(status)); + } - /// Get a stock reply with custom plain text data. - static basic_response stock_reply(status_type status, string_type content) { - using boost::lexical_cast; - basic_response rep; - rep.status = status; - rep.content = content; - rep.headers.resize(2); - rep.headers[0].name = "Content-Length"; - rep.headers[0].value = lexical_cast(rep.content.size()); - rep.headers[1].name = "Content-Type"; - rep.headers[1].value = "text/html"; - return rep; - } + /// Get a stock reply with custom plain text data. + static basic_response stock_reply(status_type status, String const & content) { + using boost::lexical_cast; + basic_response rep; + rep.status = status; + rep.content = content; + rep.headers.resize(2); + rep.headers[0].name = "Content-Length"; + rep.headers[0].value = lexical_cast(rep.content.size()); + rep.headers[1].name = "Content-Type"; + rep.headers[1].value = "text/html"; + return rep; + } - /// Swap response objects - void swap(basic_response &r) { - using std::swap; - swap(headers, r.headers); - swap(content, r.content); - } + /// Swap response objects + void swap(basic_response &r) { + using std::swap; + swap(headers, r.headers); + // swap(content, r.content); + } - private: - - static string_type to_string(status_type status) { - static const char ok[] = ""; - static const char created[] = - "" - "Created" - "

201 Created

" - ""; - static const char accepted[] = - "" - "Accepted" - "

202 Accepted

" - ""; - static const char no_content[] = - "" - "No Content" - "

204 Content

" - ""; - static const char multiple_choices[] = - "" - "Multiple Choices" - "

300 Multiple Choices

" - ""; - static const char moved_permanently[] = - "" - "Moved Permanently" - "

301 Moved Permanently

" - ""; - static const char moved_temporarily[] = - "" - "Moved Temporarily" - "

302 Moved Temporarily

" - ""; - static const char not_modified[] = - "" - "Not Modified" - "

304 Not Modified

" - ""; - static const char bad_request[] = - "" - "Bad Request" - "

400 Bad Request

" - ""; - static const char unauthorized[] = - "" - "Unauthorized" - "

401 Unauthorized

" - ""; - static const char forbidden[] = - "" - "Forbidden" - "

403 Forbidden

" - ""; - static const char not_found[] = - "" - "Not Found" - "

404 Not Found

" - ""; - static const char not_supported[] = - "" - "Method Not Supported" - "

Method Not Supported

" - ""; - static const char not_acceptable[] = - "" - "Request Not Acceptable" - "

Request Not Acceptable

" - ""; - static const char internal_server_error[] = - "" - "Internal Server Error" - "

500 Internal Server Error

" - ""; - static const char not_implemented[] = - "" - "Not Implemented" - "

501 Not Implemented

" - ""; - static const char bad_gateway[] = - "" - "Bad Gateway" - "

502 Bad Gateway

" - ""; - static const char service_unavailable[] = - "" - "Service Unavailable" - "

503 Service Unavailable

" - ""; + private: - switch (status) - { - case basic_response::ok: - return ok; - case basic_response::created: - return created; - case basic_response::accepted: - return accepted; - case basic_response::no_content: - return no_content; - case basic_response::multiple_choices: - return multiple_choices; - case basic_response::moved_permanently: - return moved_permanently; - case basic_response::moved_temporarily: - return moved_temporarily; - case basic_response::not_modified: - return not_modified; - case basic_response::bad_request: - return bad_request; - case basic_response::unauthorized: - return unauthorized; - case basic_response::forbidden: - return forbidden; - case basic_response::not_found: - return not_found; - case basic_response::not_supported: - return not_supported; - case basic_response::not_acceptable: - return not_acceptable; - case basic_response::internal_server_error: - return internal_server_error; - case basic_response::not_implemented: - return not_implemented; - case basic_response::bad_gateway: - return bad_gateway; - case basic_response::service_unavailable: - return service_unavailable; - default: - return internal_server_error; - } + static String to_string(status_type status) { + static const char ok[] = ""; + static const char created[] = + "" + "Created" + "

201 Created

" + ""; + static const char accepted[] = + "" + "Accepted" + "

202 Accepted

" + ""; + static const char no_content[] = + "" + "No Content" + "

204 Content

" + ""; + static const char multiple_choices[] = + "" + "Multiple Choices" + "

300 Multiple Choices

" + ""; + static const char moved_permanently[] = + "" + "Moved Permanently" + "

301 Moved Permanently

" + ""; + static const char moved_temporarily[] = + "" + "Moved Temporarily" + "

302 Moved Temporarily

" + ""; + static const char not_modified[] = + "" + "Not Modified" + "

304 Not Modified

" + ""; + static const char bad_request[] = + "" + "Bad Request" + "

400 Bad Request

" + ""; + static const char unauthorized[] = + "" + "Unauthorized" + "

401 Unauthorized

" + ""; + static const char forbidden[] = + "" + "Forbidden" + "

403 Forbidden

" + ""; + static const char not_found[] = + "" + "Not Found" + "

404 Not Found

" + ""; + static const char not_supported[] = + "" + "Method Not Supported" + "

Method Not Supported

" + ""; + static const char not_acceptable[] = + "" + "Request Not Acceptable" + "

Request Not Acceptable

" + ""; + static const char internal_server_error[] = + "" + "Internal Server Error" + "

500 Internal Server Error

" + ""; + static const char not_implemented[] = + "" + "Not Implemented" + "

501 Not Implemented

" + ""; + static const char bad_gateway[] = + "" + "Bad Gateway" + "

502 Bad Gateway

" + ""; + static const char service_unavailable[] = + "" + "Service Unavailable" + "

503 Service Unavailable

" + ""; + + switch (status) + { + case basic_response::ok: + return ok; + case basic_response::created: + return created; + case basic_response::accepted: + return accepted; + case basic_response::no_content: + return no_content; + case basic_response::multiple_choices: + return multiple_choices; + case basic_response::moved_permanently: + return moved_permanently; + case basic_response::moved_temporarily: + return moved_temporarily; + case basic_response::not_modified: + return not_modified; + case basic_response::bad_request: + return bad_request; + case basic_response::unauthorized: + return unauthorized; + case basic_response::forbidden: + return forbidden; + case basic_response::not_found: + return not_found; + case basic_response::not_supported: + return not_supported; + case basic_response::not_acceptable: + return not_acceptable; + case basic_response::internal_server_error: + return internal_server_error; + case basic_response::not_implemented: + return not_implemented; + case basic_response::bad_gateway: + return bad_gateway; + case basic_response::service_unavailable: + return service_unavailable; + default: + return internal_server_error; + } + } + + boost::asio::const_buffer to_buffer(status_type status) { + using boost::asio::buffer; + static const String ok = + "HTTP/1.0 200 OK\r\n"; + static const String created = + "HTTP/1.0 201 Created\r\n"; + static const String accepted = + "HTTP/1.0 202 Accepted\r\n"; + static const String no_content = + "HTTP/1.0 204 No Content\r\n"; + static const String multiple_choices = + "HTTP/1.0 300 Multiple Choices\r\n"; + static const String moved_permanently = + "HTTP/1.0 301 Moved Permanently\r\n"; + static const String moved_temporarily = + "HTTP/1.0 302 Moved Temporarily\r\n"; + static const String not_modified = + "HTTP/1.0 304 Not Modified\r\n"; + static const String bad_request = + "HTTP/1.0 400 Bad Request\r\n"; + static const String unauthorized = + "HTTP/1.0 401 Unauthorized\r\n"; + static const String forbidden = + "HTTP/1.0 403 Forbidden\r\n"; + static const String not_found = + "HTTP/1.0 404 Not Found\r\n"; + static const String not_supported = + "HTTP/1.0 405 Method Not Supported\r\n"; + static const String not_acceptable = + "HTTP/1.0 406 Method Not Acceptable\r\n"; + static const String internal_server_error = + "HTTP/1.0 500 Internal Server Error\r\n"; + static const String not_implemented = + "HTTP/1.0 501 Not Implemented\r\n"; + static const String bad_gateway = + "HTTP/1.0 502 Bad Gateway\r\n"; + static const String service_unavailable = + "HTTP/1.0 503 Service Unavailable\r\n"; + + switch (status) { + case basic_response::ok: + return buffer(ok); + case basic_response::created: + return buffer(created); + case basic_response::accepted: + return buffer(accepted); + case basic_response::no_content: + return buffer(no_content); + case basic_response::multiple_choices: + return buffer(multiple_choices); + case basic_response::moved_permanently: + return buffer(moved_permanently); + case basic_response::moved_temporarily: + return buffer(moved_temporarily); + case basic_response::not_modified: + return buffer(not_modified); + case basic_response::bad_request: + return buffer(bad_request); + case basic_response::unauthorized: + return buffer(unauthorized); + case basic_response::forbidden: + return buffer(forbidden); + case basic_response::not_found: + return buffer(not_found); + case basic_response::not_supported: + return buffer(not_supported); + case basic_response::not_acceptable: + return buffer(not_acceptable); + case basic_response::internal_server_error: + return buffer(internal_server_error); + case basic_response::not_implemented: + return buffer(not_implemented); + case basic_response::bad_gateway: + return buffer(bad_gateway); + case basic_response::service_unavailable: + return buffer(service_unavailable); + default: + return buffer(internal_server_error); } + } - boost::asio::const_buffer to_buffer(status_type status) { - using boost::asio::buffer; - static const string_type ok = - "HTTP/1.0 200 OK\r\n"; - static const string_type created = - "HTTP/1.0 201 Created\r\n"; - static const string_type accepted = - "HTTP/1.0 202 Accepted\r\n"; - static const string_type no_content = - "HTTP/1.0 204 No Content\r\n"; - static const string_type multiple_choices = - "HTTP/1.0 300 Multiple Choices\r\n"; - static const string_type moved_permanently = - "HTTP/1.0 301 Moved Permanently\r\n"; - static const string_type moved_temporarily = - "HTTP/1.0 302 Moved Temporarily\r\n"; - static const string_type not_modified = - "HTTP/1.0 304 Not Modified\r\n"; - static const string_type bad_request = - "HTTP/1.0 400 Bad Request\r\n"; - static const string_type unauthorized = - "HTTP/1.0 401 Unauthorized\r\n"; - static const string_type forbidden = - "HTTP/1.0 403 Forbidden\r\n"; - static const string_type not_found = - "HTTP/1.0 404 Not Found\r\n"; - static const string_type not_supported = - "HTTP/1.0 405 Method Not Supported\r\n"; - static const string_type not_acceptable = - "HTTP/1.0 406 Method Not Acceptable\r\n"; - static const string_type internal_server_error = - "HTTP/1.0 500 Internal Server Error\r\n"; - static const string_type not_implemented = - "HTTP/1.0 501 Not Implemented\r\n"; - static const string_type bad_gateway = - "HTTP/1.0 502 Bad Gateway\r\n"; - static const string_type service_unavailable = - "HTTP/1.0 503 Service Unavailable\r\n"; - - switch (status) { - case basic_response::ok: - return buffer(ok); - case basic_response::created: - return buffer(created); - case basic_response::accepted: - return buffer(accepted); - case basic_response::no_content: - return buffer(no_content); - case basic_response::multiple_choices: - return buffer(multiple_choices); - case basic_response::moved_permanently: - return buffer(moved_permanently); - case basic_response::moved_temporarily: - return buffer(moved_temporarily); - case basic_response::not_modified: - return buffer(not_modified); - case basic_response::bad_request: - return buffer(bad_request); - case basic_response::unauthorized: - return buffer(unauthorized); - case basic_response::forbidden: - return buffer(forbidden); - case basic_response::not_found: - return buffer(not_found); - case basic_response::not_supported: - return buffer(not_supported); - case basic_response::not_acceptable: - return buffer(not_acceptable); - case basic_response::internal_server_error: - return buffer(internal_server_error); - case basic_response::not_implemented: - return buffer(not_implemented); - case basic_response::bad_gateway: - return buffer(bad_gateway); - case basic_response::service_unavailable: - return buffer(service_unavailable); - default: - return buffer(internal_server_error); - } - } - - }; +}; } // namespace http diff --git a/boost/network/protocol/http/message/directives/status.hpp b/boost/network/protocol/http/message/directives/status.hpp index 6595658b7..2b910d595 100644 --- a/boost/network/protocol/http/message/directives/status.hpp +++ b/boost/network/protocol/http/message/directives/status.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/header.hpp b/boost/network/protocol/http/message/header.hpp index 052ece94b..e842ebd45 100644 --- a/boost/network/protocol/http/message/header.hpp +++ b/boost/network/protocol/http/message/header.hpp @@ -21,79 +21,24 @@ namespace boost { namespace network { namespace http { - template - struct unsupported_string; - - struct request_header_narrow { - typedef std::string string_type; - std::string name, value; - }; - - struct request_header_wide { - typedef std::wstring string_type; - std::wstring name, value; - }; - - template struct request_header { - typedef unsupported_string type; - }; - - template - struct request_header >::type> { - typedef request_header_narrow type; - }; - - template - struct request_header >::type> { - typedef request_header_wide type; + std::string name, value; }; - inline void swap(request_header_narrow & l, request_header_narrow & r) { - swap(l.name, r.name); - swap(l.value, r.value); - } - - inline void swap(request_header_wide & l, request_header_wide & r) { + inline void swap(request_header & l, request_header & r) { swap(l.name, r.name); swap(l.value, r.value); } - struct response_header_narrow { - typedef std::string string_type; - std::string name, value; - }; - - struct response_header_wide { - typedef std::wstring string_type; - std::wstring name, value; - }; - - template struct response_header { - typedef unsupported_string type; - }; - - template - struct response_header >::type> { - typedef response_header_wide type; - }; - - template - struct response_header >::type> { - typedef response_header_narrow type; + std::string name, value; }; - inline void swap(response_header_narrow & l, response_header_narrow & r) { + inline void swap(response_header & l, response_header & r) { std::swap(l.name, r.name); std::swap(l.value, r.value); } - inline void swap(response_header_wide & l, response_header_wide & r) { - std::swap(l.name, r.name); - std::swap(l.value, r.value); - } - } // namespace http } // namespace network @@ -101,27 +46,15 @@ namespace boost { namespace network { namespace http { } // namespace boost BOOST_FUSION_ADAPT_STRUCT( - boost::network::http::request_header_narrow, + boost::network::http::request_header, (std::string, name) (std::string, value) ) BOOST_FUSION_ADAPT_STRUCT( - boost::network::http::request_header_wide, - (std::wstring, name) - (std::wstring, value) - ) - -BOOST_FUSION_ADAPT_STRUCT( - boost::network::http::response_header_narrow, + boost::network::http::response_header, (std::string, name) (std::string, value) ) -BOOST_FUSION_ADAPT_STRUCT( - boost::network::http::response_header_wide, - (std::wstring, name) - (std::wstring, value) - ) - #endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 diff --git a/boost/network/protocol/http/message/message_base.hpp b/boost/network/protocol/http/message/message_base.hpp deleted file mode 100644 index bc27bd03c..000000000 --- a/boost/network/protocol/http/message/message_base.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 - -// Copyright 2010 (c) Dean Michael Berris -// Copyright 2010 (c) Sinefunc, Inc. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -namespace boost { namespace network { namespace http { - - template - struct async_message; - - template - struct message_impl; - - template - struct message_base - : mpl::if_< - is_async, - async_message, - message_impl - > - {}; - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 diff --git a/boost/network/protocol/http/message/modifiers/body.hpp b/boost/network/protocol/http/message/modifiers/body.hpp deleted file mode 100644 index 40523b4ea..000000000 --- a/boost/network/protocol/http/message/modifiers/body.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - namespace impl { - - template - void body(basic_response & response, T const & value, mpl::false_ const &) { - response << ::boost::network::body(value); - } - - template - void body(basic_response & response, T const & future, mpl::true_ const &) { - response.body(future); - } - - } - - template - inline void - body(basic_response & response, T const & value) { - impl::body(response, value, is_async()); - } - - template - inline void - body_impl(basic_request & request, T const & value, tags::server) { - request.body = value; - } - - template - inline void - body_impl(basic_request & request, T const & value, tags::client) { - request << ::boost::network::body(value); - } - - template - inline void - body(basic_request & request, T const & value) { - body_impl(request, value, typename client_or_server::type()); - } - -} // namespace http - - namespace impl { - - template - inline void body(Message const & message, ValueType const & body_, http::tags::http_server, Async) { - message.body = body_; - } - - } /* impl */ - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 diff --git a/boost/network/protocol/http/message/modifiers/destination.hpp b/boost/network/protocol/http/message/modifiers/destination.hpp deleted file mode 100644 index d67958653..000000000 --- a/boost/network/protocol/http/message/modifiers/destination.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - namespace impl { - - template - void destination(basic_response & response, T const & value, mpl::false_ const &) { - response << ::boost::network::destination(value); - } - - template - void destination(basic_response & response, T const & future, mpl::true_ const &) { - response.destination(future); - } - - } - - template - inline void - destination(basic_response & response, T const & value) { - impl::destination(response, value, is_async()); - } - - template - struct ServerRequest; - - template - inline void - destination_impl(basic_request & request, T const & value, tags::server) { - request.destination = value; - } - - template - inline void - destination_impl(basic_request & request, T const & value, tags::pod) { - request.destination = value; - } - - template - inline void - destination_impl(basic_request & request, T const & value, tags::normal) { - request.destination(value); - } - - template - inline void - destination_impl(basic_request & request, T const & value, tags::client) { - destination_impl(request, value, typename pod_or_normal::type()); - } - - template - inline void - destination(basic_request & request, T const & value) { - destination_impl(request, value, typename client_or_server::type()); - } - -} // namespace http - - namespace impl { - - template - inline void destination(Message const & message, ValueType const & destination_, http::tags::http_server, Async) { - message.destination = destination_; - } - - } /* impl */ - -} // namespace network - -} // namespace boost - -#include - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 diff --git a/boost/network/protocol/http/message/modifiers/headers.hpp b/boost/network/protocol/http/message/modifiers/headers.hpp deleted file mode 100644 index 9bfcec4fc..000000000 --- a/boost/network/protocol/http/message/modifiers/headers.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - namespace impl { - - template - void headers(basic_response & response, T const & value, mpl::false_ const &) { - response << headers(value); - } - - template - void headers(basic_response & response, T const & future, mpl::true_ const &) { - response.headers(future); - } - - template - void headers(basic_request & request, T const & value, tags::server const &) { - request.headers = value; - } - - } - - template - inline void - headers(basic_response & response, T const & value) { - impl::headers(response, value, is_async()); - } - - template - inline void - headers(basic_request & request, T const & value) { - impl::headers(request, value, Tag()); - } - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 diff --git a/boost/network/protocol/http/message/modifiers/source.hpp b/boost/network/protocol/http/message/modifiers/source.hpp deleted file mode 100644 index 4fa537b6a..000000000 --- a/boost/network/protocol/http/message/modifiers/source.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 - -// Copyright 2010 (C) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - namespace impl { - - template - void source(basic_response & response, T const & value, mpl::false_ const &) { - response << ::boost::network::source(value); - } - - template - void source(basic_response & response, T const & future, mpl::true_ const &) { - response.source(future); - } - - template - void source(basic_request & request, T const & value, tags::server const &) { - request.source = value; - } - - template - void source(basic_request & request, T const & value, tags::client const &) { - request << ::boost::network::source(value); - } - - } - - template - inline void - source(basic_response & response, T const & value) { - impl::source(response, value, is_async()); - } - - template - inline void - source_impl(basic_request & request, T const & value, tags::server) { - impl::source(request, value, Tag()); - } - - template - inline void - source_impl(basic_request & request, T const & value, tags::client) { - impl::source(request, value, Tag()); - } - - template - inline void - source(basic_request & request, T const & value) { - source_impl(request, value, typename client_or_server::type()); - } - -} // namespace http - - namespace impl { - - template - inline void source(Message const & message, ValueType const & source_, http::tags::http_server const &, Async const &) { - message.source = source_; - } - - } /* impl */ - -} // namespace network - -} // namespace boost - -#include -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 diff --git a/boost/network/protocol/http/message/modifiers/status.hpp b/boost/network/protocol/http/message/modifiers/status.hpp index dfcd305e8..ca6024e09 100644 --- a/boost/network/protocol/http/message/modifiers/status.hpp +++ b/boost/network/protocol/http/message/modifiers/status.hpp @@ -7,31 +7,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_response; - - namespace impl { - - template - void status(basic_response & response, T const & value, mpl::false_ const &) { - response << boost::network::http::status(value); - } - - template - void status(basic_response & response, T const & future, mpl::true_ const &) { - response.status(future); - } - - } // namespace impl - - template - void status(basic_response & response, T const & value) { - impl::status(response, value, is_async()); - } +inline void status(response_base & response, std::string const & value) { + response.set_status(value); +} } // namespace http diff --git a/boost/network/protocol/http/message/modifiers/status_message.hpp b/boost/network/protocol/http/message/modifiers/status_message.hpp index bcd92bcb8..3d24601cc 100644 --- a/boost/network/protocol/http/message/modifiers/status_message.hpp +++ b/boost/network/protocol/http/message/modifiers/status_message.hpp @@ -7,31 +7,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_response; - - namespace impl { - - template - void status_message(basic_response & response, T const & value, mpl::false_ const &) { - response << boost::network::http::status_message(value); - } - - template - void status_message(basic_response & response, T const & future, mpl::true_ const &) { - response.status_message(future); - } - - } // namespace impl - - template - void status_message(basic_response & response, T const & value) { - impl::status_message(response, value, is_async()); - } +inline void status_message(response_base & response, std::string const & value) { + response.set_status_message(value); +} } // namespace http diff --git a/boost/network/protocol/http/message/modifiers/version.hpp b/boost/network/protocol/http/message/modifiers/version.hpp index 0077ca4f6..ee668fc07 100644 --- a/boost/network/protocol/http/message/modifiers/version.hpp +++ b/boost/network/protocol/http/message/modifiers/version.hpp @@ -7,32 +7,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_response; - - namespace impl { - - template - void version(basic_response & response, T const & value, mpl::false_ const &) { - response << boost::network::http::version(value); - } - - template - void version(basic_response & response, T const & future, mpl::true_ const &) { - response.version(future); - } - - } // namespace impl - - template - void version(basic_response & response, T const & value) { - impl::version(response, value, is_async()); - } +inline void version(response_base & response, std::string const & value) { + response.set_version(value); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/destination.hpp b/boost/network/protocol/http/message/wrappers/destination.hpp deleted file mode 100644 index bf851aac7..000000000 --- a/boost/network/protocol/http/message/wrappers/destination.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 - -// Copyright 2010 (c) Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - template - struct Request; - - template - struct Response; - - BOOST_NETWORK_DEFINE_HTTP_WRAPPER(destination, destination, destination); - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 diff --git a/boost/network/protocol/http/message/wrappers/source.hpp b/boost/network/protocol/http/message/wrappers/source.hpp deleted file mode 100644 index be5f67ea9..000000000 --- a/boost/network/protocol/http/message/wrappers/source.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - BOOST_NETWORK_DEFINE_HTTP_WRAPPER(source, source, source); - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 diff --git a/boost/network/protocol/http/message/wrappers/status.hpp b/boost/network/protocol/http/message/wrappers/status.hpp index 2fc860a94..4c06a6eab 100644 --- a/boost/network/protocol/http/message/wrappers/status.hpp +++ b/boost/network/protocol/http/message/wrappers/status.hpp @@ -11,39 +11,22 @@ namespace boost { namespace network { namespace http { - template - struct basic_response; - - namespace impl { - - template - struct status_wrapper { - - basic_response const & response_; - - explicit status_wrapper(basic_response const & response) - : response_(response) {} - - status_wrapper(status_wrapper const & other) - : response_(other.response_) {} - - operator boost::uint16_t () { - return response_.status(); - } - - }; - - } // namespace impl - - template - struct Response; - - template - inline - impl::status_wrapper - status(basic_response const & response) { - return impl::status_wrapper(response); - } +namespace impl { + +struct status_wrapper { + explicit status_wrapper(response_base & response_); + operator std::string () const; + private: + response_base & response_; +}; + +} // namespace impl + +inline +impl::status_wrapper +status(response_base & response) { + return impl::status_wrapper(response); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/status_message.hpp b/boost/network/protocol/http/message/wrappers/status_message.hpp index 99f29658d..a7c19165c 100644 --- a/boost/network/protocol/http/message/wrappers/status_message.hpp +++ b/boost/network/protocol/http/message/wrappers/status_message.hpp @@ -7,40 +7,31 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - namespace impl { - - template - struct status_message_wrapper { +#include - typedef typename string::type string_type; - - basic_response const & response_; - - explicit status_message_wrapper(basic_response const & response) - : response_(response) {} +namespace boost { namespace network { namespace http { - status_message_wrapper(status_message_wrapper const & other) - : response_(other.response_) {} +namespace impl { - operator string_type () { - return response_.status_message(); - } +struct status_message_wrapper { + explicit status_message_wrapper(response_base & response_); + operator std::string () const; + private: + response_base & response_; + mutable optional cache_; +}; - }; +inline std::ostream & operator<<(std::ostream & os, status_message_wrapper const & status_message) { + return os << static_cast(status_message); +} - } // namespace impl +} // namespace impl - template - inline - impl::status_message_wrapper - status_message(basic_response const & response) { - return impl::status_message_wrapper(response); - } +inline +impl::status_message_wrapper +status_message(response_base & response) { + return impl::status_message_wrapper(response); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/uri.hpp b/boost/network/protocol/http/message/wrappers/uri.hpp index 622d53a4a..222f24e09 100644 --- a/boost/network/protocol/http/message/wrappers/uri.hpp +++ b/boost/network/protocol/http/message/wrappers/uri.hpp @@ -8,33 +8,27 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include namespace boost { namespace network { namespace http { - template - struct basic_request; - - namespace impl { - template - struct uri_wrapper { - basic_request const & message_; - uri_wrapper(basic_request const & message) - : message_(message) {} - typedef typename basic_request::string_type string_type; - operator string_type() { - return message_.uri().raw(); - } - operator boost::network::uri::basic_uri::type> () { - return message_.uri(); - } - }; - } - - template inline - impl::uri_wrapper - uri(basic_request const & request) { - return impl::uri_wrapper(request); - } +namespace impl { + +struct uri_wrapper { + explicit uri_wrapper(request_base & request_); + operator std::string() const; + operator boost::network::uri::uri() const; + private: + request_base & request_; +}; + +} // namespace impl + +inline +impl::uri_wrapper +uri(request_base & request) { + return impl::uri_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/version.hpp b/boost/network/protocol/http/message/wrappers/version.hpp index b3e16d2fc..6b8f0b7d3 100644 --- a/boost/network/protocol/http/message/wrappers/version.hpp +++ b/boost/network/protocol/http/message/wrappers/version.hpp @@ -9,38 +9,27 @@ namespace boost { namespace network { namespace http { - template - struct basic_response; - - namespace impl { - - template - struct version_wrapper { - - typedef typename string::type string_type; - - basic_response const & response_; - - explicit version_wrapper(basic_response const & response) - : response_(response) {} - - version_wrapper(version_wrapper const & other) - : response_(other.response_) {} - - operator string_type () { - return response_.version(); - } - - }; - - } // namespace impl - - template - inline - impl::version_wrapper - version(basic_response const & response) { - return impl::version_wrapper(response); - } +namespace impl { + +struct version_wrapper { + explicit version_wrapper(response_base & response_); + operator std::string() const; + private: + response_base & response_; + mutable optional cache_; +}; + +inline std::ostream & operator<< (std::ostream & os, version_wrapper const & version) { + return os << static_cast(version); +} + +} // namespace impl + +inline +impl::version_wrapper +version(response_base & response) { + return impl::version_wrapper(response); +} } // namespace http diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index ef5927ba5..7b10f5586 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -29,15 +29,9 @@ #include #include #include -#include -#include -#include -#include #include #include #include -#include -#include #include #include diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index bf9a00005..080ba77f8 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -9,6 +9,8 @@ #include +struct response_base; + #include #include #include @@ -18,61 +20,16 @@ #include #include #include -#include -#include -#include -#include #include #include #include -#include -#include #include -#include -#include #include namespace boost { namespace network { namespace http { - template - struct basic_response : public message_base::type { - - typedef typename string::type string_type; - - private: - typedef typename message_base::type base_type; - - public: - - typedef Tag tag; - - basic_response() - : base_type() - {} - - basic_response(basic_response const & other) - : base_type(other) - {} - - basic_response & operator=(basic_response rhs) { - rhs.swap(*this); - return *this; - }; - - void swap(basic_response & other) { - base_type & base_ref(other), - & this_ref(*this); - std::swap(this_ref, base_ref); - }; - }; - - template - inline void swap(basic_response & lhs, basic_response & rhs) { - lhs.swap(rhs); - } - } // namespace http } // namespace network diff --git a/boost/network/protocol/http/response_concept.hpp b/boost/network/protocol/http/response_concept.hpp index 9d067532d..25094ca40 100644 --- a/boost/network/protocol/http/response_concept.hpp +++ b/boost/network/protocol/http/response_concept.hpp @@ -23,9 +23,9 @@ namespace boost { namespace network { namespace http { R response_; swap(response, response_); // swappable via ADL - typedef typename traits::version::type version_type; - typedef typename traits::status::type status_type; - typedef typename traits::status_message::type status_message_type; + typedef std::string version_type; + typedef std::string status_type; + typedef std::string status_message_type; response << version(version_type()) // version directive << status(status_type()) // status directive diff --git a/boost/network/protocol/http/server/impl/parsers.ipp b/boost/network/protocol/http/server/impl/parsers.ipp index e39c7b26d..848b0fc4d 100644 --- a/boost/network/protocol/http/server/impl/parsers.ipp +++ b/boost/network/protocol/http/server/impl/parsers.ipp @@ -35,7 +35,7 @@ namespace boost { namespace network { namespace http { , version_pair); } - BOOST_NETWORK_INLINE void parse_headers(std::string const & input, std::vector & container) { + BOOST_NETWORK_INLINE void parse_headers(std::string const & input, std::vector & container) { using namespace boost::spirit::qi; parse( input.begin(), input.end(), From d0ad12298162c69240a38c3796a1cebdea85a076 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 30 Sep 2011 17:37:11 +1000 Subject: [PATCH 027/438] Minimal interface required for responses. --- boost/network/protocol/http/response_base.hpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 boost/network/protocol/http/response_base.hpp diff --git a/boost/network/protocol/http/response_base.hpp b/boost/network/protocol/http/response_base.hpp new file mode 100644 index 000000000..284ca7a3f --- /dev/null +++ b/boost/network/protocol/http/response_base.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_BASE_HPP_20110930 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_BASE_HPP_20110930 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { namespace http { + +struct response_base : message_base { + virtual void set_status(std::string const & new_status) = 0; + virtual void set_status_message(std::string const & new_status_message) = 0; + virtual void set_version(std::string const & new_version) = 0; + virtual ~response_base() = 0; +}; + +response_base::~response_base() {} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_BASE_HPP_20110930 */ From b1cfe58bc65ab11043f199a2ebf86fcb1a3ba185 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 8 Oct 2011 16:19:13 +1100 Subject: [PATCH 028/438] WIP: Ongoing refactoring... --- boost/network/constants.hpp | 169 +++--------------- boost/network/constants.ipp | 126 +++++++++++++ boost/network/protocol/http/client.hpp | 10 +- .../protocol/http/client/async_impl.hpp | 94 ---------- boost/network/protocol/http/client/base.hpp | 48 +++++ boost/network/protocol/http/client/base.ipp | 112 ++++++++++++ .../http/client/connection_manager.hpp | 10 +- boost/network/protocol/http/client/facade.hpp | 40 ++--- .../http/message/modifiers/clear_headers.hpp | 46 ----- .../http/message/modifiers/method.hpp | 13 +- .../protocol/http/message/wrappers/body.hpp | 71 -------- .../http/message/wrappers/headers.hpp | 126 ------------- .../protocol/http/message/wrappers/method.hpp | 36 ++-- boost/network/protocol/http/request.hpp | 68 +++++-- boost/network/protocol/http/request.ipp | 68 +------ boost/network/protocol/http/request_base.hpp | 67 +++++++ boost/network/protocol/http/response.hpp | 39 +++- 17 files changed, 506 insertions(+), 637 deletions(-) create mode 100644 boost/network/constants.ipp delete mode 100644 boost/network/protocol/http/client/async_impl.hpp create mode 100644 boost/network/protocol/http/client/base.hpp create mode 100644 boost/network/protocol/http/client/base.ipp delete mode 100644 boost/network/protocol/http/message/modifiers/clear_headers.hpp delete mode 100644 boost/network/protocol/http/message/wrappers/body.hpp delete mode 100644 boost/network/protocol/http/message/wrappers/headers.hpp create mode 100644 boost/network/protocol/http/request_base.hpp diff --git a/boost/network/constants.hpp b/boost/network/constants.hpp index 3f03d6d6c..12d7e33b3 100644 --- a/boost/network/constants.hpp +++ b/boost/network/constants.hpp @@ -6,149 +6,36 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - namespace boost { namespace network { - namespace impl { - template - struct constants_narrow { - - static char const * crlf() { - static char crlf_[] = { '\r', '\n', 0 }; - return crlf_; - } - - static char const * dot() { - static char dot_[] = { '.', 0 }; - return dot_; - } - - static char dot_char() { return '.'; } - - static char const * http_slash() { - static char http_slash_[] = { 'H', 'T', 'T', 'P', '/', 0 }; - return http_slash_; - } - - static char const * space() { - static char space_[] = {' ', 0}; - return space_; - } - - static char space_char() { return ' '; } - - static char const * slash() { - static char slash_[] = {'/', 0}; - return slash_; - } - - static char slash_char() { return '/'; } - - static char const * host() { - static char host_[] = {'H', 'o', 's', 't', 0}; - return host_; - } - - static char const * colon() { - static char colon_[] = {':', 0}; - return colon_; - } - - static char colon_char() { return ':'; } - - static char const * accept() { - static char accept_[] = {'A', 'c', 'c', 'e', 'p', 't', 0}; - return accept_; - } - - static char const * default_accept_mime() { - static char mime_[] = { - '*', '/', '*', 0 - }; - return mime_; - } - - static char const * accept_encoding() { - static char accept_encoding_[] = { - 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0 - }; - return accept_encoding_; - } - - static char const * default_accept_encoding() { - static char default_accept_encoding_[] = { - 'i','d','e','n','t','i','t','y',';','q','=','1','.','0',',',' ','*',';','q','=','0',0 - }; - return default_accept_encoding_; - } - - static char const * user_agent() { - static char user_agent_[] = { - 'U','s','e','r','-','A','g','e','n','t',0 - }; - return user_agent_; - } - - static char const * cpp_netlib_slash() { - static char cpp_netlib_slash_[] = { - 'c','p','p','-','n','e','t','l','i','b','/',0 - }; - return cpp_netlib_slash_; - } - - static char question_mark_char() { - return '?'; - } - - static char hash_char() { - return '#'; - } - - static char const * connection() { - static char connection_[] = { - 'C','o','n','n','e','c','t','i','o','n',0 - }; - return connection_; - } - - static char const * close() { - static char close_[] = { - 'C','l','o','s','e', 0 - }; - return close_; - } - - static char const * https() { - static char https_[] = "https"; - return https_; - } - - }; - - template - struct constants_wide { - - static wchar_t const * https() { - static wchar_t https_[] = L"https"; - return https_; - } - - }; - } - - template - struct constants : - mpl::if_< - is_default_string, - impl::constants_narrow, - typename mpl::if_< - is_default_wstring, - impl::constants_wide, - unsupported_tag - >::type - >::type - {}; +struct constants { + static char const * crlf(); + static char const * dot(); + static char dot_char(); + static char const * http_slash(); + static char const * space(); + static char space_char(); + static char const * slash(); + static char slash_char(); + static char const * host(); + static char const * colon(); + static char colon_char(); + static char const * accept(); + static char const * default_accept_mime(); + static char const * accept_encoding(); + static char const * default_accept_encoding(); + static char const * user_agent(); + static char const * cpp_netlib_slash(); + static char question_mark_char(); + static char hash_char(); + static char const * connection(); + static char const * close(); + static char const * https(); +}; + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif } // namespace network diff --git a/boost/network/constants.ipp b/boost/network/constants.ipp new file mode 100644 index 000000000..86ac0ffc8 --- /dev/null +++ b/boost/network/constants.ipp @@ -0,0 +1,126 @@ +#ifndef BOOST_NETWORK_CONSTANTS_HPP_20111008 +#define BOOST_NETWORK_CONSTANTS_HPP_20111008 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { + +char const * constants::crlf() { + static char crlf_[] = { '\r', '\n', 0 }; + return crlf_; +} + +char const * constants::dot() { + static char dot_[] = { '.', 0 }; + return dot_; +} + +char constants::dot_char() { return '.'; } + +char const * constants::http_slash() { + static char http_slash_[] = { 'H', 'T', 'T', 'P', '/', 0 }; + return http_slash_; +} + +char const * constants::space() { + static char space_[] = {' ', 0}; + return space_; +} + +char constants::space_char() { return ' '; } + +char const * constants::slash() { + static char slash_[] = {'/', 0}; + return slash_; +} + +char constants::slash_char() { return '/'; } + +char const * constants::host() { + static char host_[] = {'H', 'o', 's', 't', 0}; + return host_; +} + +char const * constants::colon() { + static char colon_[] = {':', 0}; + return colon_; +} + +char constants::colon_char() { return ':'; } + +char const * constants::accept() { + static char accept_[] = {'A', 'c', 'c', 'e', 'p', 't', 0}; + return accept_; +} + +char const * constants::default_accept_mime() { + static char mime_[] = { + '*', '/', '*', 0 + }; + return mime_; +} + +char const * constants::accept_encoding() { + static char accept_encoding_[] = { + 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0 + }; + return accept_encoding_; +} + +char const * constants::default_accept_encoding() { + static char default_accept_encoding_[] = { + 'i','d','e','n','t','i','t','y',';','q','=','1','.','0',',',' ','*',';','q','=','0',0 + }; + return default_accept_encoding_; +} + +char const * constants::user_agent() { + static char user_agent_[] = { + 'U','s','e','r','-','A','g','e','n','t',0 + }; + return user_agent_; +} + +char const * constants::cpp_netlib_slash() { + static char cpp_netlib_slash_[] = { + 'c','p','p','-','n','e','t','l','i','b','/',0 + }; + return cpp_netlib_slash_; +} + +char constants::question_mark_char() { + return '?'; +} + +char constants::hash_char() { + return '#'; +} + +char const * constants::connection() { + static char connection_[] = { + 'C','o','n','n','e','c','t','i','o','n',0 + }; + return connection_; +} + +char const * constants::close() { + static char close_[] = { + 'C','l','o','s','e', 0 + }; + return close_; +} + +char const * constants::https() { + static char https_[] = "https"; + return https_; +} + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_CONSTANTS_HPP_20111008 */ diff --git a/boost/network/protocol/http/client.hpp b/boost/network/protocol/http/client.hpp index 2d45ff2df..85c3bb583 100644 --- a/boost/network/protocol/http/client.hpp +++ b/boost/network/protocol/http/client.hpp @@ -12,18 +12,18 @@ #include #include #include +#include +#include namespace boost { namespace network { namespace http { -template -struct basic_client : basic_client_facade { +struct client : basic_client_facade { private: typedef basic_client_facade base_facade_type; public: - typedef basic_request request; - typedef basic_response response; - typedef String string_type; + typedef ::boost::network::http::request request; + typedef ::boost::network::http::response response; // Constructor // ================================================================= diff --git a/boost/network/protocol/http/client/async_impl.hpp b/boost/network/protocol/http/client/async_impl.hpp deleted file mode 100644 index 2fbd5d488..000000000 --- a/boost/network/protocol/http/client/async_impl.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 -#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 - -// Copyright Dean Michael Berris 2010. -// Copyright 2011 Dean Michael Berris (dberris@google.com). -// Copyright 2011 Google, Inc. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { - - template - struct basic_client_impl; - - namespace impl { - template - struct async_client - { - typedef - typename string::type - string_type; - - typedef - function const &, system::error_code const &)> - body_callback_function_type; - - async_client(shared_ptr connection_manager) - : service_ptr(new boost::asio::io_service), - service_(*service_ptr), - sentinel_(new boost::asio::io_service::work(service_)), - connection_manager_(connection_manager) - { - lifetime_thread_.reset(new boost::thread( - boost::bind( - &boost::asio::io_service::run, - &service_ - ))); - } - - async_client(boost::asio::io_service & service, - shared_ptr connection_manager) - : service_ptr(0), - service_(service), - sentinel_(new boost::asio::io_service::work(service_)), - connection_manager_(connection_manager) - { - } - - ~async_client() throw () - { - sentinel_.reset(); - connection_manager_->reset(); - if (lifetime_thread_.get()) { - lifetime_thread_->join(); - lifetime_thread_.reset(); - } - delete service_ptr; - } - - basic_response const request_skeleton( - basic_request const & request_, - string_type const & method, - bool get_body, - body_callback_function_type callback - ) - { - shared_ptr connection_; - connection_ = connection_manager_->get_connection(service_, request_); - shared_ptr response = connection_->send_request( - method, request_, get_body, callback); - return *response; - } - - boost::asio::io_service * service_ptr; - boost::asio::io_service & service_; - boost::shared_ptr sentinel_; - boost::shared_ptr lifetime_thread_; - shared_ptr connection_manager_; - }; - } // namespace impl - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 diff --git a/boost/network/protocol/http/client/base.hpp b/boost/network/protocol/http/client/base.hpp new file mode 100644 index 000000000..7e3eff5bc --- /dev/null +++ b/boost/network/protocol/http/client/base.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_BASE_HPP_20111008 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_BASE_HPP_20111008 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct client_base_pimpl; + +struct client_base { + typedef + function const &, system::error_code const &)> + body_callback_function_type; + + client_base(shared_ptr connection_manager_); + client_base(asio::io_service & service, + shared_ptr connection_manager_); + ~client_base(); + response const request_skeleton(request_base const & request_, + std::string const & method, + bool get_body, + body_callback_function_type callback); + private: + client_base_pimpl * pimpl; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_BASE_HPP_20111008 */ diff --git a/boost/network/protocol/http/client/base.ipp b/boost/network/protocol/http/client/base.ipp new file mode 100644 index 000000000..8140f67e4 --- /dev/null +++ b/boost/network/protocol/http/client/base.ipp @@ -0,0 +1,112 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct client_base_pimpl { + typedef + function const &, system::error_code const &)> + body_callback_function_type; + client_base_pimpl(shared_ptr connection_manager_); + client_base_pimpl(io_service & service, shared_ptr connection_manager_); + response const request_skeleton(request const & request_, + std::string const & method, + bool get_body, + body_callback_function_type callback); + ~client_base_pimpl(); + private: + boost::asio::io_service * service_ptr; + boost::asio::io_service & service_; + boost::shared_ptr sentinel_; + boost::shared_ptr lifetime_thread_; + shared_ptr connection_manager_; +}; + +client_base::client_base(shared_ptr connection_manager_) +: pimpl(new (std::nothrow) client_base_pimpl(connection_manager_)) +{} + +client_base::client_base(asio::io_service & service, + shared_ptr connection_manager_) +: pimpl(new (std::nothrow) client_base_pimpl(service, connection_manager_)) +{} + +response const client_base::request_skeleton(request_base const & request_, + std::string const & method, + bool get_body, + body_callback_function_type callback) { + return pimpl->request_skeleton(request_, method, get_body, callback); +} + +client_base::~client_base() { + delete pimpl; +} + +client_base_pimpl::client_base_pimpl(shared_ptr connection_manager) + : service_ptr(new (std::nothrow) boost::asio::io_service), + service_(*service_ptr), + sentinel_(new (std::nothrow) boost::asio::io_service::work(service_)), + connection_manager_(connection_manager) +{ + lifetime_thread_.reset(new (std::nothrow) boost::thread( + boost::bind( + &boost::asio::io_service::run, + &service_ + ))); + if (!lifetime_thread_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot allocate client lifetime thread; not enough memory.")); +} + +client_base_pimpl::client_base_pimpl(boost::asio::io_service & service, + shared_ptr connection_manager) + : service_ptr(0), + service_(service), + sentinel_(new (std::nothrow) boost::asio::io_service::work(service_)), + connection_manager_(connection_manager) +{ + if (!sentinel_.get()) + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot allocate sentinel; not enough memory.")); +} + +~client_base_pimpl::client_base_pimpl() +{ + sentinel_.reset(); + connection_manager_->reset(); + if (lifetime_thread_.get()) { + lifetime_thread_->join(); + lifetime_thread_.reset(); + } + delete service_ptr; +} + +response const client_base_pimpl::request_skeleton( + request const & request_, + std::string const & method, + bool get_body, + body_callback_function_type callback + ) +{ + shared_ptr connection_; + connection_ = connection_manager_->get_connection(service_, request_); + return connection_->send_request(method, request_, get_body, callback); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 diff --git a/boost/network/protocol/http/client/connection_manager.hpp b/boost/network/protocol/http/client/connection_manager.hpp index aca063ee8..ee5dd7eb2 100644 --- a/boost/network/protocol/http/client/connection_manager.hpp +++ b/boost/network/protocol/http/client/connection_manager.hpp @@ -11,16 +11,16 @@ namespace boost { namespace network { namespace http { struct request_base; -struct response_base; +struct response; struct client_connection { typedef function const &, system::error_code const &)> callback_type; - virtual shared_ptr send_request(std::string const & method, - request_base const & request, - bool get_body, - callback_type callback) = 0; + virtual response send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) = 0; virtual void reset() = 0; virtual ~client_connection() = 0; }; diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index a47f78c7b..6faae3497 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -8,29 +8,17 @@ #include #include -#include +#include #include namespace boost { namespace network { namespace http { -template -struct basic_request; - -template -struct basic_response; - -template struct basic_client_facade { - - typedef typename string::type string_type; - typedef basic_request request; - typedef basic_response response; - typedef basic_client_impl pimpl_type; - typedef function const &,system::error_code const &)> body_callback_function_type; + typedef client_base::body_callback_function_type body_callback_function_type; template basic_client_facade(ArgPack const & args) { - init_pimpl(args, + init_base(args, typename mpl::if_< is_same< typename parameter::value_type::type, @@ -42,7 +30,7 @@ struct basic_client_facade { } BOOST_PARAMETER_MEMBER_FUNCTION((response const), head, tag, (required (request,(request const &)))) { - return pimpl->request_skeleton(request, "HEAD", false, body_callback_function_type()); + return base->request_skeleton(request, "HEAD", false, body_callback_function_type()); } BOOST_PARAMETER_MEMBER_FUNCTION((response const), get , tag, @@ -52,7 +40,7 @@ struct basic_client_facade { (optional (body_handler,(body_callback_function_type),body_callback_function_type()) )) { - return pimpl->request_skeleton(request, "GET", true, body_handler); + return base->request_skeleton(request, "GET", true, body_handler); } BOOST_PARAMETER_MEMBER_FUNCTION((response const), post, tag, @@ -83,7 +71,7 @@ struct basic_client_facade { request << header("Content-Type", content_type); } } - return pimpl->request_skeleton(request, "POST", true, body_handler); + return base->request_skeleton(request, "POST", true, body_handler); } BOOST_PARAMETER_MEMBER_FUNCTION((response const), put , tag, @@ -114,7 +102,7 @@ struct basic_client_facade { request << header("Content-Type", content_type); } } - return pimpl->request_skeleton(request, "PUT", true, body_handler); + return base->request_skeleton(request, "PUT", true, body_handler); } BOOST_PARAMETER_MEMBER_FUNCTION((response const), delete_, tag, @@ -124,11 +112,11 @@ struct basic_client_facade { (optional (body_handler,(body_callback_function_type),body_callback_function_type()) )) { - return pimpl->request_skeleton(request, "DELETE", true, body_handler); + return base->request_skeleton(request, "DELETE", true, body_handler); } void clear_resolved_cache() { - pimpl->clear_resolved_cache(); + base->clear_resolved_cache(); } protected: @@ -136,16 +124,16 @@ struct basic_client_facade { struct no_io_service {}; struct has_io_service {}; - boost::scoped_ptr pimpl; + boost::scoped_ptr base; template - void init_pimpl(ArgPack const & args, no_io_service) { - pimpl.reset(new pimpl_type(this->get_connection_manager(args))); + void init_base(ArgPack const & args, no_io_service) { + base.reset(new base_type(this->get_connection_manager(args))); } template - void init_pimpl(ArgPack const & args, has_io_service) { - pimpl.reset(new pimpl_type(args[_io_service], this->get_connection_manager(args))); + void init_base(ArgPack const & args, has_io_service) { + base.reset(new base_type(args[_io_service], this->get_connection_manager(args))); } private: diff --git a/boost/network/protocol/http/message/modifiers/clear_headers.hpp b/boost/network/protocol/http/message/modifiers/clear_headers.hpp deleted file mode 100644 index 8cf2806aa..000000000 --- a/boost/network/protocol/http/message/modifiers/clear_headers.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 - -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -namespace boost { namespace network { namespace http { - - template - inline void clear_headers_impl(basic_request & request, tags::pod) { - typedef typename basic_request::headers_container_type headers_container; - headers_container().swap(request.headers); - } - - template - inline void clear_headers_impl(basic_request & request, tags::normal) { - request.headers(typename basic_request::headers_container_type()); - } - - template - inline void clear_headers_impl(basic_request & request, tags::client) { - clear_headers_impl(request, typename pod_or_normal::type()); - } - - template - inline void clear_headers_impl(basic_request & request, tags::server) { - typedef typename basic_request::headers_container_type headers_container; - headers_container().swap(request.headers); - } - - template - inline void clear_headers(basic_request & request) { - clear_headers_impl(request, typename client_or_server::type()); - } - -} /* http */ - -} /* network */ - -} /* boost */ - -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 */ diff --git a/boost/network/protocol/http/message/modifiers/method.hpp b/boost/network/protocol/http/message/modifiers/method.hpp index bc23dc78d..f2101479a 100644 --- a/boost/network/protocol/http/message/modifiers/method.hpp +++ b/boost/network/protocol/http/message/modifiers/method.hpp @@ -6,18 +6,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_request; - - template - inline typename enable_if, void>::type - method(basic_request & request, typename string::type const & method_) { - request.method = method_; - } +inline void method(request_base & request, std::string const & method_) { + request.set_method(method_); +} } /* http */ diff --git a/boost/network/protocol/http/message/wrappers/body.hpp b/boost/network/protocol/http/message/wrappers/body.hpp deleted file mode 100644 index 068ab38a9..000000000 --- a/boost/network/protocol/http/message/wrappers/body.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 - -// Copyright 2010 (c) Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -namespace boost { namespace network { namespace http { - - template - struct basic_response; - - template - struct basic_request; - - namespace impl { - - template - struct body_wrapper { - typedef typename string::type string_type; - Message const & message_; - explicit body_wrapper(Message const & message) - : message_(message) {} - body_wrapper(body_wrapper const & other) - : message_(other.message_) {} - - operator string_type () const { - return message_.body(); - } - - size_t size() const { - return message_.body().size(); - } - - boost::iterator_range - range() const - { - return boost::make_iterator_range(message_.body()); - } - }; - - template - inline std::ostream & operator<<(std::ostream & os, body_wrapper const & body) { - os << static_cast::string_type>(body); - return os; - } - - } // namespace impl - - template - inline - typename impl::body_wrapper > - body(basic_response const & message) { - return impl::body_wrapper >(message); - } - - template - inline - typename impl::body_wrapper > - body(basic_request const & message) { - return impl::body_wrapper >(message); - } - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 diff --git a/boost/network/protocol/http/message/wrappers/headers.hpp b/boost/network/protocol/http/message/wrappers/headers.hpp deleted file mode 100644 index 0b9a13b13..000000000 --- a/boost/network/protocol/http/message/wrappers/headers.hpp +++ /dev/null @@ -1,126 +0,0 @@ - -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 -#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 - -// Copyright Dean Michael Berris 2010. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -namespace boost { namespace network { namespace http { - - template - struct headers_range { - typedef typename headers_container::type headers_container_type; - typedef typename boost::iterator_range type; - }; - - template - struct basic_request; - - template - struct basic_response; - - namespace impl { - - template - struct request_headers_wrapper { - typedef typename string::type string_type; - typedef typename headers_range >::type range_type; - typedef typename headers_container::type headers_container_type; - typedef typename headers_container_type::const_iterator const_iterator; - typedef typename headers_container_type::iterator iterator; - - explicit request_headers_wrapper(basic_request const & message) - : message_(message) - {} - - range_type operator[] (string_type const & key) const { - return message_.headers().equal_range(key); - } - - typename headers_container_type::size_type count(string_type const & key) const { - return message_.headers().count(key); - } - - const_iterator begin() const { - return message_.headers().begin(); - } - - const_iterator end() const { - return message_.headers().end(); - } - - operator range_type () { - return make_iterator_range(message_.headers().begin(), message_.headers().end()); - } - - operator headers_container_type () { - return message_.headers(); - } - - private: - basic_request const & message_; - }; - - template - struct response_headers_wrapper { - typedef typename string::type string_type; - typedef typename headers_range >::type range_type; - typedef typename headers_container::type headers_container_type; - typedef typename headers_container_type::const_iterator const_iterator; - typedef typename headers_container_type::iterator iterator; - - explicit response_headers_wrapper(basic_response const & message) - : message_(message) - {} - - range_type operator[] (string_type const & key) const { - return message_.headers().equal_range(key); - } - - typename headers_container_type::size_type count(string_type const & key) const { - return message_.headers().count(key); - } - - const_iterator begin() const { - return message_.headers().begin(); - } - - const_iterator end() const { - return message_.headers().end(); - } - - operator range_type () { - return make_iterator_range(message_.headers().begin(), message_.headers().end()); - } - - operator headers_container_type () { - return message_.headers(); - } - - private: - basic_response const & message_; - }; - - } // namespace impl - - template - inline impl::request_headers_wrapper - headers(basic_request const & request_) { - return impl::request_headers_wrapper(request_); - } - - template - inline impl::response_headers_wrapper - headers(basic_response const & response_) { - return impl::response_headers_wrapper(response_); - } - -} // namepace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 diff --git a/boost/network/protocol/http/message/wrappers/method.hpp b/boost/network/protocol/http/message/wrappers/method.hpp index 8edb98692..a122a5b2b 100644 --- a/boost/network/protocol/http/message/wrappers/method.hpp +++ b/boost/network/protocol/http/message/wrappers/method.hpp @@ -6,33 +6,21 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_request; - - template - struct method_wrapper { - explicit method_wrapper(basic_request const & message) - : message_(message) {} - - basic_request const & message_; - - typedef typename basic_request::string_type string_type; - - operator string_type() { - return message_.method; - } - }; - - template - inline typename enable_if, typename string::type >::type - method(basic_request const & message) { - return method_wrapper(message); - } +struct method_wrapper { + explicit method_wrapper(request_base & message); + operator std::string () const; + private: + request_base & message_; +}; + +inline method_wrapper const +method(request_base & message) { + return method_wrapper(message); +} } /* http */ diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index 7b10f5586..2a42d60a1 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -10,17 +10,16 @@ #include +#include #include #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -29,30 +28,59 @@ #include #include #include -#include #include #include #include #include -// forward declarations namespace boost { namespace network { namespace http { -struct request_base; - -template -struct basic_request; - -} // namespace http - -} // namespace network - -} // namespace boost - -#include - -namespace boost { namespace network { namespace http { +struct request_pimpl; + +struct request : request_base { + // FIXME Implement all these! + + // From message_base... + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_headers(function predicate, function inserter); + virtual void get_body(std::string const & body); + virtual void get_body(function)> chunk_reader, size_t size); + + // From request_base... + // Setters + virtual void set_method(std::string const & method); + virtual void set_status(std::string const & status); + virtual void set_status_message(std::string const & status_message); + virtual void set_uri(std::string const &uri); + virtual void set_uri(network::uri::uri const &uri); + + // Getters + virtual void get_uri(network::uri::uri &uri); + virtual void get_uri(std::string &uri); + virtual void get_method(std::string & method); + virtual void get_status(std::string & status); + virtual void get_status_message(std::string & status_message); + virtual void get_body_stream(body_stream & output_stream) = 0; + + virtual ~request(); + private: + request_pimpl * pimpl_; +}; template request_base & operator<< (request_base & request, @@ -67,6 +95,10 @@ request_base & operator<< (request_base & request, } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #include #endif // __NETWORK_PROTOCOL_HTTP_REQUEST_20070908-1_HPP__ diff --git a/boost/network/protocol/http/request.ipp b/boost/network/protocol/http/request.ipp index cace3fccb..d34cb7581 100644 --- a/boost/network/protocol/http/request.ipp +++ b/boost/network/protocol/http/request.ipp @@ -7,72 +7,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_NETWORK_BUFFER_CHUNK -#define BOOST_NETWORK_BUFFER_CHUNK 1024 // We want 1KiB worth of data at least. -#endif - -namespace boost { namespace network { namespace http { - -struct body_source : iostreams::source { - virtual std::streamsize read(char * buffer, std::streamsize size); - virtual ~body_source(); -}; - -struct request_storage_base { - typedef iostreams::stream body_stream; - protected: - // TODO Implement a segmented storage base which efficiently supports - // efficient memory usage that makes sense for HTTP payload. The idea is - // to expose the internal (segmented) storage to the client implementation - // so that raw buffers of formatted HTTP request data (which may or may not - // support delegated streams from user input -- i.e. for the body contents) - // can be efficiently sent out to the wire. This also implies that all - // thread-safety guarantees are handled by the storage base as well. - request_storage_base(size_t hint = BOOST_NETWORK_BUFFER_CHUNK); - virtual void set_status_line(std::string const &status_line); - virtual void append_header(std::string const &name, std::string const &value); -}; - -struct request_base : message_base, request_storage_base { - protected: - using request_storage_base::body_stream; - request_base(); - // Setters - virtual void set_method(std::string const & method); - virtual void set_status(std::string const & status); - virtual void set_status_message(std::string const & status_message); - virtual void append_header(std::string const &name, std::string const &value); - virtual void set_body_stream(shared_ptr stream); - - // Getters - virtual void get_method(std::string & method); - virtual void get_status(std::string & status); - virtual void get_status_message(std::string & status_message); - virtual void get_headers(function -struct basic_request : request_base { - basic_request(); - basic_request(basic_request const &); // valid copy constructor - // TODO implement a conditional move constructor - basic_request & operator=(basic_request); // valid assigment operator - String const method(); - void method(String const &); - - String const status(); - void status(String const &); - - std::multimap const & headers(); - - String const body(); - body_stream & body_stream(); -}; - +// TODO Implement the basic request proxy! #endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_IPP_20110910 */ diff --git a/boost/network/protocol/http/request_base.hpp b/boost/network/protocol/http/request_base.hpp new file mode 100644 index 000000000..2d532754a --- /dev/null +++ b/boost/network/protocol/http/request_base.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_BASE_HPP_20111008 +#define BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_BASE_HPP_20111008 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_NETWORK_BUFFER_CHUNK +#define BOOST_NETWORK_BUFFER_CHUNK 1024 // We want 1KiB worth of data at least. +#endif + +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct body_source : iostreams::source { + virtual std::streamsize read(char * buffer, std::streamsize size); + virtual ~body_source(); +}; + +struct request_storage_base { + typedef iostreams::stream body_stream; + protected: + // TODO Implement a segmented storage base which efficiently supports + // efficient memory usage that makes sense for HTTP payload. The idea is + // to expose the internal (segmented) storage to the client implementation + // so that raw buffers of formatted HTTP request data (which may or may not + // support delegated streams from user input -- i.e. for the body contents) + // can be efficiently sent out to the wire. This also implies that all + // thread-safety guarantees are handled by the storage base as well. + request_storage_base(size_t hint = BOOST_NETWORK_BUFFER_CHUNK); + virtual void set_status_line(std::string const &status_line); + virtual void append_header(std::string const &name, std::string const &value); + virtual ~request_storage_base(); +}; + +struct request_base : message_base, request_storage_base { + using request_storage_base::body_stream; + // Setters + virtual void set_method(std::string const & method) = 0; + virtual void set_status(std::string const & status) = 0; + virtual void set_status_message(std::string const & status_message) = 0; + virtual void set_body_stream(shared_ptr stream) = 0; + virtual void set_uri(std::string const &uri) = 0; + virtual void set_uri(network::uri::uri const &uri) = 0; + + // Getters + virtual void get_uri(network::uri::uri &uri) = 0; + virtual void get_uri(std::string &uri) = 0; + virtual void get_method(std::string & method) = 0; + virtual void get_status(std::string & status) = 0; + virtual void get_status_message(std::string & status_message) = 0; + virtual void get_body_stream(body_stream & output_stream) = 0; + virtual ~request_base() = 0; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_BASE_HPP_20111008 */ diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index 080ba77f8..4c7832102 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -9,8 +9,7 @@ #include -struct response_base; - +#include #include #include #include @@ -30,6 +29,36 @@ struct response_base; namespace boost { namespace network { namespace http { +struct response : response_base { + // FIXME implement all these! + + // From message_base... + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_headers(function predicate, function inserter); + virtual void get_body(std::string const & body); + virtual void get_body(function)> chunk_reader, size_t size); + + // From response_base... + virtual void set_status(std::string const & new_status); + virtual void set_status_message(std::string const & new_status_message); + virtual void set_version(std::string const & new_version); + virtual ~response(); +}; + } // namespace http } // namespace network @@ -40,9 +69,9 @@ namespace boost { namespace network { namespace http { namespace boost { namespace network { namespace http { - template - basic_response & operator<<( - basic_response & message, + template + response & operator<<( + response & message, Directive const & directive ) { From bd41f3cff9a9f495cdd624e6862625e40ae0ed8f Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 16 Oct 2011 23:57:49 +1100 Subject: [PATCH 029/438] Message Refactoring This commit gets the message tests to compile, but now the linker complains that the implementation of the stubbed out interfaces for the message implementation(s) are not available. This is a milestone which indicates that the work required to get the library into working shape would be clearer now. More work lies ahead. --- boost/network/message.hpp | 160 ++++------------ boost/network/message/directives.hpp | 13 +- .../directives/detail/string_directive.hpp | 25 +-- boost/network/message/directives/header.hpp | 16 +- .../message/directives/remove_header.hpp | 39 +--- boost/network/message/wrappers/headers.hpp | 5 +- .../protocol/http/algorithms/linearize.hpp | 25 +-- boost/network/protocol/http/client.hpp | 6 +- boost/network/protocol/http/client/base.hpp | 1 + .../http/client/connection/async_base.hpp | 1 - .../http/client/connection/async_normal.hpp | 5 - .../connection/async_protocol_handler.hpp | 74 ++++---- .../client/connection/connection_delegate.hpp | 3 + .../client/connection/resolver_delegate.hpp | 22 +++ boost/network/protocol/http/client/facade.hpp | 45 +++-- .../http/message/directives/method.hpp | 4 +- .../message/directives/status_message.hpp | 4 +- .../protocol/http/message/directives/uri.hpp | 2 +- .../http/message/directives/version.hpp | 2 +- .../protocol/http/message/header/name.hpp | 15 +- .../protocol/http/message/header/value.hpp | 25 +-- .../protocol/http/message/header_concept.hpp | 2 - .../protocol/http/parser/incremental.hpp | 2 - .../http/policies/async_connection.hpp | 20 +- boost/network/protocol/http/request.hpp | 3 +- libs/network/test/message_test.cpp | 174 ++++-------------- 26 files changed, 212 insertions(+), 481 deletions(-) create mode 100644 boost/network/protocol/http/client/connection/resolver_delegate.hpp diff --git a/boost/network/message.hpp b/boost/network/message.hpp index 32b3f68f0..d03393be4 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -24,8 +24,6 @@ #include #endif -#include - /** message.hpp * * This header file implements the common message type which @@ -38,136 +36,44 @@ namespace boost { namespace network { /** The common message type. */ - template - struct basic_message : basic_storage_base { - typedef std::pair header_type; - typedef std::multimap headers_container_type; - typedef String string_type; - - basic_message() - : basic_storage_base() - {} - - basic_message(const basic_message & other) - : basic_storage_base(other) - {} - - basic_message & operator=(basic_message rhs) { - rhs.swap(*this); - return *this; - } - - void swap(basic_message & other) { - basic_storage_base & this_ = *this, - & other_ = other; - swap(this_, other_); - } - - headers_container_type & headers() { - if (!headers_) { - headers_ = headers_container_type(); - this->get_headers(*headers_); - } - return *headers_; - } - - void headers(headers_container_type const & headers_) const { - this->set_headers(headers_); - } - - void add_header(typename headers_container_type::value_type const & pair_) const { - this->append_header(pair_.first, pair_.second); - } - - void remove_header(typename headers_container_type::key_type const & key) const { - this->remove_headers(key); - } - - headers_container_type const & headers() const { - if (!headers_) { - headers_ = headers_container_type(); - this->get_headers(*headers_); - } - return *headers_; - } - - string_type & body() { - if (!body_) { - body_ = String(); - this->get_body(*body_); - } - return *body_; - } - - void body(string_type const & body_) const { - this->set_body(body_); - } - - string_type const & body() const { - if (!body_) { - body_ = String(); - this->get_body(*body_); - } - return *body_; - } - - string_type & source() { - if (!source_) { - source_ = String(); - this->get_source(*source_); - } - return *source_; - } - - void source(string_type const & source_) const { - this->set_source(source_); - } - - string_type const & source() const { - if (!source_) { - source_ = String(); - this->get_source(*source_); - } - return *source_; - } - - string_type & destination() { - if (!destination_) { - destination_ = String(); - this->get_destination(*destination_); - } - return *destination_; - } - - void destination(string_type const & destination_) const { - this->set_destination(destination_); - } - - string_type const & destination() const { - if (!destination_) { - destination_ = String(); - this->get_destination(*destination_); - } - return *destination_; - } - - protected: - optional source_, destination_; - optional headers_; - optional body_; + struct message : message_base { + // Nested types + typedef iterator_range< + shared_container_iterator > > + headers_range; + + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_headers(function predicate, function inserter); + virtual void get_body(std::string const & body); + virtual void get_body(function)> chunk_reader, size_t size); + void swap(message & other); + virtual ~message(); }; - template - inline void swap(basic_message & left, basic_message & right) { + inline void swap(message & left, message & right) { left.swap(right); } - - // Commenting this out as we don't need to do this anymore. - // BOOST_CONCEPT_ASSERT((Message >)); - // BOOST_CONCEPT_ASSERT((Message >)); - typedef basic_message message; - typedef basic_message wmessage; + template + message_base & operator<< (message_base & msg, Directive directive) { + directive(msg); + return msg; + } + } // namespace network } // namespace boost diff --git a/boost/network/message/directives.hpp b/boost/network/message/directives.hpp index 005a91e14..23be513f2 100644 --- a/boost/network/message/directives.hpp +++ b/boost/network/message/directives.hpp @@ -13,16 +13,9 @@ namespace boost { namespace network { - template - inline basic_message & - operator<< (basic_message & message_, Directive const & directive) { - directive(message_); - return message_; - } - - BOOST_NETWORK_STRING_DIRECTIVE(source, source_, message.source(source_), message.source=source_); - BOOST_NETWORK_STRING_DIRECTIVE(destination, destination_, message.destination(destination_), message.destination=destination_); - BOOST_NETWORK_STRING_DIRECTIVE(body, body_, message.body(body_), message.body=body_); + BOOST_NETWORK_STRING_DIRECTIVE(source); + BOOST_NETWORK_STRING_DIRECTIVE(destination); + BOOST_NETWORK_STRING_DIRECTIVE(body); } // namespace network diff --git a/boost/network/message/directives/detail/string_directive.hpp b/boost/network/message/directives/detail/string_directive.hpp index 885777da4..239b3bd44 100644 --- a/boost/network/message/directives/detail/string_directive.hpp +++ b/boost/network/message/directives/detail/string_directive.hpp @@ -29,29 +29,22 @@ */ #ifndef BOOST_NETWORK_STRING_DIRECTIVE -#define BOOST_NETWORK_STRING_DIRECTIVE(name, value, body, pod_body) \ - template \ +#define BOOST_NETWORK_STRING_DIRECTIVE(name) \ struct name##_directive { \ - ValueType const & value; \ - explicit name##_directive(ValueType const & value_) \ + std::string const & value; \ + explicit name##_directive(std::string const & value_) \ : value(value_) {} \ name##_directive(name##_directive const & other) \ : value(other.value) {} \ - template class Message> \ - typename enable_if, void>::type \ - operator()(Message & message) const { \ - pod_body; \ - } \ - template class Message> \ - typename enable_if >, void>::type \ - operator()(Message & message) const { \ - body; \ + template \ + void operator()(Message & message) const { \ + message.set_##name(value); \ } \ }; \ \ - template inline name##_directive \ - name (T const & input) { \ - return name##_directive(input); \ + inline name##_directive const \ + name (std::string const & input) { \ + return name##_directive(input); \ } #endif /* BOOST_NETWORK_STRING_DIRECTIVE */ diff --git a/boost/network/message/directives/header.hpp b/boost/network/message/directives/header.hpp index af3fcf91f..c223d721f 100644 --- a/boost/network/message/directives/header.hpp +++ b/boost/network/message/directives/header.hpp @@ -13,11 +13,10 @@ namespace boost { namespace network { namespace impl { -template struct header_directive { - explicit header_directive(KeyType const & header_name, - ValueType const & header_value) : + explicit header_directive(std::string const & header_name, + std::string const & header_value) : _header_name(header_name), _header_value(header_value) { }; @@ -28,16 +27,15 @@ struct header_directive { private: - KeyType const & _header_name; - ValueType const & _header_value; + std::string const & _header_name; + std::string const & _header_value; }; } // namespace impl -template -inline impl::header_directive -header(T1 const & header_name, T2 const & header_value) { - return impl::header_directive(header_name, header_value); +inline impl::header_directive +header(std::string const & header_name, std::string const & header_value) { + return impl::header_directive(header_name, header_value); } } // namespace network } // namespace boost diff --git a/boost/network/message/directives/remove_header.hpp b/boost/network/message/directives/remove_header.hpp index 16d863e15..1a1f4f63e 100644 --- a/boost/network/message/directives/remove_header.hpp +++ b/boost/network/message/directives/remove_header.hpp @@ -1,5 +1,6 @@ -// Copyright Dean Michael Berris 2008. +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -10,40 +11,20 @@ namespace boost { namespace network { - template - struct basic_message; - namespace impl { -template < - class T - > -struct remove_header_directive { - - explicit remove_header_directive(T header_name) : - header_name_(header_name) - { }; - - template - void operator() (basic_message & msg) const { - msg.headers().erase(header_name_); - } -private: - mutable T header_name_; +struct remove_header_directive { + explicit remove_header_directive(std::string const & header_name); + void operator() (message_base & msg) const; + private: + std::string const & header_name_; }; } // namespace impl -inline -impl::remove_header_directive -remove_header(std::string header_name) { - return impl::remove_header_directive(header_name); -} - -inline -impl::remove_header_directive -remove_header(std::wstring header_name) { - return impl::remove_header_directive(header_name); +inline impl::remove_header_directive const +remove_header(std::string const & header_name) { + return impl::remove_header_directive(header_name); } } // namespace network } // namespace boost diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index 5c217ddca..41f4daab4 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -35,13 +35,14 @@ namespace impl { */ struct headers_wrapper { typedef std::multimap container_type; - typedef shared_container_iterator iterator; typedef iterator_range > range_type; explicit headers_wrapper(message_base & message); range_type operator[] (std::string const & key) const; + operator range_type () const; container_type::size_type count() const; + container_type::size_type count(std::string const &key) const; private: void init_cache_all(); mutable shared_ptr cache_; @@ -50,7 +51,7 @@ struct headers_wrapper { } // namespace impl /// Factory method to create the right wrapper object -inline impl::headers_wrapper +inline impl::headers_wrapper const headers(message_base & message_) { return impl::headers_wrapper(message_); } diff --git a/boost/network/protocol/http/algorithms/linearize.hpp b/boost/network/protocol/http/algorithms/linearize.hpp index c53305ae2..0fd24f740 100644 --- a/boost/network/protocol/http/algorithms/linearize.hpp +++ b/boost/network/protocol/http/algorithms/linearize.hpp @@ -6,7 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include @@ -18,9 +17,8 @@ namespace boost { namespace network { namespace http { - template struct linearize_header { - typedef typename string::type string_type; + typedef std::string string_type; template struct result; @@ -35,8 +33,8 @@ namespace boost { namespace network { namespace http { ((Header)), (string_type) ) operator()(ValueType & header) { - typedef typename ostringstream::type output_stream; - typedef constants consts; + typedef std::ostringstream output_stream; + typedef constants consts; output_stream header_line; header_line << name(header) << consts::colon() << consts::space() @@ -57,9 +55,8 @@ namespace boost { namespace network { namespace http { OutputIterator oi ) { - typedef typename Request::tag Tag; - typedef constants consts; - typedef typename string::type string_type; + typedef constants consts; + typedef std::string string_type; static string_type http_slash = consts::http_slash() , accept = consts::accept() @@ -115,7 +112,7 @@ namespace boost { namespace network { namespace http { boost::copy(default_accept_encoding, oi); boost::copy(crlf, oi); } - typedef typename headers_range::type headers_range; + typedef boost::iterator_range::const_iterator> headers_range; typedef typename range_iterator::type headers_iterator; headers_range request_headers = headers(request); headers_iterator iterator = boost::begin(request_headers), @@ -129,15 +126,9 @@ namespace boost { namespace network { namespace http { boost::copy(header_value, oi); boost::copy(crlf, oi); } - if (!connection_keepalive::value) { - boost::copy(connection, oi); - *oi = consts::colon_char(); - *oi = consts::space_char(); - boost::copy(close, oi); - boost::copy(crlf, oi); - } boost::copy(crlf, oi); - typename body_range::type body_data = body(request).range(); + boost::iterator_range body_data = + body(request); return boost::copy(body_data, oi); } diff --git a/boost/network/protocol/http/client.hpp b/boost/network/protocol/http/client.hpp index 85c3bb583..bd8203a5c 100644 --- a/boost/network/protocol/http/client.hpp +++ b/boost/network/protocol/http/client.hpp @@ -50,13 +50,13 @@ struct client : basic_client_facade { // this client. BOOST_PARAMETER_CONSTRUCTOR( - basic_client, (base_facade_type), tag, + client, (base_facade_type), tag, (optional (in_out(io_service), (boost::asio::io_service&)) (follow_redirects, (bool)) (cache_resolved, (bool)) - (openssl_certificate, (string_type)) - (openssl_verify_path, (string_type)) + (openssl_certificate, (std::string)) + (openssl_verify_path, (std::string)) (connection_manager, (shared_ptr)) )) diff --git a/boost/network/protocol/http/client/base.hpp b/boost/network/protocol/http/client/base.hpp index 7e3eff5bc..b5b381e49 100644 --- a/boost/network/protocol/http/client/base.hpp +++ b/boost/network/protocol/http/client/base.hpp @@ -31,6 +31,7 @@ struct client_base { std::string const & method, bool get_body, body_callback_function_type callback); + void clear_resolved_cache(); private: client_base_pimpl * pimpl; }; diff --git a/boost/network/protocol/http/client/connection/async_base.hpp b/boost/network/protocol/http/client/connection/async_base.hpp index 1cdf85486..2ada508c9 100644 --- a/boost/network/protocol/http/client/connection/async_base.hpp +++ b/boost/network/protocol/http/client/connection/async_base.hpp @@ -9,7 +9,6 @@ #include #include -#include #include namespace boost { namespace network { namespace http { namespace impl { diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index 0595d408c..fa23fd75b 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include #include @@ -29,8 +27,6 @@ #include #include -#include - namespace boost { namespace network { namespace http { namespace impl { template @@ -38,7 +34,6 @@ namespace boost { namespace network { namespace http { namespace impl { namespace placeholders = boost::asio::placeholders; - template struct http_async_connection : async_connection_base, protected http_async_protocol_handler, diff --git a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp index f0368c0e1..6109c4ae2 100644 --- a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp +++ b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -17,18 +17,16 @@ namespace boost { namespace network { namespace http { namespace impl { struct http_async_protocol_handler { protected: - typedef typename string::type string_type; - #ifdef BOOST_NETWORK_DEBUG struct debug_escaper { - string_type & string; - explicit debug_escaper(string_type & string_) + std::string & string; + explicit debug_escaper(std::string & string_) : string(string_) {} debug_escaper(debug_escaper const & other) : string(other.string) {} - void operator()(typename string_type::value_type input) { + void operator()(typename std::string::value_type input) { if (!algorithm::is_print()(input)) { - typename ostringstream::type escaped_stream; + std::ostringstream escaped_stream; if (input == '\r') { string.append("\\r"); } else if (input == '\n') { @@ -46,36 +44,33 @@ namespace boost { namespace network { namespace http { namespace impl { template void init_response(ResponseType & response_, bool get_body) { - boost::shared_future source_future( + boost::shared_future source_future( source_promise.get_future()); source(response_, source_future); - boost::shared_future destination_future( + boost::shared_future destination_future( destination_promise.get_future()); destination(response_, destination_future); - boost::shared_future::type> + boost::shared_future > headers_future(headers_promise.get_future()); headers(response_, headers_future); - boost::shared_future body_future( + boost::shared_future body_future( body_promise.get_future()); body(response_, body_future); - boost::shared_future version_future( + boost::shared_future version_future( version_promise.get_future()); version(response_, version_future); boost::shared_future status_future( status_promise.get_future()); status(response_, status_future); - boost::shared_future status_message_future( + boost::shared_future status_message_future( status_message_promise.get_future()); status_message(response_, status_message_future); } struct to_http_headers { - typedef typename string::type string_type; template - string_type const operator() (U const & pair) const { - typedef typename ostringstream::type ostringstream_type; - typedef constants constants; - ostringstream_type header_line; + std::string const operator() (U const & pair) const { + std::ostringstream header_line; header_line << pair.first << constants::colon() << constants::space() @@ -100,7 +95,7 @@ namespace boost { namespace network { namespace http { namespace impl { response_parser_type::http_version_done, input_range); if (parsed_ok == true) { - string_type version; + std::string version; std::swap(version, partial_parsed); version.append(boost::begin(result_range), boost::end(result_range)); @@ -109,7 +104,7 @@ namespace boost { namespace network { namespace http { namespace impl { part_begin = boost::end(result_range); } else if (parsed_ok == false) { #ifdef BOOST_NETWORK_DEBUG - string_type escaped; + std::string escaped; debug_escaper escaper(escaped); std::for_each(part_begin, part_end, escaper); BOOST_NETWORK_MESSAGE("[parser:" @@ -155,7 +150,7 @@ namespace boost { namespace network { namespace http { namespace impl { response_parser_type::http_status_done, input_range); if (parsed_ok == true) { - string_type status; + std::string status; std::swap(status, partial_parsed); status.append(boost::begin(result_range), boost::end(result_range)); @@ -166,7 +161,7 @@ namespace boost { namespace network { namespace http { namespace impl { part_begin = boost::end(result_range); } else if (parsed_ok == false) { #ifdef BOOST_NETWORK_DEBUG - string_type escaped; + std::string escaped; debug_escaper escaper(escaped); std::for_each(part_begin, part_end, escaper); BOOST_NETWORK_MESSAGE("[parser:" @@ -211,7 +206,7 @@ namespace boost { namespace network { namespace http { namespace impl { response_parser_type::http_status_message_done, input_range); if (parsed_ok == true) { - string_type status_message; + std::string status_message; std::swap(status_message, partial_parsed); status_message.append(boost::begin(result_range), boost::end(result_range)); @@ -220,7 +215,7 @@ namespace boost { namespace network { namespace http { namespace impl { part_begin = boost::end(result_range); } else if (parsed_ok == false) { #ifdef BOOST_NETWORK_DEBUG - string_type escaped; + std::string escaped; debug_escaper escaper(escaped); std::for_each(part_begin, part_end, escaper); BOOST_NETWORK_MESSAGE("[parser:" @@ -249,15 +244,15 @@ namespace boost { namespace network { namespace http { namespace impl { return parsed_ok; } - void parse_headers_real(string_type & headers_part) { - typename boost::iterator_range + void parse_headers_real(std::string & headers_part) { + typename boost::iterator_range input_range = boost::make_iterator_range(headers_part) , result_range; logic::tribool parsed_ok; response_parser_type headers_parser( response_parser_type::http_header_line_done); - typename headers_container::type headers; - std::pair header_pair; + std::multimap headers; + std::pair header_pair; while (!boost::empty(input_range)) { fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( @@ -266,14 +261,14 @@ namespace boost { namespace network { namespace http { namespace impl { if (headers_parser.state() != response_parser_type::http_header_colon) break; - header_pair.first = string_type(boost::begin(result_range), + header_pair.first = std::string(boost::begin(result_range), boost::end(result_range)); input_range.advance_begin(boost::distance(result_range)); fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( response_parser_type::http_header_line_done, input_range); - header_pair.second = string_type(boost::begin(result_range), + header_pair.second = std::string(boost::begin(result_range), boost::end(result_range)); input_range.advance_begin(boost::distance(result_range)); @@ -303,7 +298,7 @@ namespace boost { namespace network { namespace http { namespace impl { response_parser_type::http_headers_done, input_range); if (parsed_ok == true) { - string_type headers_string; + std::string headers_string; std::swap(headers_string, partial_parsed); headers_string.append(boost::begin(result_range), boost::end(result_range)); @@ -313,7 +308,7 @@ namespace boost { namespace network { namespace http { namespace impl { // We want to output the contents of the buffer that caused // the error in debug builds. #ifdef BOOST_NETWORK_DEBUG - string_type escaped; + std::string escaped; debug_escaper escaper(escaped); std::for_each(part_begin, part_end, escaper); BOOST_NETWORK_MESSAGE("[parser:" @@ -359,20 +354,19 @@ namespace boost { namespace network { namespace http { namespace impl { } typedef response_parser response_parser_type; - // TODO: make 1024 go away and become a configurable value. - typedef boost::array::type, 1024> buffer_type; + typedef boost::array buffer_type; response_parser_type response_parser_; - boost::promise version_promise; + boost::promise version_promise; boost::promise status_promise; - boost::promise status_message_promise; - boost::promise::type> headers_promise; - boost::promise source_promise; - boost::promise destination_promise; - boost::promise body_promise; + boost::promise status_message_promise; + boost::promise > headers_promise; + boost::promise source_promise; + boost::promise destination_promise; + boost::promise body_promise; buffer_type part; typename buffer_type::const_iterator part_begin; - string_type partial_parsed; + std::string partial_parsed; }; diff --git a/boost/network/protocol/http/client/connection/connection_delegate.hpp b/boost/network/protocol/http/client/connection/connection_delegate.hpp index 0e18b231c..7f4bc5b5b 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate.hpp @@ -7,6 +7,9 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include +#include + namespace boost { namespace network { namespace http { namespace impl { struct connection_delegate { diff --git a/boost/network/protocol/http/client/connection/resolver_delegate.hpp b/boost/network/protocol/http/client/connection/resolver_delegate.hpp new file mode 100644 index 000000000..3acf2fd7b --- /dev/null +++ b/boost/network/protocol/http/client/connection/resolver_delegate.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_HPP_20111016 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_HPP_20111016 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { namespace http { + +struct resolver_delegate { + virtual ~resolver_delegate() = 0; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_HPP_20111016 */ diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index 6faae3497..f26282215 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace boost { namespace network { namespace http { @@ -48,26 +49,25 @@ struct basic_client_facade { (request,(request)) // yes sir, we make a copy of the original request. ) (optional - (body,(string_type const &),string_type()) - (content_type,(string_type const &),string_type()) + (body,(std::string const &),std::string()) + (content_type,(std::string const &),std::string()) (body_handler,(body_callback_function_type),body_callback_function_type()) )) { - if (body != string_type()) { + if (body.size()) { request << remove_header("Content-Length") - << header("Content-Length", boost::lexical_cast(body.size())) + << header("Content-Length", boost::lexical_cast(body.size())) << boost::network::body(body); } - typename headers_range >::type content_type_headers = + std::multimap content_type_headers = headers(request)["Content-Type"]; - if (content_type != string_type()) { + if (content_type.size()) { if (!boost::empty(content_type_headers)) request << remove_header("Content-Type"); request << header("Content-Type", content_type); } else { if (boost::empty(content_type_headers)) { - typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; + static char content_type[] = "x-application/octet-stream"; request << header("Content-Type", content_type); } } @@ -79,26 +79,25 @@ struct basic_client_facade { (request,(request)) // yes sir, we make a copy of the original request. ) (optional - (body,(string_type const &),string_type()) - (content_type,(string_type const &),string_type()) + (body,(std::string const &),std::string()) + (content_type,(std::string const &),std::string()) (body_handler,(body_callback_function_type),body_callback_function_type()) )) { - if (body != string_type()) { + if (body != std::string()) { request << remove_header("Content-Length") - << header("Content-Length", boost::lexical_cast(body.size())) + << header("Content-Length", boost::lexical_cast(body.size())) << boost::network::body(body); } - typename headers_range >::type content_type_headers = + std::multimap content_type_headers = headers(request)["Content-Type"]; - if (content_type != string_type()) { + if (content_type.size()) { if (!boost::empty(content_type_headers)) request << remove_header("Content-Type"); request << header("Content-Type", content_type); } else { if (boost::empty(content_type_headers)) { - typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; + static char content_type[] = "x-application/octet-stream"; request << header("Content-Type", content_type); } } @@ -128,29 +127,27 @@ struct basic_client_facade { template void init_base(ArgPack const & args, no_io_service) { - base.reset(new base_type(this->get_connection_manager(args))); + base.reset(new client_base(this->get_connection_manager(args))); } template void init_base(ArgPack const & args, has_io_service) { - base.reset(new base_type(args[_io_service], this->get_connection_manager(args))); + base.reset(new client_base(args[_io_service], this->get_connection_manager(args))); } private: template shared_ptr get_connection_manager(ArgPack const & args) { - shared_ptr connection_manager_ = ptr; + shared_ptr connection_manager_ = args[_connection_manager|shared_ptr()]; if (!connection_manager_.get()) { // Because there's no explicit connection manager, we use the default // implementation as provided by the tag. - typedef typename async_connection_policy::type - default_connection_manager_type; connection_manager_.reset( - new default_connection_manager_type(args[_cache_resolved|false], + new simple_async_connection_manager(args[_cache_resolved|false], args[_follow_redirects|false], - args[_openssl_certificate|optional()], - args[_openssl_verify_path|optional()])); + args[_openssl_certificate|optional()], + args[_openssl_verify_path|optional()])); } return connection_manager_; diff --git a/boost/network/protocol/http/message/directives/method.hpp b/boost/network/protocol/http/message/directives/method.hpp index 2f9aac3a4..a79718f54 100644 --- a/boost/network/protocol/http/message/directives/method.hpp +++ b/boost/network/protocol/http/message/directives/method.hpp @@ -8,9 +8,7 @@ namespace boost { namespace network { namespace http { - BOOST_NETWORK_STRING_DIRECTIVE(method, method_, - message.method(method_), - message.method=method_); + BOOST_NETWORK_STRING_DIRECTIVE(method); } /* http */ diff --git a/boost/network/protocol/http/message/directives/status_message.hpp b/boost/network/protocol/http/message/directives/status_message.hpp index 3ac16d06b..63c621b8f 100644 --- a/boost/network/protocol/http/message/directives/status_message.hpp +++ b/boost/network/protocol/http/message/directives/status_message.hpp @@ -11,9 +11,7 @@ namespace boost { namespace network { namespace http { - BOOST_NETWORK_STRING_DIRECTIVE(status_message, status_message_, - message.status_message(status_message_), - message.status_message=status_message_); + BOOST_NETWORK_STRING_DIRECTIVE(status_message); } // namespace http diff --git a/boost/network/protocol/http/message/directives/uri.hpp b/boost/network/protocol/http/message/directives/uri.hpp index 1ae91a53e..b7acb68c0 100644 --- a/boost/network/protocol/http/message/directives/uri.hpp +++ b/boost/network/protocol/http/message/directives/uri.hpp @@ -11,7 +11,7 @@ namespace boost { namespace network { namespace http { - BOOST_NETWORK_STRING_DIRECTIVE(uri, uri_, message.uri(uri_), message.uri=uri_); + BOOST_NETWORK_STRING_DIRECTIVE(uri); } // namespace http diff --git a/boost/network/protocol/http/message/directives/version.hpp b/boost/network/protocol/http/message/directives/version.hpp index 88f2d1c5a..2d4eec0fd 100644 --- a/boost/network/protocol/http/message/directives/version.hpp +++ b/boost/network/protocol/http/message/directives/version.hpp @@ -11,7 +11,7 @@ namespace boost { namespace network { namespace http { - BOOST_NETWORK_STRING_DIRECTIVE(version, version_, message.version(version_), message.version=version_); + BOOST_NETWORK_STRING_DIRECTIVE(version); } // namespace http diff --git a/boost/network/protocol/http/message/header/name.hpp b/boost/network/protocol/http/message/header/name.hpp index e7c26d17c..712ea312c 100644 --- a/boost/network/protocol/http/message/header/name.hpp +++ b/boost/network/protocol/http/message/header/name.hpp @@ -18,23 +18,12 @@ namespace boost { namespace network { namespace http { } inline std::string const & - name(request_header_narrow const & h) { + name(request_header const & h) { return h.name; } - inline std::wstring const & - name(request_header_wide const &h) { - return h.name; - } - - inline std::string const & - name(response_header_narrow const & h) { - return h.name; - } - - inline std::wstring const & - name(response_header_wide const &h) { + name(response_header const & h) { return h.name; } diff --git a/boost/network/protocol/http/message/header/value.hpp b/boost/network/protocol/http/message/header/value.hpp index 3769ec2ab..3be67c91e 100644 --- a/boost/network/protocol/http/message/header/value.hpp +++ b/boost/network/protocol/http/message/header/value.hpp @@ -7,39 +7,28 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include namespace boost { namespace network { namespace http { - struct request_header_narrow; - struct request_header_wide; - struct response_header_narrow; - struct response_header_wide; + struct request_header; + struct response_header; template T1 & value(std::pair const & p) { return p.second; } - inline request_header_narrow::string_type const & - value(request_header_narrow const & h) { + inline std::string const & + value(request_header const & h) { return h.value; } - inline request_header_wide::string_type const & - value(request_header_wide const & h) { - return h.value; - } - - inline response_header_narrow::string_type const & - value(response_header_narrow const & h) { + inline std::string const & + value(response_header const & h) { return h.value; } - inline response_header_wide::string_type const & - value(response_header_wide const & h) { - return h.value; - } - } /* http */ } /* network */ diff --git a/boost/network/protocol/http/message/header_concept.hpp b/boost/network/protocol/http/message/header_concept.hpp index 9a14d47fd..538a3b067 100644 --- a/boost/network/protocol/http/message/header_concept.hpp +++ b/boost/network/protocol/http/message/header_concept.hpp @@ -6,8 +6,6 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - namespace boost { namespace network { namespace http { template diff --git a/boost/network/protocol/http/parser/incremental.hpp b/boost/network/protocol/http/parser/incremental.hpp index 44c4c2a2e..58c16ca8c 100644 --- a/boost/network/protocol/http/parser/incremental.hpp +++ b/boost/network/protocol/http/parser/incremental.hpp @@ -8,10 +8,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include -#include #include #include #include diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index ace3d7137..a3651c18c 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -13,14 +13,13 @@ #include #include #include -#include -#include -#include #include #include #include #include #include +#include +#include namespace boost { namespace network { namespace http { @@ -60,22 +59,9 @@ struct http_1_1_async_connection_manager : connection_manager, enable_shared_fro bool cache_resolved, follow_redirects_; mutex shared_resolver_mutex; shared_ptr shared_resolver_delegate; - unordered_map > ready_connections; + boost::unordered_map > ready_connections; }; -template -struct async_connection_policy; - -template -struct async_connection_policy { // HTTP/1.0 - typedef simple_async_connection_manager type; -} - -template -struct async_connection_policy { // HTTP/1.1 - typedef http_1_1_connection_manager type; -} - } // namespace http } // namespace network diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index 2a42d60a1..c02644723 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -66,6 +66,7 @@ struct request : request_base { virtual void set_method(std::string const & method); virtual void set_status(std::string const & status); virtual void set_status_message(std::string const & status_message); + virtual void set_body_stream(shared_ptr stream); virtual void set_uri(std::string const &uri); virtual void set_uri(network::uri::uri const &uri); @@ -75,7 +76,7 @@ struct request : request_base { virtual void get_method(std::string & method); virtual void get_status(std::string & status); virtual void get_status_message(std::string & status_message); - virtual void get_body_stream(body_stream & output_stream) = 0; + virtual void get_body_stream(body_stream & output_stream); virtual ~request(); private: diff --git a/libs/network/test/message_test.cpp b/libs/network/test/message_test.cpp index a3d7d4b36..775ee8087 100644 --- a/libs/network/test/message_test.cpp +++ b/libs/network/test/message_test.cpp @@ -13,162 +13,62 @@ using namespace boost::network; -typedef boost::mpl::list< - http::tags::http_default_8bit_tcp_resolve, - http::tags::http_default_8bit_udp_resolve, - http::tags::http_keepalive_8bit_tcp_resolve, - http::tags::http_keepalive_8bit_udp_resolve, - tags::default_string, - tags::default_wstring -> tag_types; - -struct string_header_name { - static std::string string; -}; - -std::string string_header_name::string = "Header"; - -struct wstring_header_name { - static std::wstring string; -}; - -std::wstring wstring_header_name::string = L"Header"; - -struct string_header_value { - static std::string string; -}; - -std::string string_header_value::string = "Value"; - -struct wstring_header_value { - static std::wstring string; -}; - -std::wstring wstring_header_value::string = L"Value"; - -template -struct header_name : string_header_name {}; - -template <> -struct header_name : wstring_header_name {}; - -template -struct header_value : string_header_value {}; - -template <> -struct header_value : wstring_header_value {}; - -struct string_body_data { - static std::string string; -}; - -std::string string_body_data::string = "The quick brown fox jumps over the lazy dog."; - -struct wstring_body_data { - static std::wstring string; -}; - -std::wstring wstring_body_data::string = L"The quick brown fox jumps over the lazy dog."; - -template -struct body_data : string_body_data {}; - -template <> -struct body_data : wstring_body_data {}; - -struct string_source_data { - static std::string string; -}; - -std::string string_source_data::string = "Source"; - -struct wstring_source_data { - static std::wstring string; -}; - -std::wstring wstring_source_data::string = L"Source"; - -template -struct source_data : string_source_data {}; - -template <> -struct source_data : wstring_body_data {}; - -struct string_destination_data { - static std::string string; -}; - -std::string string_destination_data::string = "Destination"; - -struct wstring_destination_data { - static std::wstring string; -}; - -std::wstring wstring_destination_data::string = L"Destination"; - -template -struct destination_data : string_destination_data {}; - -template <> -struct destination_data : wstring_destination_data {}; - - /** * Defines a set of template functions that can be used to test * generic code. */ -BOOST_AUTO_TEST_CASE_TEMPLATE(copy_constructor_test, T, tag_types) { - basic_message instance; - instance << header(header_name::string, header_value::string); - basic_message copy(instance); - BOOST_CHECK_EQUAL(headers(copy).count(header_name::string), static_cast(1)); - typename headers_range >::type range = headers(copy)[header_name::string]; - BOOST_CHECK (boost::begin(range) != boost::end(range)); +BOOST_AUTO_TEST_CASE(copy_constructor_test) { + message instance; + instance << header("name", "value"); + message copy(instance); + BOOST_CHECK_EQUAL(headers(copy).count("name"), static_cast(1)); + message::headers_range range = headers(copy)["name"]; + BOOST_CHECK (!boost::empty(range)); } -BOOST_AUTO_TEST_CASE_TEMPLATE(swap_test, T, tag_types) { - basic_message instance; - instance << header(header_name::string, header_value::string); - basic_message other; +BOOST_AUTO_TEST_CASE(swap_test) { + message instance; + instance << header("name", "value"); + message other; swap(instance, other); - BOOST_CHECK_EQUAL (headers(instance).count(header_name::string), static_cast(0)); - BOOST_CHECK_EQUAL (headers(other).count(header_name::string), static_cast(1)); + BOOST_CHECK_EQUAL (headers(instance).count("name"), static_cast(0)); + BOOST_CHECK_EQUAL (headers(other).count("name"), static_cast(1)); } -BOOST_AUTO_TEST_CASE_TEMPLATE(headers_directive_test, T, tag_types) { - basic_message instance; - instance << header(header_name::string, header_value::string); - BOOST_CHECK_EQUAL ( headers(instance).count(header_name::string), static_cast(1) ); - typename headers_range >::type range = headers(instance)[header_name::string]; +BOOST_AUTO_TEST_CASE(headers_directive_test) { + message instance; + instance << header("name", "value"); + BOOST_CHECK_EQUAL ( headers(instance).count("name"), static_cast(1) ); + message::headers_range range = headers(instance)["name"]; BOOST_CHECK (boost::begin(range) != boost::end(range)); } -BOOST_AUTO_TEST_CASE_TEMPLATE(body_directive_test, T, tag_types) { - basic_message instance; - instance << ::boost::network::body(body_data::string); - typename string::type body_string = body(instance); - BOOST_CHECK ( body_string == body_data::string ); +BOOST_AUTO_TEST_CASE(body_directive_test) { + message instance; + instance << ::boost::network::body("body"); + std::string body_string = body(instance); + BOOST_CHECK ( body_string == "body" ); } -BOOST_AUTO_TEST_CASE_TEMPLATE(source_directive_test, T, tag_types) { - basic_message instance; - instance << ::boost::network::source(source_data::string); - typename string::type source_string = source(instance); - BOOST_CHECK ( source_string == source_data::string ); +BOOST_AUTO_TEST_CASE(source_directive_test) { + message instance; + instance << ::boost::network::source("source"); + std::string source_string = source(instance); + BOOST_CHECK ( source_string == "source" ); } -BOOST_AUTO_TEST_CASE_TEMPLATE(destination_directive_test, T, tag_types) { - basic_message instance; - instance << destination(destination_data::string); - BOOST_CHECK ( destination(instance) == destination_data::string ); +BOOST_AUTO_TEST_CASE(destination_directive_test) { + message instance; + instance << destination("destination"); + BOOST_CHECK ( destination(instance) == "destination" ); } -BOOST_AUTO_TEST_CASE_TEMPLATE(remove_header_directive_test, T, tag_types) { - basic_message instance; - instance << header(header_name::string, header_value::string) - << remove_header(header_name::string); - typename headers_range >::type range = headers(instance); +BOOST_AUTO_TEST_CASE(remove_header_directive_test) { + message instance; + instance << header("name", "value") + << remove_header("name"); + message::headers_range range = headers(instance); BOOST_CHECK ( boost::begin(range) == boost::end(range) ); } From 1221ce8609095057513b39386784f9d117332a36 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Thu, 20 Oct 2011 17:58:22 +1100 Subject: [PATCH 030/438] Initial implementation of boost::network::message. --- boost/network/message.hpp | 98 ++++++----- boost/network/message.ipp | 211 +++++++++++++++++++++++ boost/network/message_base.hpp | 2 +- boost/network/protocol/http/request.hpp | 5 +- boost/network/protocol/http/response.hpp | 2 +- boost/network/uri/uri.hpp | 5 +- libs/network/build/CMakeLists.txt | 2 +- libs/network/src/CMakeLists.txt | 3 + libs/network/src/message.cpp | 14 ++ libs/network/test/CMakeLists.txt | 4 +- 10 files changed, 295 insertions(+), 51 deletions(-) create mode 100644 boost/network/message.ipp create mode 100644 libs/network/src/message.cpp diff --git a/boost/network/message.hpp b/boost/network/message.hpp index d03393be4..32ebd22bc 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -34,48 +34,64 @@ */ namespace boost { namespace network { - /** The common message type. - */ - struct message : message_base { - // Nested types - typedef iterator_range< - shared_container_iterator > > - headers_range; - - // Mutators - virtual void set_destination(std::string const & destination); - virtual void set_source(std::string const & source); - virtual void append_header(std::string const & name, - std::string const & value); - virtual void remove_headers(std::string const & name); - virtual void remove_headers(); - virtual void set_body(std::string const & body); - virtual void append_body(std::string const & data); - - // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); - virtual void get_headers(function inserter); - virtual void get_headers(std::string const & name, function inserter); - virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string const & body); - virtual void get_body(function)> chunk_reader, size_t size); - void swap(message & other); - virtual ~message(); - }; - - inline void swap(message & left, message & right) { - left.swap(right); - } - - template - message_base & operator<< (message_base & msg, Directive directive) { - directive(msg); - return msg; - } - + struct message_pimpl; + + /** The common message type. + */ + struct message : message_base { + // Nested types + typedef iterator_range< + shared_container_iterator > > + headers_range; + + // Constructors + message(); + message(message const & other); + + // Assignment + message & operator=(message other); + + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_headers(function predicate, function inserter); + virtual void get_body(std::string & body); + virtual void get_body(function)> chunk_reader, size_t size); + void swap(message & other); + + // Destructor + virtual ~message(); + private: + message_pimpl * pimpl; + }; + + inline void swap(message & left, message & right) { + left.swap(right); + } + + template + message_base & operator<< (message_base & msg, Directive directive) { + directive(msg); + return msg; + } + } // namespace network } // namespace boost -#endif // __NETWORK_MESSAGE_HPP__ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif +#endif // __NETWORK_MESSAGE_HPP__ diff --git a/boost/network/message.ipp b/boost/network/message.ipp new file mode 100644 index 000000000..afd90a12d --- /dev/null +++ b/boost/network/message.ipp @@ -0,0 +1,211 @@ +#ifndef BOOST_NETWORK_MESSAGE_IPP_20111020 +#define BOOST_NETWORK_MESSAGE_IPP_20111020 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +namespace boost { namespace network { + +struct message_pimpl { + message_pimpl() : + destination_(), + source_(), + headers_(), + body_(), + body_read_pos(0) + {} + + void set_destination(std::string const & destination) { + destination_ = destination; + } + + void set_source(std::string const & source) { + source_ = source; + } + + void append_header(std::string const & name, + std::string const & value) { + headers_.insert(std::make_pair(name, value)); + } + + void remove_headers(std::string const & name) { + headers_.erase(name); + } + + void remove_headers() { + std::multimap().swap(headers_); + } + + void set_body(std::string const & body) { + body_ = body; + } + + void append_body(std::string const & data) { + body_.append(data); + } + + // Retrievers + void get_destination(std::string & destination) { + destination = destination_; + } + + void get_source(std::string & source) { + source = source_; + } + + void get_headers(function inserter) { + std::multimap::const_iterator it = headers_.begin(), + end = headers_.end(); + for (; it != end; ++it) inserter(it->first, it->second); + } + + void get_headers(std::string const & name, + function inserter) { + std::multimap::const_iterator it = headers_.find(name), + end= headers_.end(); + while (it != end) { + inserter(it->first, it->second); + ++it; + } + } + + void get_headers(function predicate, + function inserter) { + std::multimap::const_iterator it = headers_.begin(), + end = headers_.end(); + while (it != end) { + if (predicate(it->first, it->second)) + inserter(it->first, it->second); + ++it; + } + } + + void get_body(std::string & body) { + body = body_; + } + + void get_body(function)> chunk_reader, size_t size) { + static char const * nullptr_ = 0; + if (body_read_pos == body_.size()) + chunk_reader(boost::make_iterator_range(nullptr_, nullptr_)); + std::string::const_iterator it = body_.begin(), + end = body_.end(); + std::advance(it, body_read_pos); + size_t max_size = std::distance(it, end); + size_t max_read = std::min(max_size, size); + std::string::const_iterator start = it; + end = start; + std::advance(end, max_read); + body_read_pos += max_read; + chunk_reader(boost::make_iterator_range(&(*start), &(*end))); + } + + message_pimpl * clone() { + message_pimpl * other = new(std::nothrow) message_pimpl; + other->destination_ = this->destination_; + other->source_ = this->source_; + other->headers_ = this->headers_; + other->body_ = this->body_; + return other; + } + + private: + std::string destination_, source_; + std::multimap headers_; + // TODO: use Boost.IOStreams here later on. + std::string body_; + size_t body_read_pos; +}; + +message::message() + : pimpl(new (std::nothrow) message_pimpl) +{} + +message::message(message const & other) + : pimpl(other.pimpl->clone()) +{} + +message& message::operator=(message other) { + *pimpl = *other.pimpl; +} + +message::~message() { + delete pimpl; +} + +void message::set_destination(std::string const & destination) { + pimpl->set_destination(destination); +} + +void message::set_source(std::string const & source) { + pimpl->set_source(source); +} + +void message::append_header(std::string const & name, + std::string const & value) { + pimpl->append_header(name, value); +} + +void message::remove_headers(std::string const & name) { + pimpl->remove_headers(name); +} + +void message::remove_headers() { + pimpl->remove_headers(); +} + +void message::set_body(std::string const & body) { + pimpl->set_body(body); +} + +void message::append_body(std::string const & data) { + pimpl->append_body(data); +} + +void message::get_destination(std::string & destination) { + pimpl->get_destination(destination); +} + +void message::get_source(std::string & source) { + pimpl->get_source(source); +} + +void message::get_headers(function inserter) { + pimpl->get_headers(inserter); +} + +void message::get_headers(std::string const & name, + function inserter) { + pimpl->get_headers(name, inserter); +} + +void message::get_headers(function predicate, + function inserter) { + pimpl->get_headers(predicate, inserter); +} + +void message::get_body(std::string & body) { + pimpl->get_body(body); +} + +void message::get_body(function)> chunk_reader, size_t size) { + pimpl->get_body(chunk_reader, size); +} + +void message::swap(message & other) { + std::swap(this->pimpl, other.pimpl); +} + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_IPP_20111020 */ diff --git a/boost/network/message_base.hpp b/boost/network/message_base.hpp index c96a666bc..ac2aaffad 100644 --- a/boost/network/message_base.hpp +++ b/boost/network/message_base.hpp @@ -29,7 +29,7 @@ struct message_base { virtual void get_headers(function inserter) = 0; virtual void get_headers(std::string const & name, function inserter) = 0; virtual void get_headers(function predicate, function inserter) = 0; - virtual void get_body(std::string const & body) = 0; + virtual void get_body(std::string & body) = 0; virtual void get_body(function)> chunk_reader, size_t size) = 0; // Destructor diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index c02644723..edb7b0406 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -58,9 +58,9 @@ struct request : request_base { virtual void get_headers(function inserter); virtual void get_headers(std::string const & name, function inserter); virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string const & body); + virtual void get_body(std::string & body); virtual void get_body(function)> chunk_reader, size_t size); - + // From request_base... // Setters virtual void set_method(std::string const & method); @@ -103,4 +103,3 @@ request_base & operator<< (request_base & request, #include #endif // __NETWORK_PROTOCOL_HTTP_REQUEST_20070908-1_HPP__ - diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index 4c7832102..f8e1aa094 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -49,7 +49,7 @@ struct response : response_base { virtual void get_headers(function inserter); virtual void get_headers(std::string const & name, function inserter); virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string const & body); + virtual void get_body(std::string & body); virtual void get_body(function)> chunk_reader, size_t size); // From response_base... diff --git a/boost/network/uri/uri.hpp b/boost/network/uri/uri.hpp index 99054559c..31aae7c95 100644 --- a/boost/network/uri/uri.hpp +++ b/boost/network/uri/uri.hpp @@ -300,8 +300,6 @@ inline bool operator == (const uri &lhs, const uri &rhs) { return std::equal(lhs.begin(), lhs.end(), rhs.begin()); } -} // namespace uri -} // namespace network inline network::uri::uri::iterator begin(network::uri::uri &uri_) { @@ -327,6 +325,9 @@ inline void swap(network::uri::uri &lhs, network::uri::uri &rhs) { lhs.swap(rhs); } + +} // namespace uri +} // namespace network } // namespace boost diff --git a/libs/network/build/CMakeLists.txt b/libs/network/build/CMakeLists.txt index 8111a37b7..e7dbee625 100644 --- a/libs/network/build/CMakeLists.txt +++ b/libs/network/build/CMakeLists.txt @@ -3,4 +3,4 @@ find_package( Boost 1.43.0 COMPONENTS unit_test_framework system regex thread fi add_library(cppnetlib-uri STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/parse_uri_impl.cpp) add_library(cppnetlib-server-parsers STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/server_request_parsers_impl.cpp) - +add_library(cppnetlib-message STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/message.cpp) diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 169a51bfd..9e38860f6 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -15,3 +15,6 @@ add_library(cppnetlib-server-parsers ${CPP-NETLIB_HTTP_SERVER_SRCS}) set(CPP-NETLIB_HTTP_CLIENT_SRCS client.cpp) add_library(cppnetlib-client-connections ${CPP-NETLIB_HTTP_CLIENT_SRCS}) + +set(CPP-NETLIB_MESSAGE_SRCS message.cpp) +add_library(cppnetlib-message ${CPP-NETLIB_MESSAGE_SRCS}) diff --git a/libs/network/src/message.cpp b/libs/network/src/message.cpp new file mode 100644 index 000000000..eb2f65a04 --- /dev/null +++ b/libs/network/src/message.cpp @@ -0,0 +1,14 @@ +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This is the conglomeration of all message-related implementation files. All +// we're doing is including all the .ipp files that are relevant. + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 343cf5697..7e3b7a531 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -22,11 +22,11 @@ if (Boost_FOUND) set_source_files_properties(${test}.cpp PROPERTIES COMPILE_FLAGS "-Wall") add_executable(cpp-netlib-${test} ${test}.cpp) - add_dependencies(cpp-netlib-${test} cppnetlib-uri) + add_dependencies(cpp-netlib-${test} cppnetlib-uri cppnetlib-message) # add_dependencies(cpp-netlib-${test} cppnetlib-uri) # target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri) - target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri) + target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri cppnetlib-message) if (OPENSSL_FOUND) target_link_libraries(cpp-netlib-${test} ${OPENSSL_LIBRARIES}) endif() From f74775fae5b3d75e4b540b3cbf12ff5313e45304 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Thu, 20 Oct 2011 18:03:05 +1100 Subject: [PATCH 031/438] Expanding ignored files. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0a0b40a64..22066753e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ Testing *.gch libs/mime/test/mime-roundtrip *.a +bin/ +tests/ +example/ From c066d2e02d42ca68402a92fcb560b4f311b02c65 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Thu, 20 Oct 2011 19:23:10 +1100 Subject: [PATCH 032/438] Default implementation of pure virtual destructor for message_base. --- boost/network/message_base.hpp | 4 ++++ boost/network/message_base.ipp | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 boost/network/message_base.ipp diff --git a/boost/network/message_base.hpp b/boost/network/message_base.hpp index ac2aaffad..43b2307bc 100644 --- a/boost/network/message_base.hpp +++ b/boost/network/message_base.hpp @@ -40,4 +40,8 @@ struct message_base { } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_MESSAGE_BASE_HPP_20110910 */ diff --git a/boost/network/message_base.ipp b/boost/network/message_base.ipp new file mode 100644 index 000000000..061d2a6f6 --- /dev/null +++ b/boost/network/message_base.ipp @@ -0,0 +1,23 @@ +#ifndef BOOST_NETWORK_MESSAGE_BASE_IPP_20111020 +#define BOOST_NETWORK_MESSAGE_BASE_IPP_20111020 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { + +message_base::~message_base() { + // This is never used, but is required even though message_base's destructor + // is a pure virtual one. +} + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_BASE_IPP_20111020 */ From 47776015a5a519a857f3f1c5e7168eaac79c9f89 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 21 Oct 2011 14:39:05 +1100 Subject: [PATCH 033/438] Moving headers around for better organization. --- boost/network/message.hpp | 88 +++---------------- boost/network/message/directives/header.hpp | 3 +- boost/network/message/message.hpp | 86 ++++++++++++++++++ boost/network/{ => message}/message.ipp | 2 +- boost/network/{ => message}/message_base.hpp | 0 boost/network/{ => message}/message_base.ipp | 0 .../message/modifiers/clear_headers.hpp | 2 +- .../message/modifiers/remove_header.hpp | 3 +- boost/network/message/wrappers/body.hpp | 3 +- .../network/message/wrappers/destination.hpp | 3 +- boost/network/message/wrappers/source.hpp | 2 +- .../http/message/directives/status.hpp | 2 +- .../http/message/modifiers/method.hpp | 2 +- .../http/message/modifiers/status.hpp | 2 +- .../http/message/modifiers/status_message.hpp | 2 +- .../http/message/modifiers/version.hpp | 2 +- .../protocol/http/message/wrappers/method.hpp | 2 +- .../http/message/wrappers/status_message.hpp | 2 +- .../protocol/http/message/wrappers/uri.hpp | 2 +- boost/network/protocol/http/request.hpp | 79 ++--------------- .../network/protocol/http/request/request.hpp | 79 +++++++++++++++++ .../protocol/http/{ => request}/request.ipp | 0 .../http/{ => request}/request_base.hpp | 2 +- .../http/{ => request}/request_concept.hpp | 0 boost/network/protocol/http/response.hpp | 63 +------------ .../protocol/http/response/response.hpp | 65 ++++++++++++++ .../http/{ => response}/response_base.hpp | 0 .../http/{ => response}/response_concept.hpp | 0 libs/network/src/message.cpp | 2 +- 29 files changed, 267 insertions(+), 231 deletions(-) create mode 100644 boost/network/message/message.hpp rename boost/network/{ => message}/message.ipp (99%) rename boost/network/{ => message}/message_base.hpp (100%) rename boost/network/{ => message}/message_base.ipp (100%) create mode 100644 boost/network/protocol/http/request/request.hpp rename boost/network/protocol/http/{ => request}/request.ipp (100%) rename boost/network/protocol/http/{ => request}/request_base.hpp (98%) rename boost/network/protocol/http/{ => request}/request_concept.hpp (100%) create mode 100644 boost/network/protocol/http/response/response.hpp rename boost/network/protocol/http/{ => response}/response_base.hpp (100%) rename boost/network/protocol/http/{ => response}/response_concept.hpp (100%) diff --git a/boost/network/message.hpp b/boost/network/message.hpp index 32ebd22bc..e1b266384 100644 --- a/boost/network/message.hpp +++ b/boost/network/message.hpp @@ -1,10 +1,12 @@ -// Copyright Dean Michael Berris 2007. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_NETWORK_MESSAGE_HPP_20111021 +#define BOOST_NETWORK_MESSAGE_HPP_20111021 -#ifndef __NETWORK_MESSAGE_HPP__ -#define __NETWORK_MESSAGE_HPP__ +// Copyright Dean Michael Berris 2007. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) #include #include @@ -20,78 +22,10 @@ #include #include +#include + #ifdef BOOST_NETWORK_DEBUG #include #endif -/** message.hpp - * - * This header file implements the common message type which - * all networking implementations under the boost::network - * namespace. The common message type allows for easy message - * construction and manipulation suited for networked - * application development. - */ -namespace boost { namespace network { - - struct message_pimpl; - - /** The common message type. - */ - struct message : message_base { - // Nested types - typedef iterator_range< - shared_container_iterator > > - headers_range; - - // Constructors - message(); - message(message const & other); - - // Assignment - message & operator=(message other); - - // Mutators - virtual void set_destination(std::string const & destination); - virtual void set_source(std::string const & source); - virtual void append_header(std::string const & name, - std::string const & value); - virtual void remove_headers(std::string const & name); - virtual void remove_headers(); - virtual void set_body(std::string const & body); - virtual void append_body(std::string const & data); - - // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); - virtual void get_headers(function inserter); - virtual void get_headers(std::string const & name, function inserter); - virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string & body); - virtual void get_body(function)> chunk_reader, size_t size); - void swap(message & other); - - // Destructor - virtual ~message(); - private: - message_pimpl * pimpl; - }; - - inline void swap(message & left, message & right) { - left.swap(right); - } - - template - message_base & operator<< (message_base & msg, Directive directive) { - directive(msg); - return msg; - } - -} // namespace network -} // namespace boost - -#ifdef BOOST_NETWORK_NO_LIB -#include -#endif - -#endif // __NETWORK_MESSAGE_HPP__ +#endif // BOOST_NETWORK_MESSAGE_HPP_20111021 diff --git a/boost/network/message/directives/header.hpp b/boost/network/message/directives/header.hpp index c223d721f..23c849508 100644 --- a/boost/network/message/directives/header.hpp +++ b/boost/network/message/directives/header.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { @@ -41,4 +41,3 @@ header(std::string const & header_name, std::string const & header_value) { } // namespace boost #endif // __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ - diff --git a/boost/network/message/message.hpp b/boost/network/message/message.hpp new file mode 100644 index 000000000..5684b721a --- /dev/null +++ b/boost/network/message/message.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_NETWORK_MESSAGE_MESSAGE_HPP_20111021 +#define BOOST_NETWORK_MESSAGE_MESSAGE_HPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +namespace boost { namespace network { + +struct message_pimpl; + +/** The common message type. + */ +struct message : message_base { + // Nested types + typedef iterator_range< + shared_container_iterator > > + headers_range; + + // Constructors + message(); + message(message const & other); + + // Assignment + message & operator=(message other); + + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers( + function inserter); + virtual void get_headers( + std::string const & name, + function inserter); + virtual void get_headers( + function predicate, + function inserter); + virtual void get_body(std::string & body); + virtual void get_body( + function)> chunk_reader, + size_t size); + void swap(message & other); + + // Destructor + virtual ~message(); + private: + message_pimpl * pimpl; +}; + +inline void swap(message & left, message & right) { + left.swap(right); +} + +template +message_base & operator<< (message_base & msg, Directive directive) { + directive(msg); + return msg; +} + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_MESSAGE_MESSAGE_HPP_20111021 */ diff --git a/boost/network/message.ipp b/boost/network/message/message.ipp similarity index 99% rename from boost/network/message.ipp rename to boost/network/message/message.ipp index afd90a12d..370cdbe2e 100644 --- a/boost/network/message.ipp +++ b/boost/network/message/message.ipp @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace boost { namespace network { diff --git a/boost/network/message_base.hpp b/boost/network/message/message_base.hpp similarity index 100% rename from boost/network/message_base.hpp rename to boost/network/message/message_base.hpp diff --git a/boost/network/message_base.ipp b/boost/network/message/message_base.ipp similarity index 100% rename from boost/network/message_base.ipp rename to boost/network/message/message_base.ipp diff --git a/boost/network/message/modifiers/clear_headers.hpp b/boost/network/message/modifiers/clear_headers.hpp index 077337e7c..671cf0b7d 100644 --- a/boost/network/message/modifiers/clear_headers.hpp +++ b/boost/network/message/modifiers/clear_headers.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { diff --git a/boost/network/message/modifiers/remove_header.hpp b/boost/network/message/modifiers/remove_header.hpp index fbbc12170..d14146a41 100644 --- a/boost/network/message/modifiers/remove_header.hpp +++ b/boost/network/message/modifiers/remove_header.hpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include namespace boost { namespace network { @@ -22,4 +22,3 @@ void remove_header(message_base & message, std::string const & key) { } // namespace boost #endif // BOOST_NETWORK_MESSAGE_MODIFIER_REMOVE_HEADER_HPP_20100824 - diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index ce19f8d0b..093334fb2 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include namespace boost { namespace network { @@ -49,4 +49,3 @@ body(message_base & message_) { #endif #endif // __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ - diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index f4e94764e..4330f115b 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { @@ -34,4 +34,3 @@ destination(message_base & message_) { #endif #endif // __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ - diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 7485f6b73..788ec90a5 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { diff --git a/boost/network/protocol/http/message/directives/status.hpp b/boost/network/protocol/http/message/directives/status.hpp index 2b910d595..6560607ab 100644 --- a/boost/network/protocol/http/message/directives/status.hpp +++ b/boost/network/protocol/http/message/directives/status.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/method.hpp b/boost/network/protocol/http/message/modifiers/method.hpp index f2101479a..98a747f0b 100644 --- a/boost/network/protocol/http/message/modifiers/method.hpp +++ b/boost/network/protocol/http/message/modifiers/method.hpp @@ -6,7 +6,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/status.hpp b/boost/network/protocol/http/message/modifiers/status.hpp index ca6024e09..66675fa8e 100644 --- a/boost/network/protocol/http/message/modifiers/status.hpp +++ b/boost/network/protocol/http/message/modifiers/status.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/status_message.hpp b/boost/network/protocol/http/message/modifiers/status_message.hpp index 3d24601cc..ad12bf637 100644 --- a/boost/network/protocol/http/message/modifiers/status_message.hpp +++ b/boost/network/protocol/http/message/modifiers/status_message.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/modifiers/version.hpp b/boost/network/protocol/http/message/modifiers/version.hpp index ee668fc07..1af1ac567 100644 --- a/boost/network/protocol/http/message/modifiers/version.hpp +++ b/boost/network/protocol/http/message/modifiers/version.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/wrappers/method.hpp b/boost/network/protocol/http/message/wrappers/method.hpp index a122a5b2b..0219d69b5 100644 --- a/boost/network/protocol/http/message/wrappers/method.hpp +++ b/boost/network/protocol/http/message/wrappers/method.hpp @@ -6,7 +6,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/wrappers/status_message.hpp b/boost/network/protocol/http/message/wrappers/status_message.hpp index a7c19165c..40c5306a3 100644 --- a/boost/network/protocol/http/message/wrappers/status_message.hpp +++ b/boost/network/protocol/http/message/wrappers/status_message.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/message/wrappers/uri.hpp b/boost/network/protocol/http/message/wrappers/uri.hpp index 222f24e09..505ebc078 100644 --- a/boost/network/protocol/http/message/wrappers/uri.hpp +++ b/boost/network/protocol/http/message/wrappers/uri.hpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/request.hpp b/boost/network/protocol/http/request.hpp index edb7b0406..ae0098a6b 100644 --- a/boost/network/protocol/http/request.hpp +++ b/boost/network/protocol/http/request.hpp @@ -1,16 +1,15 @@ -#ifndef __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ -#define __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_HPP_20111021 +#define BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_HPP_20111021 // Copyright Dean Michael Berris 2007. // Copyright 2011 Dean Michael Berris . -// Copyright 2011 Google, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include -#include #include #include #include @@ -33,73 +32,7 @@ #include #include +#include +#include -namespace boost { namespace network { namespace http { - -struct request_pimpl; - -struct request : request_base { - // FIXME Implement all these! - - // From message_base... - // Mutators - virtual void set_destination(std::string const & destination); - virtual void set_source(std::string const & source); - virtual void append_header(std::string const & name, - std::string const & value); - virtual void remove_headers(std::string const & name); - virtual void remove_headers(); - virtual void set_body(std::string const & body); - virtual void append_body(std::string const & data); - - // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); - virtual void get_headers(function inserter); - virtual void get_headers(std::string const & name, function inserter); - virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string & body); - virtual void get_body(function)> chunk_reader, size_t size); - - // From request_base... - // Setters - virtual void set_method(std::string const & method); - virtual void set_status(std::string const & status); - virtual void set_status_message(std::string const & status_message); - virtual void set_body_stream(shared_ptr stream); - virtual void set_uri(std::string const &uri); - virtual void set_uri(network::uri::uri const &uri); - - // Getters - virtual void get_uri(network::uri::uri &uri); - virtual void get_uri(std::string &uri); - virtual void get_method(std::string & method); - virtual void get_status(std::string & status); - virtual void get_status_message(std::string & status_message); - virtual void get_body_stream(body_stream & output_stream); - - virtual ~request(); - private: - request_pimpl * pimpl_; -}; - -template -request_base & operator<< (request_base & request, - Directive const & directive) { - directive(request); - return request; -} - -} // namespace http - -} // namespace network - -} // namespace boost - -#ifdef BOOST_NETWORK_NO_LIB -#include -#endif - -#include - -#endif // __NETWORK_PROTOCOL_HTTP_REQUEST_20070908-1_HPP__ +#endif // BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_HPP_20111021 diff --git a/boost/network/protocol/http/request/request.hpp b/boost/network/protocol/http/request/request.hpp new file mode 100644 index 000000000..eab2164d2 --- /dev/null +++ b/boost/network/protocol/http/request/request.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_REQUEST_HPP_20111021 +#define BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_REQUEST_HPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +struct request_pimpl; + +struct request : request_base { + // FIXME Implement all these! + + // From message_base... + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers(function inserter); + virtual void get_headers(std::string const & name, function inserter); + virtual void get_headers(function predicate, function inserter); + virtual void get_body(std::string & body); + virtual void get_body(function)> chunk_reader, size_t size); + + // From request_base... + // Setters + virtual void set_method(std::string const & method); + virtual void set_status(std::string const & status); + virtual void set_status_message(std::string const & status_message); + virtual void set_body_stream(shared_ptr stream); + virtual void set_uri(std::string const &uri); + virtual void set_uri(network::uri::uri const &uri); + + // Getters + virtual void get_uri(network::uri::uri &uri); + virtual void get_uri(std::string &uri); + virtual void get_method(std::string & method); + virtual void get_status(std::string & status); + virtual void get_status_message(std::string & status_message); + virtual void get_body_stream(body_stream & output_stream); + + virtual ~request(); + private: + request_pimpl * pimpl_; +}; + +template +request_base & operator<< (request_base & request, + Directive const & directive) { + directive(request); + return request; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_REQUEST_HPP_20111021 */ diff --git a/boost/network/protocol/http/request.ipp b/boost/network/protocol/http/request/request.ipp similarity index 100% rename from boost/network/protocol/http/request.ipp rename to boost/network/protocol/http/request/request.ipp diff --git a/boost/network/protocol/http/request_base.hpp b/boost/network/protocol/http/request/request_base.hpp similarity index 98% rename from boost/network/protocol/http/request_base.hpp rename to boost/network/protocol/http/request/request_base.hpp index 2d532754a..d8369cdff 100644 --- a/boost/network/protocol/http/request_base.hpp +++ b/boost/network/protocol/http/request/request_base.hpp @@ -11,7 +11,7 @@ #define BOOST_NETWORK_BUFFER_CHUNK 1024 // We want 1KiB worth of data at least. #endif -#include +#include #include #include diff --git a/boost/network/protocol/http/request_concept.hpp b/boost/network/protocol/http/request/request_concept.hpp similarity index 100% rename from boost/network/protocol/http/request_concept.hpp rename to boost/network/protocol/http/request/request_concept.hpp diff --git a/boost/network/protocol/http/response.hpp b/boost/network/protocol/http/response.hpp index f8e1aa094..70a9f0521 100644 --- a/boost/network/protocol/http/response.hpp +++ b/boost/network/protocol/http/response.hpp @@ -9,7 +9,7 @@ #include -#include +#include #include #include #include @@ -25,64 +25,7 @@ #include #include -#include - -namespace boost { namespace network { namespace http { - -struct response : response_base { - // FIXME implement all these! - - // From message_base... - // Mutators - virtual void set_destination(std::string const & destination); - virtual void set_source(std::string const & source); - virtual void append_header(std::string const & name, - std::string const & value); - virtual void remove_headers(std::string const & name); - virtual void remove_headers(); - virtual void set_body(std::string const & body); - virtual void append_body(std::string const & data); - - // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); - virtual void get_headers(function inserter); - virtual void get_headers(std::string const & name, function inserter); - virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string & body); - virtual void get_body(function)> chunk_reader, size_t size); - - // From response_base... - virtual void set_status(std::string const & new_status); - virtual void set_status_message(std::string const & new_status_message); - virtual void set_version(std::string const & new_version); - virtual ~response(); -}; - -} // namespace http - -} // namespace network - -} // namespace boost - -#include - -namespace boost { namespace network { namespace http { - - template - response & operator<<( - response & message, - Directive const & directive - ) - { - directive(message); - return message; - } - -} // namespace http - -} // namespace network - -} // namespace boost +#include +#include #endif // BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_HPP diff --git a/boost/network/protocol/http/response/response.hpp b/boost/network/protocol/http/response/response.hpp new file mode 100644 index 000000000..7b22c0cac --- /dev/null +++ b/boost/network/protocol/http/response/response.hpp @@ -0,0 +1,65 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_HPP_20111021 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_HPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { namespace network { namespace http { + +struct response : response_base { + // FIXME implement all these! + + // From message_base... + // Mutators + virtual void set_destination(std::string const & destination); + virtual void set_source(std::string const & source); + virtual void append_header(std::string const & name, + std::string const & value); + virtual void remove_headers(std::string const & name); + virtual void remove_headers(); + virtual void set_body(std::string const & body); + virtual void append_body(std::string const & data); + + // Retrievers + virtual void get_destination(std::string & destination); + virtual void get_source(std::string & source); + virtual void get_headers( + function inserter); + virtual void get_headers( + std::string const & name, + function inserter); + virtual void get_headers( + function predicate, + function inserter); + virtual void get_body(std::string & body); + virtual void get_body( + function)> chunk_reader, + size_t size); + + // From response_base... + virtual void set_status(std::string const & new_status); + virtual void set_status_message(std::string const & new_status_message); + virtual void set_version(std::string const & new_version); + virtual ~response(); +}; + +template +response & operator<<( + response & message, + Directive const & directive + ) +{ + directive(message); + return message; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_HPP_20111021 */ diff --git a/boost/network/protocol/http/response_base.hpp b/boost/network/protocol/http/response/response_base.hpp similarity index 100% rename from boost/network/protocol/http/response_base.hpp rename to boost/network/protocol/http/response/response_base.hpp diff --git a/boost/network/protocol/http/response_concept.hpp b/boost/network/protocol/http/response/response_concept.hpp similarity index 100% rename from boost/network/protocol/http/response_concept.hpp rename to boost/network/protocol/http/response/response_concept.hpp diff --git a/libs/network/src/message.cpp b/libs/network/src/message.cpp index eb2f65a04..bc54a74e7 100644 --- a/libs/network/src/message.cpp +++ b/libs/network/src/message.cpp @@ -11,4 +11,4 @@ #undef BOOST_NETWORK_NO_LIB #endif -#include +#include From 3a68cff37ab86f92f794cc3aa687fd7b6599d5f3 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 21 Oct 2011 16:27:15 +1100 Subject: [PATCH 034/438] Fleshing out more implementations. --- boost/network/message/directives/header.hpp | 23 +++--- boost/network/message/directives/header.ipp | 28 ++++++++ .../message/directives/remove_header.hpp | 20 +++--- .../message/directives/remove_header.ipp | 27 +++++++ boost/network/message/message_base.ipp | 2 +- boost/network/message/wrappers/body.hpp | 11 ++- boost/network/message/wrappers/body.ipp | 71 +++++++++++++++++++ .../network/message/wrappers/destination.hpp | 9 ++- .../network/message/wrappers/destination.ipp | 33 +++++++++ boost/network/message/wrappers/headers.hpp | 19 ++--- boost/network/message/wrappers/headers.ipp | 50 ++++++++----- boost/network/message/wrappers/source.hpp | 9 +-- boost/network/message/wrappers/source.ipp | 33 +++++++++ libs/network/build/CMakeLists.txt | 11 ++- libs/network/src/CMakeLists.txt | 11 ++- libs/network/src/message/directives.cpp | 15 ++++ libs/network/src/{ => message}/message.cpp | 1 + libs/network/src/message/wrappers.cpp | 13 ++++ libs/network/test/CMakeLists.txt | 16 +++-- libs/network/test/message_test.cpp | 5 +- 20 files changed, 330 insertions(+), 77 deletions(-) create mode 100644 boost/network/message/directives/header.ipp create mode 100644 boost/network/message/directives/remove_header.ipp create mode 100644 boost/network/message/wrappers/body.ipp create mode 100644 boost/network/message/wrappers/destination.ipp create mode 100644 boost/network/message/wrappers/source.ipp create mode 100644 libs/network/src/message/directives.cpp rename libs/network/src/{ => message}/message.cpp (90%) create mode 100644 libs/network/src/message/wrappers.cpp diff --git a/boost/network/message/directives/header.hpp b/boost/network/message/directives/header.hpp index 23c849508..9edc7e0b0 100644 --- a/boost/network/message/directives/header.hpp +++ b/boost/network/message/directives/header.hpp @@ -14,21 +14,12 @@ namespace boost { namespace network { namespace impl { struct header_directive { - - explicit header_directive(std::string const & header_name, - std::string const & header_value) : - _header_name(header_name), - _header_value(header_value) - { }; - - void operator() (message_base & msg) const { - msg.append_header(_header_name, _header_value); - } - + explicit header_directive(std::string const & name, + std::string const & value); + void operator() (message_base & msg) const; private: - - std::string const & _header_name; - std::string const & _header_value; + std::string const & name_; + std::string const & value_; }; } // namespace impl @@ -40,4 +31,8 @@ header(std::string const & header_name, std::string const & header_value) { } // namespace network } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif // __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ diff --git a/boost/network/message/directives/header.ipp b/boost/network/message/directives/header.ipp new file mode 100644 index 000000000..5c5401a1f --- /dev/null +++ b/boost/network/message/directives/header.ipp @@ -0,0 +1,28 @@ +#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_IPP_20111021 +#define BOOST_NETWORK_MESSAGE_DIRECTIVES_IPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace impl { + +header_directive::header_directive(std::string const & name, + std::string const & value): + name_(name), + value_(value) {} + +void header_directive::operator() (message_base & msg) const { + msg.append_header(name_, value_); +} + +} /* impl */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_IPP_20111021 */ diff --git a/boost/network/message/directives/remove_header.hpp b/boost/network/message/directives/remove_header.hpp index 1a1f4f63e..958434b46 100644 --- a/boost/network/message/directives/remove_header.hpp +++ b/boost/network/message/directives/remove_header.hpp @@ -1,13 +1,11 @@ +#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP_20111021 +#define BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP_20111021 // Copyright 2011 Dean Michael Berris . -// Copyright 2011 Google, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP -#define NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP - +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) namespace boost { namespace network { @@ -15,7 +13,7 @@ namespace impl { struct remove_header_directive { explicit remove_header_directive(std::string const & header_name); - void operator() (message_base & msg) const; + void operator() (message_base & msg) const; private: std::string const & header_name_; }; @@ -29,6 +27,8 @@ remove_header(std::string const & header_name) { } // namespace network } // namespace boost +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif -#endif // NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP - +#endif // BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP_20111021 diff --git a/boost/network/message/directives/remove_header.ipp b/boost/network/message/directives/remove_header.ipp new file mode 100644 index 000000000..b732983e6 --- /dev/null +++ b/boost/network/message/directives/remove_header.ipp @@ -0,0 +1,27 @@ +#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_IPP_20111021 +#define BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_IPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace impl { + +remove_header_directive::remove_header_directive(std::string const & header_name): + header_name_(header_name) {} + +void remove_header_directive::operator() (message_base & msg) const { + msg.remove_headers(header_name_); +} + +} /* impl */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_IPP_20111021 */ diff --git a/boost/network/message/message_base.ipp b/boost/network/message/message_base.ipp index 061d2a6f6..0ef383e9b 100644 --- a/boost/network/message/message_base.ipp +++ b/boost/network/message/message_base.ipp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index 093334fb2..cf0b37d78 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -1,12 +1,11 @@ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 // Copyright 2011 Dean Michael Berris . // Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 -#define BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_HPP_20110930 +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) #include #include @@ -17,7 +16,7 @@ namespace boost { namespace network { namespace impl { struct body_wrapper { - explicit body_wrapper(message_base & message_); + explicit body_wrapper(message_base & message); operator std::string () const; std::size_t size() const; operator iterator_range () const; diff --git a/boost/network/message/wrappers/body.ipp b/boost/network/message/wrappers/body.ipp new file mode 100644 index 000000000..0c24f67bc --- /dev/null +++ b/boost/network/message/wrappers/body.ipp @@ -0,0 +1,71 @@ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_IPP_20111021 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_IPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace impl { + +body_wrapper::body_wrapper(message_base & message): + message_(message) {} + +body_wrapper::operator std::string () const { + if (cache_) { + return *cache_; + } + std::string tmp; + message_.get_body(tmp); + cache_ = tmp; + return *cache_; +} + +std::size_t body_wrapper::size() const { + if (cache_) { + return cache_->size(); + } + std::string tmp; + message_.get_body(tmp); + cache_ = tmp; + return cache_->size(); +} + +body_wrapper::operator boost::iterator_range () const { + if (cache_) { + return boost::make_iterator_range(*cache_); + } + std::string tmp; + message_.get_body(tmp); + cache_ = tmp; + return boost::make_iterator_range(*cache_); +} + +std::string::const_iterator body_wrapper::begin() const { + if (cache_) { + return cache_->begin(); + } + std::string tmp; + message_.get_body(tmp); + cache_ = tmp; + return cache_->begin(); +} + +std::string::const_iterator body_wrapper::end() const { + if (cache_) { + return cache_->end(); + } + std::string tmp; + message_.get_body(tmp); + cache_ = tmp; + return cache_->end(); +} + +} /* impl */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_WRAPPERS_BODY_IPP_20111021 */ diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index 4330f115b..a6d9e355c 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -2,7 +2,7 @@ #define __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ // Copyright 2011 Dean Michael Berris . -// Copyright 2011 Google, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -14,8 +14,11 @@ namespace boost { namespace network { namespace impl { struct destination_wrapper { - explicit destination_wrapper(message_base & message_); - operator std::string () const; + explicit destination_wrapper(message_base & message); + operator std::string () const; + private: + message_base & message_; + mutable optional cache_; }; } // namespace impl diff --git a/boost/network/message/wrappers/destination.ipp b/boost/network/message/wrappers/destination.ipp new file mode 100644 index 000000000..cb99e62f5 --- /dev/null +++ b/boost/network/message/wrappers/destination.ipp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_DESTINATION_IPP_20111021 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_DESTINATION_IPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace impl { + +destination_wrapper::destination_wrapper(message_base & message): + message_(message) {} + +destination_wrapper::operator std::string () const { + if (cache_) { + return *cache_; + } + std::string tmp; + message_.get_destination(tmp); + cache_ = tmp; + return *cache_; +} + +} /* impl */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_WRAPPERS_DESTINATION_IPP_20111021 */ diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index 41f4daab4..71a5e1907 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -24,27 +24,23 @@ namespace impl { * a range of iterators (std::pair) * whose keys are all equal to the index string. * - * This type is also convertible to a - * headers_range >::type - * Which allows for full range support. - * - * The type is also convertible to a - * headers_container::type - * Which copies the headers from the wrapped message. - * */ struct headers_wrapper { typedef std::multimap container_type; - typedef iterator_range > - range_type; + typedef shared_container_iterator iterator; + typedef iterator_range range_type; explicit headers_wrapper(message_base & message); range_type operator[] (std::string const & key) const; operator range_type () const; + operator container_type () const; container_type::size_type count() const; container_type::size_type count(std::string const &key) const; + iterator begin() const; + iterator end() const; private: - void init_cache_all(); + void init_cache_all() const; + message_base & message_; mutable shared_ptr cache_; }; @@ -65,4 +61,3 @@ headers(message_base & message_) { #endif #endif // __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ - diff --git a/boost/network/message/wrappers/headers.ipp b/boost/network/message/wrappers/headers.ipp index b2afc7751..80825fd23 100644 --- a/boost/network/message/wrappers/headers.ipp +++ b/boost/network/message/wrappers/headers.ipp @@ -8,60 +8,76 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include -namespace boost { namespace network { +namespace boost { namespace network { namespace impl { headers_wrapper::headers_wrapper(message_base & message) : message_(message) {} -range_type headers_wrapper::operator[] (std::string const & key) const { - cache_.reset(new (std::nothrow) container_type); - if (!cache_.get()) - BOOST_THROW_EXCEPTION(std::runtime_error( - "Cannot allocate cache multimap for headers wrapper.")); - message_.get_headers( - key, - std::inserter(*cache_, cache_->end())); - return make_shared_container_range(cache_); +headers_wrapper::range_type headers_wrapper::operator[] (std::string const & key) const { + this->init_cache_all(); + std::pair p = + cache_->equal_range(key); + return boost::make_iterator_range( + boost::make_shared_container_iterator( + p.first, cache_), + boost::make_shared_container_iterator( + p.second, cache_)); } headers_wrapper::container_type::size_type -headers_wrapper::count(string_type const & key) const { +headers_wrapper::count(std::string const & key) const { this->init_cache_all(); return cache_->size(); } headers_wrapper::iterator headers_wrapper::begin() const { this->init_cache_all(); - return make_shared_container_iterator(cache_->begin()); + container_type::iterator begin = cache_->begin(); + return make_shared_container_iterator(begin, cache_); } headers_wrapper::iterator headers_wrapper::end() const { this->init_cache_all(); - return make_shared_container_iterator(cache_->end()); + container_type::iterator end = cache_->end(); + return make_shared_container_iterator(end, cache_); }; -headers_wrapper::operator headers_wrapper::range_type () { +headers_wrapper::operator headers_wrapper::range_type () const { this->init_cache_all(); return make_shared_container_range(cache_); }; -headers_wrapper::operator headers_wrapper::container_type () { +headers_wrapper::operator headers_wrapper::container_type () const { this->init_cache_all(); return *cache_; } -void headers_wrapper::init_cache_all() { +template +struct kv_inserter { + kv_inserter(Map & m) + : m_(m) {} + void operator() (std::string const & k, std::string const & v) const { + m_.insert(std::make_pair(k, v)); + } + private: + Map & m_; +}; + +void headers_wrapper::init_cache_all() const { if (!cache_.get()) { cache_.reset(new (std::nothrow) container_type); if (!cache_.get()) BOOST_THROW_EXCEPTION(std::runtime_error( "Cannot allocate cache multimap for headers wrapper.")); - message_.get_headers(std::inserter(*cache_, cache_->end())); + message_.get_headers(kv_inserter(*cache_)); } } +} /* impl */ + } /* network */ } /* boost */ diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 788ec90a5..84c7f6fe8 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -1,5 +1,5 @@ -#ifndef __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ -#define __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP_20111021 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP_20111021 // Copyright 2011 Dean Michael Berris . // Copyright 2011 Google, Inc. @@ -14,10 +14,11 @@ namespace boost { namespace network { namespace impl { struct source_wrapper { - explicit source_wrapper(message_base & message_); + explicit source_wrapper(message_base & message); operator std::string () const; private: message_base & message_; + mutable boost::optional cache_; }; } // namespace impl @@ -35,4 +36,4 @@ source(message_base & message_) { #include #endif -#endif // __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ +#endif // BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP_20111021 diff --git a/boost/network/message/wrappers/source.ipp b/boost/network/message/wrappers/source.ipp new file mode 100644 index 000000000..829d3876f --- /dev/null +++ b/boost/network/message/wrappers/source.ipp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_IPP_20111021 +#define BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_IPP_20111021 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace impl { + +source_wrapper::source_wrapper(message_base & message): + message_(message) {} + +source_wrapper::operator std::string () const { + if (cache_) { + return *cache_; + } + std::string tmp; + message_.get_source(tmp); + cache_ = tmp; + return *cache_; +} + +} /* impl */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_WRAPPERS_SOURCE_IPP_20111021 */ diff --git a/libs/network/build/CMakeLists.txt b/libs/network/build/CMakeLists.txt index e7dbee625..305bb82ce 100644 --- a/libs/network/build/CMakeLists.txt +++ b/libs/network/build/CMakeLists.txt @@ -3,4 +3,13 @@ find_package( Boost 1.43.0 COMPONENTS unit_test_framework system regex thread fi add_library(cppnetlib-uri STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/parse_uri_impl.cpp) add_library(cppnetlib-server-parsers STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/server_request_parsers_impl.cpp) -add_library(cppnetlib-message STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/message.cpp) +add_library(cppnetlib-message + STATIC + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/message/message.cpp) +add_library(cppnetlib-message-directives + STATIC + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/message/directives.cpp) +add_library(cppnetlib-http-message + STATIC + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/request.cpp + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/response.cpp) diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 9e38860f6..6680dbd89 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -16,5 +16,14 @@ add_library(cppnetlib-server-parsers ${CPP-NETLIB_HTTP_SERVER_SRCS}) set(CPP-NETLIB_HTTP_CLIENT_SRCS client.cpp) add_library(cppnetlib-client-connections ${CPP-NETLIB_HTTP_CLIENT_SRCS}) -set(CPP-NETLIB_MESSAGE_SRCS message.cpp) +set(CPP-NETLIB_MESSAGE_SRCS message/message.cpp) add_library(cppnetlib-message ${CPP-NETLIB_MESSAGE_SRCS}) + +set(CPP-NETLIB_MESSAGE_DIRECTIVES_SRCS message/directives.cpp) +add_library(cppnetlib-message-directives ${CPP-NETLIB_MESSAGE_DIRECTIVES_SRCS}) + +set(CPP-NETLIB_MESSAGE_WRAPPERS_SRCS message/wrappers.cpp) +add_library(cppnetlib-message-wrappers ${CPP-NETLIB_MESSAGE_WRAPPERS_SRCS}) + +set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) +add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) diff --git a/libs/network/src/message/directives.cpp b/libs/network/src/message/directives.cpp new file mode 100644 index 000000000..960ce80d9 --- /dev/null +++ b/libs/network/src/message/directives.cpp @@ -0,0 +1,15 @@ +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This is the directives file where all standard directives on messages are +// pulled in and compiled into a library. + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include +#include diff --git a/libs/network/src/message.cpp b/libs/network/src/message/message.cpp similarity index 90% rename from libs/network/src/message.cpp rename to libs/network/src/message/message.cpp index bc54a74e7..d92958017 100644 --- a/libs/network/src/message.cpp +++ b/libs/network/src/message/message.cpp @@ -12,3 +12,4 @@ #endif #include +#include diff --git a/libs/network/src/message/wrappers.cpp b/libs/network/src/message/wrappers.cpp new file mode 100644 index 000000000..95374e599 --- /dev/null +++ b/libs/network/src/message/wrappers.cpp @@ -0,0 +1,13 @@ +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file conglomerates all the standard wrappers that come with cpp-netlib. +// It just includes all the implementation files that get turned into a library. + +#include +#include +#include +#include diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 7e3b7a531..48bc6a707 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -22,11 +22,19 @@ if (Boost_FOUND) set_source_files_properties(${test}.cpp PROPERTIES COMPILE_FLAGS "-Wall") add_executable(cpp-netlib-${test} ${test}.cpp) - add_dependencies(cpp-netlib-${test} cppnetlib-uri cppnetlib-message) + add_dependencies(cpp-netlib-${test} + cppnetlib-uri + cppnetlib-message + cppnetlib-message-directives + cppnetlib-message-wrappers) - # add_dependencies(cpp-netlib-${test} cppnetlib-uri) - # target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri) - target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri cppnetlib-message) + target_link_libraries(cpp-netlib-${test} + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + cppnetlib-uri + cppnetlib-message + cppnetlib-message-directives + cppnetlib-message-wrappers) if (OPENSSL_FOUND) target_link_libraries(cpp-netlib-${test} ${OPENSSL_LIBRARIES}) endif() diff --git a/libs/network/test/message_test.cpp b/libs/network/test/message_test.cpp index 775ee8087..ae61973d8 100644 --- a/libs/network/test/message_test.cpp +++ b/libs/network/test/message_test.cpp @@ -7,9 +7,8 @@ #define BOOST_TEST_MODULE message test #include #include -#include +#include #include -#include using namespace boost::network; @@ -71,5 +70,3 @@ BOOST_AUTO_TEST_CASE(remove_header_directive_test) { message::headers_range range = headers(instance); BOOST_CHECK ( boost::begin(range) == boost::end(range) ); } - - From fcc93d7870021e7deb67c9b393812eeb965f640e Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sat, 22 Oct 2011 08:22:22 +0200 Subject: [PATCH 035/438] Some minor fixes to make sure that the tests could build on MSVC. --- boost/network/message/message.ipp | 1 + libs/network/src/CMakeLists.txt | 4 ++-- libs/network/test/message_test.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/boost/network/message/message.ipp b/boost/network/message/message.ipp index 370cdbe2e..88f17ba9e 100644 --- a/boost/network/message/message.ipp +++ b/boost/network/message/message.ipp @@ -135,6 +135,7 @@ message::message(message const & other) message& message::operator=(message other) { *pimpl = *other.pimpl; + return *this; } message::~message() { diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 6680dbd89..1e87917b5 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -25,5 +25,5 @@ add_library(cppnetlib-message-directives ${CPP-NETLIB_MESSAGE_DIRECTIVES_SRCS}) set(CPP-NETLIB_MESSAGE_WRAPPERS_SRCS message/wrappers.cpp) add_library(cppnetlib-message-wrappers ${CPP-NETLIB_MESSAGE_WRAPPERS_SRCS}) -set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) -add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) +#set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) +#add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) diff --git a/libs/network/test/message_test.cpp b/libs/network/test/message_test.cpp index ae61973d8..92a6b9103 100644 --- a/libs/network/test/message_test.cpp +++ b/libs/network/test/message_test.cpp @@ -67,6 +67,6 @@ BOOST_AUTO_TEST_CASE(remove_header_directive_test) { message instance; instance << header("name", "value") << remove_header("name"); - message::headers_range range = headers(instance); + message::headers_range range = headers(instance)["name"]; BOOST_CHECK ( boost::begin(range) == boost::end(range) ); } From f867bdb9e8a229e50a5174c4554938e87f9e1564 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 28 Oct 2011 13:48:27 +1100 Subject: [PATCH 036/438] Adding missing HTTP implementations. --- libs/network/src/http/request.cpp | 0 libs/network/src/http/response.cpp | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 libs/network/src/http/request.cpp create mode 100644 libs/network/src/http/response.cpp diff --git a/libs/network/src/http/request.cpp b/libs/network/src/http/request.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/libs/network/src/http/response.cpp b/libs/network/src/http/response.cpp new file mode 100644 index 000000000..e69de29bb From 144f21d519c356d07ffae41872243be860ce6d09 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 28 Oct 2011 13:58:14 +1100 Subject: [PATCH 037/438] Fixes to transformer and thread pool libs. --- boost/network/include/message.hpp | 1 - .../network/message/transformers/to_lower.hpp | 113 +++++++++--------- .../network/message/transformers/to_upper.hpp | 86 ++++++------- boost/network/utils/thread_pool.hpp | 109 ++++------------- libs/network/src/CMakeLists.txt | 3 + libs/network/test/CMakeLists.txt | 14 ++- 6 files changed, 140 insertions(+), 186 deletions(-) diff --git a/boost/network/include/message.hpp b/boost/network/include/message.hpp index 539292673..2f7d00897 100644 --- a/boost/network/include/message.hpp +++ b/boost/network/include/message.hpp @@ -8,7 +8,6 @@ // // This is the modular include file for using the basic message type -#include #include #endif // BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ diff --git a/boost/network/message/transformers/to_lower.hpp b/boost/network/message/transformers/to_lower.hpp index 75ed3a67b..aa2227c6e 100644 --- a/boost/network/message/transformers/to_lower.hpp +++ b/boost/network/message/transformers/to_lower.hpp @@ -8,6 +8,7 @@ #define __NETWORK_MESSAGE_TRANSFORMERS_TO_LOWER_HPP__ #include +#include /** to_lower.hpp * @@ -18,61 +19,63 @@ * This defines a type, to be applied using template * metaprogramming on the selected string target. */ -namespace boost { namespace network { - - namespace impl { - - template - struct to_lower_transformer { }; - - template <> - struct to_lower_transformer { - template - void operator() (basic_message & message_) const { - boost::to_lower(message_.source()); - } - - protected: - ~to_lower_transformer() { } - }; - - template <> - struct to_lower_transformer { - template - void operator() (basic_message & message_) const { - boost::to_lower(message_.destination()); - } - - protected: - ~to_lower_transformer() { }; - }; - - } // namespace impl - - namespace detail { - struct to_lower_placeholder_helper; - } - - detail::to_lower_placeholder_helper to_lower_(detail::to_lower_placeholder_helper); - - namespace detail { - - struct to_lower_placeholder_helper { - template - struct type : public impl::to_lower_transformer { }; - private: - to_lower_placeholder_helper() {} - to_lower_placeholder_helper(to_lower_placeholder_helper const &) {} - friend to_lower_placeholder_helper boost::network::to_lower_(to_lower_placeholder_helper); - }; - - } - - typedef detail::to_lower_placeholder_helper (*to_lower_placeholder)(detail::to_lower_placeholder_helper); - - inline detail::to_lower_placeholder_helper to_lower_(detail::to_lower_placeholder_helper) { - return detail::to_lower_placeholder_helper(); - } +namespace boost { namespace network { namespace impl { + +template +struct to_lower_transformer { }; + +template <> +struct to_lower_transformer { + void operator() (message_base & message_) const { + std::string source_; + message_.get_source(source_); + boost::to_lower(source_); + message_.set_source(source_); + } + + protected: + ~to_lower_transformer() { } +}; + +template <> +struct to_lower_transformer { + void operator() (message_base & message_) const { + std::string destination_; + message_.get_destination(destination_); + boost::to_lower(destination_); + message_.set_destination(destination_); + } + + protected: + ~to_lower_transformer() { }; +}; + +} // namespace impl + +namespace detail { + struct to_lower_placeholder_helper; +} + +detail::to_lower_placeholder_helper to_lower_(detail::to_lower_placeholder_helper); + +namespace detail { + +struct to_lower_placeholder_helper { + template + struct type : public impl::to_lower_transformer { }; + private: + to_lower_placeholder_helper() {} + to_lower_placeholder_helper(to_lower_placeholder_helper const &) {} + friend to_lower_placeholder_helper boost::network::to_lower_(to_lower_placeholder_helper); +}; + +} + +typedef detail::to_lower_placeholder_helper (*to_lower_placeholder)(detail::to_lower_placeholder_helper); + +inline detail::to_lower_placeholder_helper to_lower_(detail::to_lower_placeholder_helper) { + return detail::to_lower_placeholder_helper(); +} } // namespace network diff --git a/boost/network/message/transformers/to_upper.hpp b/boost/network/message/transformers/to_upper.hpp index 8ad11c09e..f8c684c16 100644 --- a/boost/network/message/transformers/to_upper.hpp +++ b/boost/network/message/transformers/to_upper.hpp @@ -8,6 +8,7 @@ #define __NETWORK_MESSAGE_TRANSFORMERS_TO_UPPER_HPP__ #include +#include /** to_upper.hpp * @@ -18,61 +19,64 @@ * This defines a type, to be applied using template * metaprogramming on the selected string target. */ -namespace boost { namespace network { +namespace boost { namespace network { namespace impl { - namespace impl { +template +struct to_upper_transformer { }; - template - struct to_upper_transformer { }; +template <> +struct to_upper_transformer { + void operator() (message_base & message_) const { + std::string source_; + message_.get_source(source_); + boost::to_upper(source_); + message_.set_source(source_); + } - template <> - struct to_upper_transformer { - template - void operator() (basic_message & message_) const { - boost::to_upper(message_.source()); - } + protected: + ~to_upper_transformer() { }; +}; - protected: - ~to_upper_transformer() { }; - }; +template <> +struct to_upper_transformer { + void operator() (message_base & message_) const { + std::string destination_; + message_.get_destination(destination_); + boost::to_upper(destination_); + message_.set_destination(destination_); + } - template <> - struct to_upper_transformer { - template - void operator() (basic_message & message_) const { - boost::to_upper(message_.destination()); - } + protected: + ~to_upper_transformer() { }; +}; - protected: - ~to_upper_transformer() { }; - }; +} // namespace impl - } // namespace impl +namespace detail { + struct to_upper_placeholder_helper; +} - namespace detail { - struct to_upper_placeholder_helper; - } +detail::to_upper_placeholder_helper to_upper_(detail::to_upper_placeholder_helper); - detail::to_upper_placeholder_helper to_upper_(detail::to_upper_placeholder_helper); +namespace detail { - namespace detail { +struct to_upper_placeholder_helper { + template + struct type : public impl::to_upper_transformer { }; - struct to_upper_placeholder_helper { - template - struct type : public impl::to_upper_transformer { }; - private: - to_upper_placeholder_helper() {} - to_upper_placeholder_helper(to_upper_placeholder_helper const &) {} - friend to_upper_placeholder_helper boost::network::to_upper_(to_upper_placeholder_helper); - }; + private: + to_upper_placeholder_helper() {} + to_upper_placeholder_helper(to_upper_placeholder_helper const &) {} + friend to_upper_placeholder_helper boost::network::to_upper_(to_upper_placeholder_helper); +}; - } +} - typedef detail::to_upper_placeholder_helper (*to_upper_placeholder)(detail::to_upper_placeholder_helper); +typedef detail::to_upper_placeholder_helper (*to_upper_placeholder)(detail::to_upper_placeholder_helper); - inline detail::to_upper_placeholder_helper to_upper_(detail::to_upper_placeholder_helper) { - return detail::to_upper_placeholder_helper(); - } +inline detail::to_upper_placeholder_helper to_upper_(detail::to_upper_placeholder_helper) { + return detail::to_upper_placeholder_helper(); +} } // namespace network diff --git a/boost/network/utils/thread_pool.hpp b/boost/network/utils/thread_pool.hpp index 1938f6d81..18c91ce3e 100644 --- a/boost/network/utils/thread_pool.hpp +++ b/boost/network/utils/thread_pool.hpp @@ -7,7 +7,6 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include #include #include #include @@ -16,98 +15,32 @@ namespace boost { namespace network { namespace utils { - typedef boost::shared_ptr io_service_ptr; - typedef boost::shared_ptr worker_threads_ptr; - typedef boost::shared_ptr sentinel_ptr; - - template - struct basic_thread_pool { - basic_thread_pool( - std::size_t threads = 1, - io_service_ptr io_service = io_service_ptr(), - worker_threads_ptr worker_threads = worker_threads_ptr() - ) - : threads_(threads) - , io_service_(io_service) - , worker_threads_(worker_threads) - , sentinel_() - { - bool commit = false; - BOOST_SCOPE_EXIT_TPL((&commit)(&io_service_)(&worker_threads_)(&sentinel_)) { - if (!commit) { - sentinel_.reset(); - io_service_.reset(); - if (worker_threads_.get()) { - worker_threads_->interrupt_all(); - worker_threads_->join_all(); - } - worker_threads_.reset(); - } - } BOOST_SCOPE_EXIT_END +typedef boost::shared_ptr io_service_ptr; +typedef boost::shared_ptr worker_threads_ptr; +typedef boost::shared_ptr sentinel_ptr; - if (!io_service_.get()) { - io_service_.reset(new boost::asio::io_service); - } +struct thread_pool_pimpl; - if (!worker_threads_.get()) { - worker_threads_.reset(new boost::thread_group); - } +struct thread_pool { + thread_pool(std::size_t threads = 1, + io_service_ptr io_service = io_service_ptr(), + worker_threads_ptr worker_threads = worker_threads_ptr()); + std::size_t const thread_count() const; + void post(function f); + ~thread_pool(); + void swap(thread_pool & other); + protected: + thread_pool_pimpl * pimpl; +}; - if (!sentinel_.get()) { - sentinel_.reset(new boost::asio::io_service::work(*io_service_)); - } +inline void swap(thread_pool & l, thread_pool & r) { + l.swap(r); +} - for (std::size_t counter = 0; counter < threads_; ++counter) - worker_threads_->create_thread( - boost::bind( - &boost::asio::io_service::run, - io_service_ - ) - ); +} // utils - commit = true; - } +} // network - std::size_t const thread_count() const { - return threads_; - } - - void post(boost::function f) { - io_service_->post(f); - } - - ~basic_thread_pool() throw () { - sentinel_.reset(); - try { - worker_threads_->join_all(); - } catch (...) { - BOOST_ASSERT(false && "A handler was not supposed to throw, but one did."); - } - } - - void swap(basic_thread_pool & other) { - std::swap(other.threads_, threads_); - std::swap(other.io_service_, io_service_); - std::swap(other.worker_threads_, worker_threads_); - std::swap(other.sentinel_, sentinel_); - } - protected: - std::size_t threads_; - io_service_ptr io_service_; - worker_threads_ptr worker_threads_; - sentinel_ptr sentinel_; - - private: - basic_thread_pool(basic_thread_pool const &); // no copies please - basic_thread_pool & operator=(basic_thread_pool); // no assignment please - }; - - typedef basic_thread_pool thread_pool; - -} /* utils */ - -} /* network */ - -} /* boost */ +} // boost #endif /* BOOST_NETWORK_UTILS_THREAD_POOL_HPP_20101020 */ diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 6680dbd89..75b77264e 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -27,3 +27,6 @@ add_library(cppnetlib-message-wrappers ${CPP-NETLIB_MESSAGE_WRAPPERS_SRCS}) set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) + +set(CPP-NETLIB_UTILS_THREAD_POOL_SRCS utils/thread_pool.cpp) +add_library(cppnetlib-utils-thread_pool ${CPP-NETLIB_UTILS_THREAD_POOL_SRCS}) diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index 48bc6a707..beb55f287 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -16,7 +16,6 @@ if (Boost_FOUND) TESTS message_test message_transform_test - utils_thread_pool ) foreach (test ${TESTS}) set_source_files_properties(${test}.cpp @@ -43,5 +42,18 @@ if (Boost_FOUND) add_test(cpp-netlib-${test} ${CPP-NETLIB_BINARY_DIR}/tests/cpp-netlib-${test}) endforeach (test) + set_source_files_properties(utils_thread_pool.cpp + PROPERTIES COMPILE_FLAGS "-Wall") + add_executable(cpp-netlib-utils_thread_pool utils_thread_pool.cpp) + add_dependencies(cpp-netlib-utils_thread_pool + cppnetlib-utils-thread_pool) + target_link_libraries(cpp-netlib-utils_thread_pool + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + cppnetlib-utils-thread_pool) + set_target_properties(cpp-netlib-utils_thread_pool + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CPP-NETLIB_BINARY_DIR}/tests) + add_test(cpp-netlib-utils_thread_pool ${CPP-NETLIB_BRINARY_DIR}/tests/cpp-netlib-utils_thread_pool) + endif() From f255c4c8007f8382376f78f6b03fb48bbb906d3f Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 28 Oct 2011 14:00:35 +1100 Subject: [PATCH 038/438] Adding missing files. --- boost/network/utils/thread_pool.ipp | 124 +++++++++++++++++++++++++ libs/network/src/http/request.cpp | 0 libs/network/src/http/response.cpp | 0 libs/network/src/utils/thread_pool.cpp | 7 ++ 4 files changed, 131 insertions(+) create mode 100644 boost/network/utils/thread_pool.ipp create mode 100644 libs/network/src/http/request.cpp create mode 100644 libs/network/src/http/response.cpp create mode 100644 libs/network/src/utils/thread_pool.cpp diff --git a/boost/network/utils/thread_pool.ipp b/boost/network/utils/thread_pool.ipp new file mode 100644 index 000000000..582739368 --- /dev/null +++ b/boost/network/utils/thread_pool.ipp @@ -0,0 +1,124 @@ +#ifndef BOOST_NETWORK_UTILS_THREAD_POOL_IPP_20111021 +#define BOOST_NETWORK_UTILS_THREAD_POOL_IPP_20111021 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace utils { + +struct thread_pool_pimpl { + thread_pool_pimpl( + std::size_t threads = 1, + io_service_ptr io_service = io_service_ptr(), + worker_threads_ptr worker_threads = worker_threads_ptr() + ) + : threads_(threads) + , io_service_(io_service) + , worker_threads_(worker_threads) + , sentinel_() + { + bool commit = false; + BOOST_SCOPE_EXIT((&commit)(&io_service_)(&worker_threads_)(&sentinel_)) { + if (!commit) { + sentinel_.reset(); + io_service_.reset(); + if (worker_threads_.get()) { + worker_threads_->interrupt_all(); + worker_threads_->join_all(); + } + worker_threads_.reset(); + } + } BOOST_SCOPE_EXIT_END + + if (!io_service_.get()) { + io_service_.reset(new boost::asio::io_service); + } + + if (!worker_threads_.get()) { + worker_threads_.reset(new boost::thread_group); + } + + if (!sentinel_.get()) { + sentinel_.reset(new boost::asio::io_service::work(*io_service_)); + } + + for (std::size_t counter = 0; counter < threads_; ++counter) + worker_threads_->create_thread( + boost::bind( + &boost::asio::io_service::run, + io_service_ + ) + ); + + commit = true; + } + + std::size_t const thread_count() const { + return threads_; + } + + void post(boost::function f) { + io_service_->post(f); + } + + ~thread_pool_pimpl() { + sentinel_.reset(); + try { + worker_threads_->join_all(); + } catch (...) { + BOOST_ASSERT(false && "A handler was not supposed to throw, but one did."); + std::abort(); + } + } + + void swap(thread_pool_pimpl & other) { + std::swap(other.threads_, threads_); + std::swap(other.io_service_, io_service_); + std::swap(other.worker_threads_, worker_threads_); + std::swap(other.sentinel_, sentinel_); + } +protected: + std::size_t threads_; + io_service_ptr io_service_; + worker_threads_ptr worker_threads_; + sentinel_ptr sentinel_; + +private: + thread_pool_pimpl(thread_pool_pimpl const &); // no copies please + thread_pool_pimpl & operator=(thread_pool_pimpl); // no assignment please +}; + +thread_pool::thread_pool(std::size_t threads, + io_service_ptr io_service, + worker_threads_ptr worker_threads) +: pimpl(new (std::nothrow) thread_pool_pimpl(threads, io_service, worker_threads)) +{} + +std::size_t const thread_pool::thread_count() const { + return pimpl->thread_count(); +} + +void thread_pool::post(function f) { + pimpl->post(f); +} + +void thread_pool::swap(thread_pool & other) { + std::swap(other.pimpl, this->pimpl); +} + +thread_pool::~thread_pool() { + delete pimpl; +} + +} /* utils */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_UTILS_THREAD_POOL_IPP_20111021 */ diff --git a/libs/network/src/http/request.cpp b/libs/network/src/http/request.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/libs/network/src/http/response.cpp b/libs/network/src/http/response.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/libs/network/src/utils/thread_pool.cpp b/libs/network/src/utils/thread_pool.cpp new file mode 100644 index 000000000..4254f43d4 --- /dev/null +++ b/libs/network/src/utils/thread_pool.cpp @@ -0,0 +1,7 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include From 5cf5a25341fe5c0fbe55c334871e0fbd8175811c Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Fri, 28 Oct 2011 14:06:55 +1100 Subject: [PATCH 039/438] Order of linking issue. --- libs/network/test/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/network/test/CMakeLists.txt b/libs/network/test/CMakeLists.txt index beb55f287..652ae3e10 100644 --- a/libs/network/test/CMakeLists.txt +++ b/libs/network/test/CMakeLists.txt @@ -48,9 +48,9 @@ if (Boost_FOUND) add_dependencies(cpp-netlib-utils_thread_pool cppnetlib-utils-thread_pool) target_link_libraries(cpp-netlib-utils_thread_pool + cppnetlib-utils-thread_pool ${Boost_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - cppnetlib-utils-thread_pool) + ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(cpp-netlib-utils_thread_pool PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CPP-NETLIB_BINARY_DIR}/tests) add_test(cpp-netlib-utils_thread_pool ${CPP-NETLIB_BRINARY_DIR}/tests/cpp-netlib-utils_thread_pool) From 3654e3fd93ecb7f70cb9e2f78e91d1b6f628959a Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Tue, 1 Nov 2011 23:17:47 +1100 Subject: [PATCH 040/438] Removing unnecessary tag include. --- libs/network/test/uri/url_builder_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/network/test/uri/url_builder_test.cpp b/libs/network/test/uri/url_builder_test.cpp index fb55e96ad..089f4ea5c 100644 --- a/libs/network/test/uri/url_builder_test.cpp +++ b/libs/network/test/uri/url_builder_test.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include From d9c30d7cfd6091fa870805e1b1f1153e928dbd30 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Wed, 2 Nov 2011 00:21:19 +1100 Subject: [PATCH 041/438] Getting the client_constructor_test to compile! --- boost/network/message/transformers.hpp | 29 ++++---- boost/network/message/wrappers/headers.hpp | 2 +- .../http/message/wrappers/version.hpp | 2 + .../http/policies/async_connection.hpp | 8 +++ .../test/http/client_constructor_test.cpp | 17 +++-- libs/network/test/http/client_types.hpp | 68 ------------------- libs/network/test/http/tag_types.hpp | 24 ------- 7 files changed, 33 insertions(+), 117 deletions(-) delete mode 100644 libs/network/test/http/client_types.hpp delete mode 100644 libs/network/test/http/tag_types.hpp diff --git a/boost/network/message/transformers.hpp b/boost/network/message/transformers.hpp index baea48f4b..68ad230ed 100644 --- a/boost/network/message/transformers.hpp +++ b/boost/network/message/transformers.hpp @@ -14,7 +14,7 @@ #include #include #include - +#include #include namespace boost { namespace network { @@ -37,23 +37,22 @@ namespace boost { namespace network { }; template - struct transform_impl : public get_real_algorithm::type { }; + struct transform_impl : public get_real_algorithm::type { }; } // namspace impl template - inline impl::transform_impl - transform(Algorithm, Selector) { - return impl::transform_impl(); - } - - template - inline basic_message & - operator<< (basic_message & msg_, - impl::transform_impl - const & transformer) { - transformer(msg_); - return msg_; - } + inline impl::transform_impl + transform(Algorithm, Selector) { + return impl::transform_impl(); + } + + template + message_base & operator<< ( + message_base & msg_, + impl::transform_impl const & transformer) { + transformer(msg_); + return msg_; + } } // namespace network diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index 71a5e1907..ba71860eb 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace boost { namespace network { diff --git a/boost/network/protocol/http/message/wrappers/version.hpp b/boost/network/protocol/http/message/wrappers/version.hpp index 6b8f0b7d3..28e35988b 100644 --- a/boost/network/protocol/http/message/wrappers/version.hpp +++ b/boost/network/protocol/http/message/wrappers/version.hpp @@ -7,6 +7,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + namespace boost { namespace network { namespace http { namespace impl { diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index a3651c18c..3793fba43 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -28,6 +28,10 @@ struct simple_async_connection_manager : connection_manager { bool follow_redirects, optional openssl_certificate, optional openssl_verify_path); + simple_async_connection_manager(bool cache_resolved, + bool follow_redirects, + std::string const & openssl_certificate, + std::string const & openssl_verify_path); virtual shared_ptr get_connection( asio::io_service & service, request_base const & request); // override @@ -46,6 +50,10 @@ struct http_1_1_async_connection_manager : connection_manager, enable_shared_fro bool follow_redirects, optional openssl_certificate, optional openssl_verify_path); + http_1_1_async_connection_manager(bool cache_resolved, + bool follow_redirects, + std::string const & openssl_certificate, + std::string const & openssl_verify_path); virtual shared_ptr get_connection( asio::io_service & service, request_base const & request); // override diff --git a/libs/network/test/http/client_constructor_test.cpp b/libs/network/test/http/client_constructor_test.cpp index 9fa0b15b2..0f764271a 100644 --- a/libs/network/test/http/client_constructor_test.cpp +++ b/libs/network/test/http/client_constructor_test.cpp @@ -7,29 +7,28 @@ #define BOOST_TEST_MODULE HTTP 1.0 Client Constructor Test #include #include -#include "client_types.hpp" namespace http = boost::network::http; -BOOST_AUTO_TEST_CASE_TEMPLATE(http_client_constructor_test, client, client_types) { - client instance; +BOOST_AUTO_TEST_CASE(http_client_constructor_test) { + http::client instance; boost::asio::io_service io_service; - client instance2(io_service); - client instance3(http::_io_service=io_service); + http::client instance2(io_service); + http::client instance3(http::_io_service=io_service); } -BOOST_AUTO_TEST_CASE_TEMPLATE(http_cient_constructor_params_test, client, client_types) { - client instance( +BOOST_AUTO_TEST_CASE(http_cient_constructor_params_test) { + http::client instance( http::_follow_redirects=true, http::_cache_resolved=true ); boost::asio::io_service io_service; - client instance2( + http::client instance2( http::_follow_redirects=true, http::_io_service=io_service, http::_cache_resolved=true ); - client instance3( + http::client instance3( http::_openssl_certificate="foo", http::_openssl_verify_path="bar" ); diff --git a/libs/network/test/http/client_types.hpp b/libs/network/test/http/client_types.hpp deleted file mode 100644 index 3bed03afe..000000000 --- a/libs/network/test/http/client_types.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef CLIENT_TYPES_ROOWQCLE -#define CLIENT_TYPES_ROOWQCLE - -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include "tag_types.hpp" -#include -#include -#include -#include -#include -#include - -namespace mpl = boost::mpl ; - -template -struct client_adapter { - template - struct apply { - typedef boost::network::http::basic_client type; - }; -}; - -typedef - mpl::transform< - tag_types, - client_adapter<1,0> - >::type - client_1_0; - -typedef - mpl::transform< - tag_types, - client_adapter<1,1> - >::type - client_1_1; - -typedef mpl::joint_view< - client_1_0 - , client_1_1 ->::type client_types; - -typedef - mpl::joint_view< - mpl::transform< - mpl::remove_if< - tag_types, - boost::network::is_sync< - boost::mpl::_ - > - >::type, - client_adapter<1,0> - >::type, - mpl::transform< - mpl::remove_if< - tag_types, - boost::network::is_sync< - boost::mpl::_ - > - >::type, - client_adapter<1,1> - >::type - >::type async_only_client_types; - -#endif /* CLIENT_TYPES_ROOWQCLE */ diff --git a/libs/network/test/http/tag_types.hpp b/libs/network/test/http/tag_types.hpp deleted file mode 100644 index 219ae9303..000000000 --- a/libs/network/test/http/tag_types.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TAG_TYPES_4NNM8B5T -#define TAG_TYPES_4NNM8B5T - -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -namespace http = boost::network::http; - -typedef boost::mpl::vector< - http::tags::http_default_8bit_tcp_resolve - , http::tags::http_default_8bit_udp_resolve - , http::tags::http_keepalive_8bit_tcp_resolve - , http::tags::http_keepalive_8bit_udp_resolve - , http::tags::http_async_8bit_udp_resolve - , http::tags::http_async_8bit_tcp_resolve -> tag_types; - - -#endif /* TAG_TYPES_4NNM8B5T */ From 31a8807b70b85be14287c758de089578f4f1311c Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Wed, 2 Nov 2011 23:33:10 +1100 Subject: [PATCH 042/438] Adding missing default destructor implementations for request/response bases. --- .../protocol/http/request/request_base.hpp | 4 ++++ .../protocol/http/request/request_base.ipp | 24 +++++++++++++++++++ .../protocol/http/response/response_base.hpp | 8 +++++-- .../protocol/http/response/response_base.ipp | 23 ++++++++++++++++++ libs/network/src/http/request.cpp | 11 +++++++++ libs/network/src/http/response.cpp | 11 +++++++++ libs/network/test/http/CMakeLists.txt | 14 +++++++++-- libs/network/test/uri/CMakeLists.txt | 5 +++- 8 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 boost/network/protocol/http/request/request_base.ipp create mode 100644 boost/network/protocol/http/response/response_base.ipp diff --git a/boost/network/protocol/http/request/request_base.hpp b/boost/network/protocol/http/request/request_base.hpp index d8369cdff..add874829 100644 --- a/boost/network/protocol/http/request/request_base.hpp +++ b/boost/network/protocol/http/request/request_base.hpp @@ -64,4 +64,8 @@ struct request_base : message_base, request_storage_base { } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_BASE_HPP_20111008 */ diff --git a/boost/network/protocol/http/request/request_base.ipp b/boost/network/protocol/http/request/request_base.ipp new file mode 100644 index 000000000..5209ffacf --- /dev/null +++ b/boost/network/protocol/http/request/request_base.ipp @@ -0,0 +1,24 @@ +#ifndef BOOST_NETWORK_RPTOCOL_HTTP_REQUEST_BASE_IPP_20111102 +#define BOOST_NETWORK_RPTOCOL_HTTP_REQUEST_BASE_IPP_20111102 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +request_base::~request_base() { + // default implementation, only required for linking. +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_RPTOCOL_HTTP_REQUEST_BASE_IPP_20111102 */ diff --git a/boost/network/protocol/http/response/response_base.hpp b/boost/network/protocol/http/response/response_base.hpp index 284ca7a3f..e6c4597a9 100644 --- a/boost/network/protocol/http/response/response_base.hpp +++ b/boost/network/protocol/http/response/response_base.hpp @@ -7,6 +7,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + namespace boost { namespace network { namespace http { struct response_base : message_base { @@ -16,12 +18,14 @@ struct response_base : message_base { virtual ~response_base() = 0; }; -response_base::~response_base() {} - } /* http */ } /* network */ } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_BASE_HPP_20110930 */ diff --git a/boost/network/protocol/http/response/response_base.ipp b/boost/network/protocol/http/response/response_base.ipp new file mode 100644 index 000000000..6ff547217 --- /dev/null +++ b/boost/network/protocol/http/response/response_base.ipp @@ -0,0 +1,23 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_BASE_IPP_20111102 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_BASE_IPP_20111102 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +response_base::~response_base() { + // default implementation, required only for linking. +} + +} /* http */ +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_BASE_IPP_20111102 */ diff --git a/libs/network/src/http/request.cpp b/libs/network/src/http/request.cpp index e69de29bb..983880dc4 100644 --- a/libs/network/src/http/request.cpp +++ b/libs/network/src/http/request.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/response.cpp b/libs/network/src/http/response.cpp index e69de29bb..0989e5f70 100644 --- a/libs/network/src/http/response.cpp +++ b/libs/network/src/http/response.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/test/http/CMakeLists.txt b/libs/network/test/http/CMakeLists.txt index dcc3749cb..5b04d0026 100644 --- a/libs/network/test/http/CMakeLists.txt +++ b/libs/network/test/http/CMakeLists.txt @@ -31,8 +31,18 @@ if (Boost_FOUND) PROPERTIES COMPILE_FLAGS "-Wall") endif() add_executable(cpp-netlib-http-${test} ${test}.cpp) - add_dependencies(cpp-netlib-http-${test} cppnetlib-uri) - target_link_libraries(cpp-netlib-http-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri cppnetlib-client-connections) + add_dependencies(cpp-netlib-http-${test} + cppnetlib-uri + cppnetlib-message + cppnetlib-http-message + cppnetlib-client-connections) + target_link_libraries(cpp-netlib-http-${test} + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + cppnetlib-uri + cppnetlib-message + cppnetlib-http-message + cppnetlib-client-connections) if (OPENSSL_FOUND) target_link_libraries(cpp-netlib-http-${test} ${OPENSSL_LIBRARIES}) endif() diff --git a/libs/network/test/uri/CMakeLists.txt b/libs/network/test/uri/CMakeLists.txt index ab2f012a8..84ccb9a6f 100644 --- a/libs/network/test/uri/CMakeLists.txt +++ b/libs/network/test/uri/CMakeLists.txt @@ -22,7 +22,10 @@ if (Boost_FOUND) PROPERTIES COMPILE_FLAGS "-Wall") add_executable(cpp-netlib-${test} ${test}.cpp) add_dependencies(cpp-netlib-${test} cppnetlib-uri) - target_link_libraries(cpp-netlib-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri) + target_link_libraries(cpp-netlib-${test} + ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + cppnetlib-uri) if (OPENSSL_FOUND) target_link_libraries(cpp-netlib-${test} ${OPENSSL_LIBRARIES}) endif() From 80a073ad99d43838119c96adfcefafc5b4dfba3e Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Thu, 3 Nov 2011 22:46:58 +1100 Subject: [PATCH 043/438] Initial implementation of default destructors for client connections. --- .../http/client/client_connection.hpp | 40 +++++++++++++++++++ .../http/client/client_connection.ipp | 25 ++++++++++++ .../http/client/connection_manager.hpp | 27 +++++-------- .../http/client/connection_manager.ipp | 22 ++++++++++ libs/network/src/CMakeLists.txt | 3 ++ libs/network/src/http/client_connections.cpp | 12 ++++++ 6 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 boost/network/protocol/http/client/client_connection.hpp create mode 100644 boost/network/protocol/http/client/client_connection.ipp create mode 100644 boost/network/protocol/http/client/connection_manager.ipp create mode 100644 libs/network/src/http/client_connections.cpp diff --git a/boost/network/protocol/http/client/client_connection.hpp b/boost/network/protocol/http/client/client_connection.hpp new file mode 100644 index 000000000..10556d14d --- /dev/null +++ b/boost/network/protocol/http/client/client_connection.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_HPP_20111103 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_HPP_20111103 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct client_connection { + typedef function const &, + system::error_code const &)> + callback_type; + virtual response send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback) = 0; + virtual void reset() = 0; + virtual ~client_connection() = 0; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_HPP_20111103 */ diff --git a/boost/network/protocol/http/client/client_connection.ipp b/boost/network/protocol/http/client/client_connection.ipp new file mode 100644 index 000000000..989ad213b --- /dev/null +++ b/boost/network/protocol/http/client/client_connection.ipp @@ -0,0 +1,25 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_IPP_20111103 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_IPP_20111103 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +client_connection::~client_connection() { + // default implementation, for linkage only. +} + + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CLIENT_CONNECTION_IPP_20111103 */ diff --git a/boost/network/protocol/http/client/connection_manager.hpp b/boost/network/protocol/http/client/connection_manager.hpp index ee5dd7eb2..e28ce5dee 100644 --- a/boost/network/protocol/http/client/connection_manager.hpp +++ b/boost/network/protocol/http/client/connection_manager.hpp @@ -7,23 +7,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -namespace boost { namespace network { namespace http { - -struct request_base; - -struct response; +#include +#include +#include +#include -struct client_connection { - typedef function const &, - system::error_code const &)> - callback_type; - virtual response send_request(std::string const & method, - request_base const & request, - bool get_body, - callback_type callback) = 0; - virtual void reset() = 0; - virtual ~client_connection() = 0; -}; +namespace boost { namespace network { namespace http { struct connection_manager { virtual shared_ptr get_connection( @@ -34,7 +23,13 @@ struct connection_manager { }; } /* http */ + } /* network */ + } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_HPP_20110930 */ diff --git a/boost/network/protocol/http/client/connection_manager.ipp b/boost/network/protocol/http/client/connection_manager.ipp new file mode 100644 index 000000000..fc1b45978 --- /dev/null +++ b/boost/network/protocol/http/client/connection_manager.ipp @@ -0,0 +1,22 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_IPP_20111103 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_IPP_20111103 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +connection_manager::~connection_manager() { + // default implementation, for linkage only. +} + +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_MANAGER_IPP_20111103 */ diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 75b77264e..c3101a62d 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -28,5 +28,8 @@ add_library(cppnetlib-message-wrappers ${CPP-NETLIB_MESSAGE_WRAPPERS_SRCS}) set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) +set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/client_connections.cpp) +add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) + set(CPP-NETLIB_UTILS_THREAD_POOL_SRCS utils/thread_pool.cpp) add_library(cppnetlib-utils-thread_pool ${CPP-NETLIB_UTILS_THREAD_POOL_SRCS}) diff --git a/libs/network/src/http/client_connections.cpp b/libs/network/src/http/client_connections.cpp new file mode 100644 index 000000000..06cb0df22 --- /dev/null +++ b/libs/network/src/http/client_connections.cpp @@ -0,0 +1,12 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include +#include From 24e49cbcd0758d21463b49d1dc5b977e1fcca96d Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Wed, 23 Nov 2011 23:53:31 +1100 Subject: [PATCH 044/438] Major Surgery, aligning APIs. So this set of changes moves forward the APIs of the internals of the client implementation. This is going to be more in flux until the request and response implementations get filled out. For the moment the "simplification" continues. WARNING: There's a lot of legacy code here still, most of which will not be kept. After this refactoring process is completed, the layout of the library will also change to better reflect the structure. --- boost/network/message/message.hpp | 15 +- boost/network/message/message.ipp | 28 +- boost/network/message/message_base.hpp | 14 +- .../network/message/wrappers/destination.hpp | 6 +- .../network/message/wrappers/destination.ipp | 2 +- .../protocol/http/algorithms/linearize.hpp | 2 +- boost/network/protocol/http/client.hpp | 1 + .../http/client/connection/async_normal.hpp | 443 ++---------------- .../http/client/connection/async_normal.ipp | 395 ++++++++++++++++ .../client/connection/connection_delegate.hpp | 5 +- .../connection_delegate_factory.hpp | 46 +- .../connection_delegate_factory.ipp | 48 ++ .../client/connection/connection_factory.hpp | 36 ++ .../client/connection/normal_delegate.hpp | 4 +- .../client/connection/normal_delegate.ipp | 10 +- .../connection/resolver_delegate_factory.hpp | 19 +- .../connection/simple_connection_factory.hpp | 48 ++ .../connection/simple_connection_factory.ipp | 82 ++++ .../http/client/connection/ssl_delegate.hpp | 4 +- .../http/client/connection/ssl_delegate.ipp | 16 +- boost/network/protocol/http/client/facade.hpp | 37 +- .../protocol/http/client/parameters.hpp | 1 + .../http/client/simple_connection_manager.hpp | 119 +++++ .../http/client/simple_connection_manager.ipp | 99 ++++ .../network/protocol/http/request/request.hpp | 26 +- .../protocol/http/request/request_base.hpp | 12 +- .../protocol/http/response/response.hpp | 14 +- libs/network/src/CMakeLists.txt | 6 +- .../src/http/connection_delegate_factory.cpp | 11 + .../src/http/simple_connection_factory.cpp | 11 + .../src/http/simple_connection_manager.cpp | 11 + 31 files changed, 1025 insertions(+), 546 deletions(-) create mode 100644 boost/network/protocol/http/client/connection/async_normal.ipp create mode 100644 boost/network/protocol/http/client/connection/connection_delegate_factory.ipp create mode 100644 boost/network/protocol/http/client/connection/connection_factory.hpp create mode 100644 boost/network/protocol/http/client/connection/simple_connection_factory.hpp create mode 100644 boost/network/protocol/http/client/connection/simple_connection_factory.ipp create mode 100644 boost/network/protocol/http/client/simple_connection_manager.hpp create mode 100644 boost/network/protocol/http/client/simple_connection_manager.ipp create mode 100644 libs/network/src/http/connection_delegate_factory.cpp create mode 100644 libs/network/src/http/simple_connection_factory.cpp create mode 100644 libs/network/src/http/simple_connection_manager.cpp diff --git a/boost/network/message/message.hpp b/boost/network/message/message.hpp index 5684b721a..2d570a506 100644 --- a/boost/network/message/message.hpp +++ b/boost/network/message/message.hpp @@ -43,20 +43,21 @@ struct message : message_base { virtual void append_body(std::string const & data); // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); + virtual void get_destination(std::string & destination) const; + virtual void get_source(std::string & source) const; virtual void get_headers( - function inserter); + function inserter) const; virtual void get_headers( std::string const & name, - function inserter); + function inserter) const; virtual void get_headers( function predicate, - function inserter); - virtual void get_body(std::string & body); + function inserter) const; + virtual void get_body(std::string & body) const; virtual void get_body( function)> chunk_reader, - size_t size); + size_t size) const; + void swap(message & other); // Destructor diff --git a/boost/network/message/message.ipp b/boost/network/message/message.ipp index 88f17ba9e..fa0e14601 100644 --- a/boost/network/message/message.ipp +++ b/boost/network/message/message.ipp @@ -53,22 +53,22 @@ struct message_pimpl { } // Retrievers - void get_destination(std::string & destination) { + void get_destination(std::string & destination) const { destination = destination_; } - void get_source(std::string & source) { + void get_source(std::string & source) const { source = source_; } - void get_headers(function inserter) { + void get_headers(function inserter) const { std::multimap::const_iterator it = headers_.begin(), end = headers_.end(); for (; it != end; ++it) inserter(it->first, it->second); } void get_headers(std::string const & name, - function inserter) { + function inserter) const { std::multimap::const_iterator it = headers_.find(name), end= headers_.end(); while (it != end) { @@ -78,7 +78,7 @@ struct message_pimpl { } void get_headers(function predicate, - function inserter) { + function inserter) const { std::multimap::const_iterator it = headers_.begin(), end = headers_.end(); while (it != end) { @@ -92,7 +92,7 @@ struct message_pimpl { body = body_; } - void get_body(function)> chunk_reader, size_t size) { + void get_body(function)> chunk_reader, size_t size) const { static char const * nullptr_ = 0; if (body_read_pos == body_.size()) chunk_reader(boost::make_iterator_range(nullptr_, nullptr_)); @@ -122,7 +122,7 @@ struct message_pimpl { std::multimap headers_; // TODO: use Boost.IOStreams here later on. std::string body_; - size_t body_read_pos; + mutable size_t body_read_pos; }; message::message() @@ -171,33 +171,33 @@ void message::append_body(std::string const & data) { pimpl->append_body(data); } -void message::get_destination(std::string & destination) { +void message::get_destination(std::string & destination) const { pimpl->get_destination(destination); } -void message::get_source(std::string & source) { +void message::get_source(std::string & source) const { pimpl->get_source(source); } -void message::get_headers(function inserter) { +void message::get_headers(function inserter) const { pimpl->get_headers(inserter); } void message::get_headers(std::string const & name, - function inserter) { + function inserter) const { pimpl->get_headers(name, inserter); } void message::get_headers(function predicate, - function inserter) { + function inserter) const { pimpl->get_headers(predicate, inserter); } -void message::get_body(std::string & body) { +void message::get_body(std::string & body) const { pimpl->get_body(body); } -void message::get_body(function)> chunk_reader, size_t size) { +void message::get_body(function)> chunk_reader, size_t size) const { pimpl->get_body(chunk_reader, size); } diff --git a/boost/network/message/message_base.hpp b/boost/network/message/message_base.hpp index 43b2307bc..5f3681e5a 100644 --- a/boost/network/message/message_base.hpp +++ b/boost/network/message/message_base.hpp @@ -24,13 +24,13 @@ struct message_base { virtual void append_body(std::string const & data) = 0; // Retrievers - virtual void get_destination(std::string & destination) = 0; - virtual void get_source(std::string & source) = 0; - virtual void get_headers(function inserter) = 0; - virtual void get_headers(std::string const & name, function inserter) = 0; - virtual void get_headers(function predicate, function inserter) = 0; - virtual void get_body(std::string & body) = 0; - virtual void get_body(function)> chunk_reader, size_t size) = 0; + virtual void get_destination(std::string & destination) const = 0; + virtual void get_source(std::string & source) const = 0; + virtual void get_headers(function inserter) const = 0; + virtual void get_headers(std::string const & name, function inserter) const = 0; + virtual void get_headers(function predicate, function inserter) const = 0; + virtual void get_body(std::string & body) const = 0; + virtual void get_body(function)> chunk_reader, size_t size) const = 0; // Destructor virtual ~message_base() = 0; // pure virtual diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index a6d9e355c..1f3f44330 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -14,17 +14,17 @@ namespace boost { namespace network { namespace impl { struct destination_wrapper { - explicit destination_wrapper(message_base & message); + explicit destination_wrapper(message_base const & message); operator std::string () const; private: - message_base & message_; + message_base const & message_; mutable optional cache_; }; } // namespace impl inline std::string const -destination(message_base & message_) { +destination(message_base const & message_) { return impl::destination_wrapper(message_); } diff --git a/boost/network/message/wrappers/destination.ipp b/boost/network/message/wrappers/destination.ipp index cb99e62f5..99c1d73ff 100644 --- a/boost/network/message/wrappers/destination.ipp +++ b/boost/network/message/wrappers/destination.ipp @@ -11,7 +11,7 @@ namespace boost { namespace network { namespace impl { -destination_wrapper::destination_wrapper(message_base & message): +destination_wrapper::destination_wrapper(message_base const & message): message_(message) {} destination_wrapper::operator std::string () const { diff --git a/boost/network/protocol/http/algorithms/linearize.hpp b/boost/network/protocol/http/algorithms/linearize.hpp index 0fd24f740..f109640b2 100644 --- a/boost/network/protocol/http/algorithms/linearize.hpp +++ b/boost/network/protocol/http/algorithms/linearize.hpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/boost/network/protocol/http/client.hpp b/boost/network/protocol/http/client.hpp index bd8203a5c..41ae22bc7 100644 --- a/boost/network/protocol/http/client.hpp +++ b/boost/network/protocol/http/client.hpp @@ -58,6 +58,7 @@ struct client : basic_client_facade { (openssl_certificate, (std::string)) (openssl_verify_path, (std::string)) (connection_manager, (shared_ptr)) + (connection_factory, (shared_ptr)) )) // diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index fa23fd75b..51abe10a1 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -1,426 +1,41 @@ #ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_CONNECTION_HPP_20100601 #define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_CONNECTION_HPP_20100601 -// Copyright 2010 (C) Dean Michael Berris -// Copyright 2010 (C) Sinefunc, Inc. // Copyright 2011 Dean Michael Berris (dberris@google.com). // Copyright 2011 Google,Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace network { namespace http { namespace impl { - - template - struct async_connection_base; - - namespace placeholders = boost::asio::placeholders; - - struct http_async_connection - : async_connection_base, - protected http_async_protocol_handler, - boost::enable_shared_from_this > - { - typedef async_connection_base base; - typedef http_async_protocol_handler protocol_base; - typedef typename base::resolver_type resolver_type; - typedef typename base::resolver_base::resolver_iterator resolver_iterator; - typedef typename base::resolver_base::resolver_iterator_pair resolver_iterator_pair; - typedef typename base::response response; - typedef typename base::string_type string_type; - typedef typename base::request request; - typedef typename base::resolver_base::resolve_function resolve_function; - typedef typename base::body_callback_function_type body_callback_function_type; - typedef http_async_connection this_type; - typedef typename delegate_factory::type delegate_factory_type; - typedef typename delegate_factory_type::connection_delegate_ptr - connection_delegate_ptr; - - http_async_connection(resolver_delegate_ptr resolver_delegate, - asio::io_service & io_service, - bool follow_redirect, - connection_delegate_ptr delegate) - : - follow_redirect_(follow_redirect), - request_strand_(io_service), - resolver_delegate_(resolver_delegate), - delegate_(delegate) {} - - // This is the main entry point for the connection/request pipeline. We're - // overriding async_connection_base<...>::start(...) here which is called - // by the client. - virtual response start(request const & request, - string_type const & method, - bool get_body, - body_callback_function_type callback) { - response response_; - this->init_response(response_, get_body); - linearize(request, method, version_major, version_minor, - std::ostreambuf_iterator::type>(&command_streambuf)); - this->method = method; - boost::uint16_t port_ = port(request); - resolver_delegate_->resolve(host(request), - port_, - request_strand_.wrap( - boost::bind( - &this_type::handle_resolved, - this_type::shared_from_this(), - port_, - get_body, - callback, - _1, - _2))); - return response_; - } - - private: - - http_async_connection(http_async_connection const &); // = delete - - void set_errors(boost::system::error_code const & ec) { - boost::system::system_error error(ec); - this->version_promise.set_exception(boost::copy_exception(error)); - this->status_promise.set_exception(boost::copy_exception(error)); - this->status_message_promise.set_exception(boost::copy_exception(error)); - this->headers_promise.set_exception(boost::copy_exception(error)); - this->source_promise.set_exception(boost::copy_exception(error)); - this->destination_promise.set_exception(boost::copy_exception(error)); - this->body_promise.set_exception(boost::copy_exception(error)); - } - - void handle_resolved(boost::uint16_t port, - bool get_body, - body_callback_function_type callback, - boost::system::error_code const & ec, - resolver_iterator_pair endpoint_range) { - if (!ec && !boost::empty(endpoint_range)) { - // Here we deal with the case that there was an error encountered and - // that there's still more endpoints to try connecting to. - resolver_iterator iter = boost::begin(endpoint_range); - asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); - delegate_->connect(endpoint, - request_strand_.wrap( - boost::bind( - &this_type::handle_connected, - this_type::shared_from_this(), - port, - get_body, - callback, - std::make_pair(++iter, - resolver_iterator()), - placeholders::error))); - } else { - set_errors(ec ? ec : boost::asio::error::host_not_found); - } - } - - void handle_connected(boost::uint16_t port, - bool get_body, - body_callback_function_type callback, - resolver_iterator_pair endpoint_range, - boost::system::error_code const & ec) { - if (!ec) { - BOOST_ASSERT(delegate_.get() != 0); - delegate_->write(command_streambuf, - request_strand_.wrap( - boost::bind( - &this_type::handle_sent_request, - this_type::shared_from_this(), - get_body, - callback, - placeholders::error, - placeholders::bytes_transferred))); - } else { - if (!boost::empty(endpoint_range)) { - resolver_iterator iter = boost::begin(endpoint_range); - asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); - delegate_->connect(endpoint, - request_strand_.wrap( - boost::bind( - &this_type::handle_connected, - this_type::shared_from_this(), - port, - get_body, - callback, - std::make_pair(++iter, - resolver_iterator()), - placeholders::error))); - } else { - set_errors(ec ? ec : boost::asio::error::host_not_found); - } - } - } - - enum state_t { - version, status, status_message, headers, body - }; - - void handle_sent_request(bool get_body, - body_callback_function_type callback, - boost::system::error_code const & ec, - std::size_t bytes_transferred) { - if (!ec) { - delegate_->read_some( - boost::asio::mutable_buffers_1(this->part.c_array(), - this->part.size()), - request_strand_.wrap( - boost::bind(&this_type::handle_received_data, - this_type::shared_from_this(), - version, get_body, callback, - placeholders::error, - placeholders::bytes_transferred))); - } else { - set_errors(ec); - } - } - - void handle_received_data(state_t state, bool get_body, body_callback_function_type callback, boost::system::error_code const & ec, std::size_t bytes_transferred) { - if (!ec || ec == boost::asio::error::eof) { - logic::tribool parsed_ok; - size_t remainder; - switch(state) { - case version: - parsed_ok = - this->parse_version(delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - version, get_body, callback, - placeholders::error, - placeholders::bytes_transferred)), - bytes_transferred); - if (!parsed_ok || indeterminate(parsed_ok)) return; - case status: - parsed_ok = - this->parse_status(delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - status, get_body, callback, - placeholders::error, - placeholders::bytes_transferred)), - bytes_transferred); - if (!parsed_ok || indeterminate(parsed_ok)) return; - case status_message: - parsed_ok = - this->parse_status_message(delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - status_message, get_body, callback, - placeholders::error, placeholders::bytes_transferred - ) - ), - bytes_transferred - ); - if (!parsed_ok || indeterminate(parsed_ok)) return; - case headers: - // In the following, remainder is the number of bytes that remain - // in the buffer. We need this in the body processing to make sure - // that the data remaining in the buffer is dealt with before - // another call to get more data for the body is scheduled. - fusion::tie(parsed_ok, remainder) = - this->parse_headers(delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - headers, get_body, callback, - placeholders::error, placeholders::bytes_transferred - ) - ), - bytes_transferred - ); - - if (!parsed_ok || indeterminate(parsed_ok)) return; - - if (!get_body) { - // We short-circuit here because the user does not - // want to get the body (in the case of a HEAD - // request). - this->body_promise.set_value(""); - this->destination_promise.set_value(""); - this->source_promise.set_value(""); - this->part.assign('\0'); - this->response_parser_.reset(); - return; - } - - if (callback) { - // Here we deal with the spill-over data from the - // headers processing. This means the headers data - // has already been parsed appropriately and we're - // looking to treat everything that remains in the - // buffer. - typename protocol_base::buffer_type::const_iterator begin = this->part_begin; - typename protocol_base::buffer_type::const_iterator end = begin; - std::advance(end, remainder); - - // We're setting the body promise here to an empty string because - // this can be used as a signaling mechanism for the user to - // determine that the body is now ready for processing, even - // though the callback is already provided. - this->body_promise.set_value(""); - - // The invocation of the callback is synchronous to allow us to - // wait before scheduling another read. - callback(make_iterator_range(begin, end), ec); - - delegate_->read_some( - boost::asio::mutable_buffers_1(this->part.c_array(), - this->part.size()), - request_strand_.wrap( - boost::bind(&this_type::handle_received_data, - this_type::shared_from_this(), - body, - get_body, - callback, - placeholders::error, - placeholders::bytes_transferred))); - } else { - // Here we handle the body data ourself and append to an - // ever-growing string buffer. - this->parse_body( - delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - body, get_body, callback, - placeholders::error, placeholders::bytes_transferred - ) - ), - remainder); - } - return; - case body: - if (ec == boost::asio::error::eof) { - // Here we're handling the case when the connection has been - // closed from the server side, or at least that the end of file - // has been reached while reading the socket. This signals the end - // of the body processing chain. - if (callback) { - typename protocol_base::buffer_type::const_iterator begin = - this->part.begin(), - end = begin; - std::advance(end, bytes_transferred); - - // We call the callback function synchronously passing the error - // condition (in this case, end of file) so that it can handle - // it appropriately. - callback(make_iterator_range(begin, end), ec); - } else { - string_type body_string; - std::swap(body_string, this->partial_parsed); - body_string.append( - this->part.begin() - , bytes_transferred - ); - this->body_promise.set_value(body_string); - } - // TODO set the destination value somewhere! - this->destination_promise.set_value(""); - this->source_promise.set_value(""); - this->part.assign('\0'); - this->response_parser_.reset(); - } else { - // This means the connection has not been closed yet and we want to get more - // data. - if (callback) { - // Here we have a body_handler callback. Let's invoke the - // callback from here and make sure we're getting more data - // right after. - typename protocol_base::buffer_type::const_iterator begin = this->part.begin(); - typename protocol_base::buffer_type::const_iterator end = begin; - std::advance(end, bytes_transferred); - callback(make_iterator_range(begin, end), ec); - delegate_->read_some( - boost::asio::mutable_buffers_1( - this->part.c_array(), - this->part.size()), - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - body, - get_body, - callback, - placeholders::error, - placeholders::bytes_transferred))); - } else { - // Here we don't have a body callback. Let's - // make sure that we deal with the remainder - // from the headers part in case we do have data - // that's still in the buffer. - this->parse_body(delegate_, - request_strand_.wrap( - boost::bind( - &this_type::handle_received_data, - this_type::shared_from_this(), - body, - get_body, - callback, - placeholders::error, - placeholders::bytes_transferred)), - bytes_transferred); - } - } - return; - default: - BOOST_ASSERT(false && "Bug, report this to the developers!"); - } - } else { - boost::system::system_error error(ec); - this->source_promise.set_exception(boost::copy_exception(error)); - this->destination_promise.set_exception(boost::copy_exception(error)); - switch (state) { - case version: - this->version_promise.set_exception(boost::copy_exception(error)); - case status: - this->status_promise.set_exception(boost::copy_exception(error)); - case status_message: - this->status_message_promise.set_exception(boost::copy_exception(error)); - case headers: - this->headers_promise.set_exception(boost::copy_exception(error)); - case body: - this->body_promise.set_exception(boost::copy_exception(error)); - break; - default: - BOOST_ASSERT(false && "Bug, report this to the developers!"); - } - } - } - - bool follow_redirect_; - boost::asio::io_service::strand request_strand_; - resolver_delegate_ptr resolver_delegate_; - connection_delegate_ptr delegate_; - boost::asio::streambuf command_streambuf; - string_type method; - }; - -} // namespace impl +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct http_async_connection_pimpl; + +struct http_async_connection +: client_connection +, enable_shared_from_this { + using client_connection::callback_type; + http_async_connection(shared_ptr resolver_delegate, + shared_ptr connection_delegate, + asio::io_service & io_service, + bool follow_redirects); + virtual response send_request(std::string const & method, + request_base const & request, + bool get_body, + callback_type callback); // override + virtual void reset(); // override + virtual ~http_async_connection(); + private: + scoped_ptr pimpl; +}; } // namespace http diff --git a/boost/network/protocol/http/client/connection/async_normal.ipp b/boost/network/protocol/http/client/connection/async_normal.ipp new file mode 100644 index 000000000..405e644c4 --- /dev/null +++ b/boost/network/protocol/http/client/connection/async_normal.ipp @@ -0,0 +1,395 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_NORMAL_IPP_20111123 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_NORMAL_IPP_20111123 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +namespace placeholders = boost::asio::placeholders; + +struct http_async_connection +: client_connection +, boost::enable_shared_from_this +{ + + http_async_connection(resolver_delegate_ptr resolver_delegate, + asio::io_service & io_service, + bool follow_redirect, + connection_delegate_ptr delegate) + : + follow_redirect_(follow_redirect), + request_strand_(io_service), + resolver_delegate_(resolver_delegate), + delegate_(delegate) {} + + // This is the main entry point for the connection/request pipeline. We're + // overriding async_connection_base<...>::start(...) here which is called + // by the client. + virtual response start(request const & request, + string_type const & method, + bool get_body, + body_callback_function_type callback) { + response response_; + this->init_response(response_, get_body); + linearize(request, method, version_major, version_minor, + std::ostreambuf_iterator::type>(&command_streambuf)); + this->method = method; + boost::uint16_t port_ = port(request); + resolver_delegate_->resolve(host(request), + port_, + request_strand_.wrap( + boost::bind( + &this_type::handle_resolved, + this_type::shared_from_this(), + port_, + get_body, + callback, + _1, + _2))); + return response_; + } + +private: + + http_async_connection(http_async_connection const &); // = delete + + void set_errors(boost::system::error_code const & ec) { + boost::system::system_error error(ec); + this->version_promise.set_exception(boost::copy_exception(error)); + this->status_promise.set_exception(boost::copy_exception(error)); + this->status_message_promise.set_exception(boost::copy_exception(error)); + this->headers_promise.set_exception(boost::copy_exception(error)); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + this->body_promise.set_exception(boost::copy_exception(error)); + } + + void handle_resolved(boost::uint16_t port, + bool get_body, + body_callback_function_type callback, + boost::system::error_code const & ec, + resolver_iterator_pair endpoint_range) { + if (!ec && !boost::empty(endpoint_range)) { + // Here we deal with the case that there was an error encountered and + // that there's still more endpoints to try connecting to. + resolver_iterator iter = boost::begin(endpoint_range); + asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + delegate_->connect(endpoint, + request_strand_.wrap( + boost::bind( + &this_type::handle_connected, + this_type::shared_from_this(), + port, + get_body, + callback, + std::make_pair(++iter, + resolver_iterator()), + placeholders::error))); + } else { + set_errors(ec ? ec : boost::asio::error::host_not_found); + } + } + + void handle_connected(boost::uint16_t port, + bool get_body, + body_callback_function_type callback, + resolver_iterator_pair endpoint_range, + boost::system::error_code const & ec) { + if (!ec) { + BOOST_ASSERT(delegate_.get() != 0); + delegate_->write(command_streambuf, + request_strand_.wrap( + boost::bind( + &this_type::handle_sent_request, + this_type::shared_from_this(), + get_body, + callback, + placeholders::error, + placeholders::bytes_transferred))); + } else { + if (!boost::empty(endpoint_range)) { + resolver_iterator iter = boost::begin(endpoint_range); + asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + delegate_->connect(endpoint, + request_strand_.wrap( + boost::bind( + &this_type::handle_connected, + this_type::shared_from_this(), + port, + get_body, + callback, + std::make_pair(++iter, + resolver_iterator()), + placeholders::error))); + } else { + set_errors(ec ? ec : boost::asio::error::host_not_found); + } + } + } + + enum state_t { + version, status, status_message, headers, body + }; + + void handle_sent_request(bool get_body, + body_callback_function_type callback, + boost::system::error_code const & ec, + std::size_t bytes_transferred) { + if (!ec) { + delegate_->read_some( + boost::asio::mutable_buffers_1(this->part.c_array(), + this->part.size()), + request_strand_.wrap( + boost::bind(&this_type::handle_received_data, + this_type::shared_from_this(), + version, get_body, callback, + placeholders::error, + placeholders::bytes_transferred))); + } else { + set_errors(ec); + } + } + + void handle_received_data(state_t state, bool get_body, body_callback_function_type callback, boost::system::error_code const & ec, std::size_t bytes_transferred) { + if (!ec || ec == boost::asio::error::eof) { + logic::tribool parsed_ok; + size_t remainder; + switch(state) { + case version: + parsed_ok = + this->parse_version(delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + version, get_body, callback, + placeholders::error, + placeholders::bytes_transferred)), + bytes_transferred); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case status: + parsed_ok = + this->parse_status(delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + status, get_body, callback, + placeholders::error, + placeholders::bytes_transferred)), + bytes_transferred); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case status_message: + parsed_ok = + this->parse_status_message(delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + status_message, get_body, callback, + placeholders::error, placeholders::bytes_transferred + ) + ), + bytes_transferred + ); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case headers: + // In the following, remainder is the number of bytes that remain + // in the buffer. We need this in the body processing to make sure + // that the data remaining in the buffer is dealt with before + // another call to get more data for the body is scheduled. + fusion::tie(parsed_ok, remainder) = + this->parse_headers(delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + headers, get_body, callback, + placeholders::error, placeholders::bytes_transferred + ) + ), + bytes_transferred + ); + + if (!parsed_ok || indeterminate(parsed_ok)) return; + + if (!get_body) { + // We short-circuit here because the user does not + // want to get the body (in the case of a HEAD + // request). + this->body_promise.set_value(""); + this->destination_promise.set_value(""); + this->source_promise.set_value(""); + this->part.assign('\0'); + this->response_parser_.reset(); + return; + } + + if (callback) { + // Here we deal with the spill-over data from the + // headers processing. This means the headers data + // has already been parsed appropriately and we're + // looking to treat everything that remains in the + // buffer. + typename protocol_base::buffer_type::const_iterator begin = this->part_begin; + typename protocol_base::buffer_type::const_iterator end = begin; + std::advance(end, remainder); + + // We're setting the body promise here to an empty string because + // this can be used as a signaling mechanism for the user to + // determine that the body is now ready for processing, even + // though the callback is already provided. + this->body_promise.set_value(""); + + // The invocation of the callback is synchronous to allow us to + // wait before scheduling another read. + callback(make_iterator_range(begin, end), ec); + + delegate_->read_some( + boost::asio::mutable_buffers_1(this->part.c_array(), + this->part.size()), + request_strand_.wrap( + boost::bind(&this_type::handle_received_data, + this_type::shared_from_this(), + body, + get_body, + callback, + placeholders::error, + placeholders::bytes_transferred))); + } else { + // Here we handle the body data ourself and append to an + // ever-growing string buffer. + this->parse_body( + delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + body, get_body, callback, + placeholders::error, placeholders::bytes_transferred + ) + ), + remainder); + } + return; + case body: + if (ec == boost::asio::error::eof) { + // Here we're handling the case when the connection has been + // closed from the server side, or at least that the end of file + // has been reached while reading the socket. This signals the end + // of the body processing chain. + if (callback) { + typename protocol_base::buffer_type::const_iterator begin = + this->part.begin(), + end = begin; + std::advance(end, bytes_transferred); + + // We call the callback function synchronously passing the error + // condition (in this case, end of file) so that it can handle + // it appropriately. + callback(make_iterator_range(begin, end), ec); + } else { + string_type body_string; + std::swap(body_string, this->partial_parsed); + body_string.append( + this->part.begin() + , bytes_transferred + ); + this->body_promise.set_value(body_string); + } + // TODO set the destination value somewhere! + this->destination_promise.set_value(""); + this->source_promise.set_value(""); + this->part.assign('\0'); + this->response_parser_.reset(); + } else { + // This means the connection has not been closed yet and we want to get more + // data. + if (callback) { + // Here we have a body_handler callback. Let's invoke the + // callback from here and make sure we're getting more data + // right after. + typename protocol_base::buffer_type::const_iterator begin = this->part.begin(); + typename protocol_base::buffer_type::const_iterator end = begin; + std::advance(end, bytes_transferred); + callback(make_iterator_range(begin, end), ec); + delegate_->read_some( + boost::asio::mutable_buffers_1( + this->part.c_array(), + this->part.size()), + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + body, + get_body, + callback, + placeholders::error, + placeholders::bytes_transferred))); + } else { + // Here we don't have a body callback. Let's + // make sure that we deal with the remainder + // from the headers part in case we do have data + // that's still in the buffer. + this->parse_body(delegate_, + request_strand_.wrap( + boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), + body, + get_body, + callback, + placeholders::error, + placeholders::bytes_transferred)), + bytes_transferred); + } + } + return; + default: + BOOST_ASSERT(false && "Bug, report this to the developers!"); + } + } else { + boost::system::system_error error(ec); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + switch (state) { + case version: + this->version_promise.set_exception(boost::copy_exception(error)); + case status: + this->status_promise.set_exception(boost::copy_exception(error)); + case status_message: + this->status_message_promise.set_exception(boost::copy_exception(error)); + case headers: + this->headers_promise.set_exception(boost::copy_exception(error)); + case body: + this->body_promise.set_exception(boost::copy_exception(error)); + break; + default: + BOOST_ASSERT(false && "Bug, report this to the developers!"); + } + } + } + + bool follow_redirect_; + boost::asio::io_service::strand request_strand_; + resolver_delegate_ptr resolver_delegate_; + connection_delegate_ptr delegate_; + boost::asio::streambuf command_streambuf; + string_type method; +}; + + +} /* http */ + +} /* network */ + +} /* boost */ + +#endbooif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_NORMAL_IPP_20111123 */ diff --git a/boost/network/protocol/http/client/connection/connection_delegate.hpp b/boost/network/protocol/http/client/connection/connection_delegate.hpp index 7f4bc5b5b..6d1d4e3ce 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate.hpp @@ -9,8 +9,9 @@ #include #include +#include -namespace boost { namespace network { namespace http { namespace impl { +namespace boost { namespace network { namespace http { struct connection_delegate { virtual void connect(asio::ip::tcp::endpoint & endpoint, @@ -22,8 +23,6 @@ struct connection_delegate { virtual ~connection_delegate() {} }; -} /* impl */ - } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp index 05991c6d4..d467615b4 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp @@ -9,53 +9,35 @@ #include #include -#include -#ifdef BOOST_NETWORK_ENABLE_HTTPS -#include -#endif /* BOOST_NETWORK_ENABLE_HTTPS */ -namespace boost { namespace network { namespace http { namespace impl { - -struct ssl_delegate; - -struct normal_delegate; +namespace boost { namespace network { namespace http { struct connection_delegate_factory { typedef shared_ptr connection_delegate_ptr; + connection_delegate_factory(); + // This is the factory method that actually returns the delegate instance. // TODO Support passing in proxy settings when crafting connections. - static connection_delegate_ptr new_connection_delegate( + virtual connection_delegate_ptr create_connection_delegate( asio::io_service & service, bool https, optional certificate_filename, optional verify_path); + + virtual ~connection_delegate_factory(); + + private: + connection_delegate_factory(connection_delegate_factory const &); // = delete + connection_delegate_factory& operator=(connection_delegate_factory); // = delete }; -connection_delegate_factory::connection_delegate_ptr -connection_delegate_factory::new_connection_delegate( - asio::io_service & service, - bool https, - optional certificate_filename, - optional verify_path) { - connection_delegate_ptr delegate; - if (https) { -#ifdef BOOST_NETWORK_ENABLE_HTTPS - delegate.reset(new ssl_delegate(service, - certificate_filename, - verify_path)); -#else - BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported.")); -#endif /* BOOST_NETWORK_ENABLE_HTTPS */ - } else { - delegate.reset(new normal_delegate(service)); - } - return delegate; -} - -} /* impl */ } /* http */ } /* network */ } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_DELEGATE_FACTORY_HPP_20110819 */ diff --git a/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp b/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp new file mode 100644 index 000000000..4ac901457 --- /dev/null +++ b/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp @@ -0,0 +1,48 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_FACTORY_IPP_20111123 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_FACTORY_IPP_20111123 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#ifdef BOOST_NETWORK_ENABLE_HTTPS +#include +#endif /* BOOST_NETWORK_ENABLE_HTTPS */ + +#include + +namespace boost { namespace network { namespace http { + +connection_delegate_factory::connection_delegate_factory() {} + +connection_delegate_factory::connection_delegate_ptr +connection_delegate_factory::create_connection_delegate( + asio::io_service & service, + bool https, + optional certificate_filename, + optional verify_path) { + connection_delegate_ptr delegate; + if (https) { +#ifdef BOOST_NETWORK_ENABLE_HTTPS + delegate.reset(new ssl_delegate(service, + certificate_filename, + verify_path)); +#else + BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported.")); +#endif /* BOOST_NETWORK_ENABLE_HTTPS */ + } else { + delegate.reset(new normal_delegate(service)); + } + return delegate; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_FACTORY_IPP_20111123 */ diff --git a/boost/network/protocol/http/client/connection/connection_factory.hpp b/boost/network/protocol/http/client/connection/connection_factory.hpp new file mode 100644 index 000000000..c2dad0852 --- /dev/null +++ b/boost/network/protocol/http/client/connection/connection_factory.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_HPP_20111112 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_HPP_20111112 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct connection_factory { + virtual shared_ptr create_connection(asio::io_service & service, + request_base const & request, + bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path) = 0; + virtual ~connection_factory() = 0; // pure virtual, interface only. +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_HPP_20111112 */ diff --git a/boost/network/protocol/http/client/connection/normal_delegate.hpp b/boost/network/protocol/http/client/connection/normal_delegate.hpp index d18f1461a..8817aa235 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.hpp +++ b/boost/network/protocol/http/client/connection/normal_delegate.hpp @@ -11,7 +11,7 @@ #include #include -namespace boost { namespace network { namespace http { namespace impl { +namespace boost { namespace network { namespace http { struct normal_delegate : connection_delegate { normal_delegate(asio::io_service & service); @@ -32,8 +32,6 @@ struct normal_delegate : connection_delegate { normal_delegate& operator=(normal_delegate); // = delete }; -} /* impl */ - } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/connection/normal_delegate.ipp b/boost/network/protocol/http/client/connection/normal_delegate.ipp index f084dc163..f05263cdf 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.ipp +++ b/boost/network/protocol/http/client/connection/normal_delegate.ipp @@ -14,29 +14,29 @@ #include #include -boost::network::http::impl::normal_delegate::normal_delegate(asio::io_service & service) +boost::network::http::normal_delegate::normal_delegate(asio::io_service & service) : service_(service) {} -void boost::network::http::impl::normal_delegate::connect( +void boost::network::http::normal_delegate::connect( asio::ip::tcp::endpoint & endpoint, function handler) { socket_.reset(new asio::ip::tcp::socket(service_)); socket_->async_connect(endpoint, handler); } -void boost::network::http::impl::normal_delegate::write( +void boost::network::http::normal_delegate::write( asio::streambuf & command_streambuf, function handler) { asio::async_write(*socket_, command_streambuf, handler); } -void boost::network::http::impl::normal_delegate::read_some( +void boost::network::http::normal_delegate::read_some( asio::mutable_buffers_1 const & read_buffer, function handler) { socket_->async_read_some(read_buffer, handler); } -boost::network::http::impl::normal_delegate::~normal_delegate() {} +boost::network::http::normal_delegate::~normal_delegate() {} #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 */ diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp index e754473f6..cb55bdb8e 100644 --- a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp @@ -9,21 +9,20 @@ #include -namespace boost { namespace network { namespace http { namespace impl { +namespace boost { namespace network { namespace http { struct resolver_base; -template -struct resolver_delegate_factory; - -template -struct resolver_delegate_factory >::type> { - typedef shared_ptr resolver_delegate_ptr; - // TODO Implement this! - resolver_delegate_ptr new_resolver_delegate(...); +struct resolver_delegate_factory { + resolver_delegate_factory(); + virtual shared_ptr create_resolver_delegate( + asio::io_service & service, + request_base const & request); + private: + resolver_delegate_factory(resolver_delegate_factory const &); // = delete + resolver_delegate_factory& operator=(resolver_delegate_factory); // = delete }; -} /* impl */ } /* http */ } /* network */ } /* boost */ diff --git a/boost/network/protocol/http/client/connection/simple_connection_factory.hpp b/boost/network/protocol/http/client/connection/simple_connection_factory.hpp new file mode 100644 index 000000000..c2d3759b7 --- /dev/null +++ b/boost/network/protocol/http/client/connection/simple_connection_factory.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111112 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111112 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct simple_connection_factory_pimpl; + +struct simple_connection_factory : connection_factory { + simple_connection_factory(); + simple_connection_factory(shared_ptr conn_delegate_factory, + shared_ptr res_delegate_factory); + virtual shared_ptr create_connection(asio::io_service & service, + request_base const & request, + bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path); // override + virtual ~simple_connection_factory(); + private: + scoped_ptr pimpl; + simple_connection_factory(simple_connection_factory const &); // = delete + simple_connection_factory& operator=(simple_connection_factory); // = delete +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111112 */ + diff --git a/boost/network/protocol/http/client/connection/simple_connection_factory.ipp b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp new file mode 100644 index 000000000..17fcced83 --- /dev/null +++ b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp @@ -0,0 +1,82 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111120 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111120 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct simple_connection_factory_pimpl { + simple_connection_factory_pimpl(shared_ptr conn_delegate_factory, + shared_ptr res_delegate_factory) + : conn_delegate_factory_(conn_delegate_factory) + , res_delegate_factory_(res_delegate_factory) + {} + + shared_ptr create_connection( + asio::io_service & service, + request_base const & request, + bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path) { + ::boost::network::uri::uri uri_(destination(request)); + bool https = to_lower_copy(scheme(uri_)) == "https"; + shared_ptr conn_; + conn_.reset(new (std::nothrow) http_async_connection( + res_delegate_factory_->create_resolver_delegate(service, request), + conn_delegate_factory_->create_connection_delegate( + service, https, openssl_certificate, openssl_verify_path), + service, + follow_redirects)); + } + + private: + shared_ptr conn_delegate_factory_; + shared_ptr res_delegate_factory_; +}; + +simple_connection_factory::simple_connection_factory() { + shared_ptr connection_delegate_factory_; + connection_delegate_factory_.reset(new (std::nothrow) connection_delegate_factory()); + shared_ptr resolver_delegate_factory_; + resolver_delegate_factory_.reset(new (std::nothrow) resolver_delegate_factory()); + pimpl.reset(new (std::nothrow) simple_connection_factory_pimpl( + connection_delegate_factory_, resolver_delegate_factory_)); +} + +simple_connection_factory::simple_connection_factory(shared_ptr conn_delegate_factory, + shared_ptr res_delegate_factory) +: pimpl(new (std::nothrow) simple_connection_factory_pimpl(conn_delegate_factory, res_delegate_factory)) +{} + +shared_ptr +simple_connection_factory::create_connection(asio::io_service & service, + request_base const & request, + bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path) { + return pimpl->create_connection(service, request, cache_resolved, follow_redirects, + openssl_certificate, openssl_verify_path); +} + +simple_connection_factory::~simple_connection_factory() { + // do nothing +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SIMPLE_CONNECTION_FACTORY_20111120 */ diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.hpp b/boost/network/protocol/http/client/connection/ssl_delegate.hpp index d07281df7..41cb284b0 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.hpp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.hpp @@ -13,7 +13,7 @@ #include #include -namespace boost { namespace network { namespace http { namespace impl { +namespace boost { namespace network { namespace http { struct ssl_delegate : connection_delegate, enable_shared_from_this { ssl_delegate(asio::io_service & service, @@ -41,8 +41,6 @@ struct ssl_delegate : connection_delegate, enable_shared_from_this function handler); }; -} /* impl */ - } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.ipp b/boost/network/protocol/http/client/connection/ssl_delegate.ipp index c7ee5e573..65a8f541e 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.ipp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.ipp @@ -10,14 +10,14 @@ #include #include -boost::network::http::impl::ssl_delegate::ssl_delegate(asio::io_service & service, +boost::network::http::ssl_delegate::ssl_delegate(asio::io_service & service, optional certificate_filename, optional verify_path) : service_(service), certificate_filename_(certificate_filename), verify_path_(verify_path) {} -void boost::network::http::impl::ssl_delegate::connect( +void boost::network::http::ssl_delegate::connect( asio::ip::tcp::endpoint & endpoint, function handler) { context_.reset(new asio::ssl::context( @@ -33,13 +33,13 @@ void boost::network::http::impl::ssl_delegate::connect( socket_.reset(new asio::ssl::stream(service_, *context_)); socket_->lowest_layer().async_connect( endpoint, - bind(&boost::network::http::impl::ssl_delegate::handle_connected, - boost::network::http::impl::ssl_delegate::shared_from_this(), + bind(&boost::network::http::ssl_delegate::handle_connected, + boost::network::http::ssl_delegate::shared_from_this(), asio::placeholders::error, handler)); } -void boost::network::http::impl::ssl_delegate::handle_connected(system::error_code const & ec, +void boost::network::http::ssl_delegate::handle_connected(system::error_code const & ec, function handler) { if (!ec) { socket_->async_handshake(asio::ssl::stream_base::client, handler); @@ -48,18 +48,18 @@ void boost::network::http::impl::ssl_delegate::handle_connected(system::error_co } } -void boost::network::http::impl::ssl_delegate::write( +void boost::network::http::ssl_delegate::write( asio::streambuf & command_streambuf, function handler) { asio::async_write(*socket_, command_streambuf, handler); } -void boost::network::http::impl::ssl_delegate::read_some( +void boost::network::http::ssl_delegate::read_some( asio::mutable_buffers_1 const & read_buffer, function handler) { socket_->async_read_some(read_buffer, handler); } -boost::network::http::impl::ssl_delegate::~ssl_delegate() {} +boost::network::http::ssl_delegate::~ssl_delegate() {} #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 */ diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index f26282215..ee6113222 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -10,7 +10,8 @@ #include #include #include -#include +#include +#include namespace boost { namespace network { namespace http { @@ -127,12 +128,16 @@ struct basic_client_facade { template void init_base(ArgPack const & args, no_io_service) { - base.reset(new client_base(this->get_connection_manager(args))); + base.reset(new client_base( + this->get_connection_manager(args))); } template void init_base(ArgPack const & args, has_io_service) { - base.reset(new client_base(args[_io_service], this->get_connection_manager(args))); + base.reset( + new client_base( + args[_io_service], + this->get_connection_manager(args))); } private: @@ -142,16 +147,32 @@ struct basic_client_facade { shared_ptr connection_manager_ = args[_connection_manager|shared_ptr()]; if (!connection_manager_.get()) { // Because there's no explicit connection manager, we use the default - // implementation as provided by the tag. + // implementation. connection_manager_.reset( - new simple_async_connection_manager(args[_cache_resolved|false], - args[_follow_redirects|false], - args[_openssl_certificate|optional()], - args[_openssl_verify_path|optional()])); + new (std::nothrow) simple_connection_manager( + args[_cache_resolved|false], + args[_follow_redirects|false], + args[_openssl_certificate|optional()], + args[_openssl_verify_path|optional()], + this->get_connection_factory(args))); } return connection_manager_; } + + template + shared_ptr get_connection_factory(ArgPack const & args) { + shared_ptr connection_factory_ = args[_connection_factory|shared_ptr()]; + if (!connection_factory_.get()) { + // Because there's no explicit connection factory, we use the default + // implementation. + connection_factory_.reset( + new (std::nothrow) simple_connection_factory()); + } + + return connection_factory_; + } + }; } // namespace http diff --git a/boost/network/protocol/http/client/parameters.hpp b/boost/network/protocol/http/client/parameters.hpp index 19c213fe1..340e9506e 100644 --- a/boost/network/protocol/http/client/parameters.hpp +++ b/boost/network/protocol/http/client/parameters.hpp @@ -21,6 +21,7 @@ namespace boost { namespace network { namespace http { BOOST_PARAMETER_NAME(body_handler) BOOST_PARAMETER_NAME(connection_manager) + BOOST_PARAMETER_NAME(connection_factory) } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/simple_connection_manager.hpp b/boost/network/protocol/http/client/simple_connection_manager.hpp new file mode 100644 index 000000000..173135164 --- /dev/null +++ b/boost/network/protocol/http/client/simple_connection_manager.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_HPP_20111105 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_HPP_20111105 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +namespace boost { namespace network { namespace http { + +/// Forward declaration of simple_connection_manager_pimpl. +struct simple_connection_manager_pimpl; + +/** simple_connection_manager + * + * This connection manager implementation doesn't do any connection tracking + * and mostly delegates the connection creation from a connection factory. + */ +struct simple_connection_manager : connection_manager { + /** Constructor + * + * Args: + * bool cache_resolved: Indicate whether to cache resolved endpoints. + * bool follow_redirects: Indicate whether to follow HTTP 301/302/304 + * redirections. + * optional openssl_certificate: The filename for the + * OpenSSL certificate to use. + * optional openssl_verify_path: The directory from which + * OpenSSL certificates are + * searched for when + * verification is requested. + * shared_ptr: The connection factory that actually + * creates the appropriate client + * connection object. + */ + simple_connection_manager(bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path, + shared_ptr connection_factory); + + /** Constructor + * + * Args: + * bool cache_resolved: Indicate whether to cache resolved endpoints. + * bool follow_redirects: Indicate whether to follow HTTP 301/302/304 + * redirections. + * std::string const & openssl_certificate: The filename for the + * OpenSSL certificate to use. + * std::string const & openssl_verify_path: The directory from which + * OpenSSL certificates are + * searched for when + * verification is requested. + * shared_ptr: The connection factory that actually + * creates the appropriate client + * connection object. + */ + simple_connection_manager(bool cache_resolved, + bool follow_redirects, + std::string const & openssl_certificate, + std::string const & openssl_verify_path, + shared_ptr connection_factory); + + /** get_connection + * + * Args: + * asio::io_service & service: The io_service instance to which the + * connection should be bound to (for newly + * created objects, ignored for already + * created objects). + * request_base const & request: The request object that includes the + * information required by the connection. + * + * Returns: + * shared_ptr -- either an already-generated object + * or a newly constructed connection configured to perform the request. + */ + virtual shared_ptr get_connection( + asio::io_service & service, + request_base const & request); // override + + /** reset + * + * This function resets the internal caches and intermediary data structures + * used by the connection manager to perform its functions. In the case of + * this simple_connection_manager, the call to reset will not do anything. + */ + virtual void reset(); // override + + /** Destructor. + */ + virtual ~simple_connection_manager(); // override + + protected: + scoped_ptr pimpl; + + private: + /// Disabled copy constructor. + simple_connection_manager(simple_connection_manager const &); // = delete + /// Disabled assignment operator. + simple_connection_manager & operator=(simple_connection_manager); // = delete +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_HPP_20111105 */ diff --git a/boost/network/protocol/http/client/simple_connection_manager.ipp b/boost/network/protocol/http/client/simple_connection_manager.ipp new file mode 100644 index 000000000..ff049ac92 --- /dev/null +++ b/boost/network/protocol/http/client/simple_connection_manager.ipp @@ -0,0 +1,99 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_IPP_20111112 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_IPP_20111112 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +struct simple_connection_manager_pimpl { + simple_connection_manager_pimpl(bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path, + shared_ptr connection_factory) + : cache_resolved_(cache_resolved_) + , follow_redirects_(follow_redirects) + , openssl_certificate_(openssl_certificate) + , openssl_verify_path_(openssl_verify_path) + , connection_factory_(connection_factory) + {} + + simple_connection_manager_pimpl(bool cache_resolved, + bool follow_redirects, + std::string const & openssl_certificate, + std::string const & openssl_verify_path, + shared_ptr connection_factory) + : cache_resolved_(cache_resolved_) + , follow_redirects_(follow_redirects) + , openssl_certificate_(openssl_certificate) + , openssl_verify_path_(openssl_verify_path) + , connection_factory_(connection_factory) + {} + + shared_ptr get_connection(asio::io_service & service, + request_base const & request) { + return connection_factory_->create_connection( + service, request, cache_resolved_, follow_redirects_, + openssl_certificate_, openssl_verify_path_); + } + + void reset() { + // do nothing here. + } + + ~simple_connection_manager_pimpl() { + // do nothing here. + } + + private: + bool cache_resolved_, follow_redirects_; + optional openssl_certificate_, openssl_verify_path_; + shared_ptr connection_factory_; + +}; + +simple_connection_manager::simple_connection_manager(bool cache_resolved, + bool follow_redirects, + optional openssl_certificate, + optional openssl_verify_path, + shared_ptr connection_factory) +: pimpl(new (std::nothrow) simple_connection_manager_pimpl( + cache_resolved, follow_redirects, openssl_certificate, openssl_verify_path, connection_factory)) +{} + +simple_connection_manager::simple_connection_manager(bool cache_resolved, + bool follow_redirects, + std::string const & openssl_certificate, + std::string const & openssl_verify_path, + shared_ptr connection_factory) +: pimpl(new (std::nothrow) simple_connection_manager_pimpl( + cache_resolved, follow_redirects, openssl_certificate, openssl_verify_path, connection_factory)) +{} + +shared_ptr simple_connection_manager::get_connection( + asio::io_service & service, + request_base const & request) { + return pimpl->get_connection(service, request); +} + +void simple_connection_manager::reset() { + pimpl->reset(); +} + +simple_connection_manager::~simple_connection_manager() { + // do nothing here. +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SIMPLE_CONNECTION_MANAGER_IPP_20111112 */ diff --git a/boost/network/protocol/http/request/request.hpp b/boost/network/protocol/http/request/request.hpp index eab2164d2..eb01a25d9 100644 --- a/boost/network/protocol/http/request/request.hpp +++ b/boost/network/protocol/http/request/request.hpp @@ -28,13 +28,13 @@ struct request : request_base { virtual void append_body(std::string const & data); // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); - virtual void get_headers(function inserter); - virtual void get_headers(std::string const & name, function inserter); - virtual void get_headers(function predicate, function inserter); - virtual void get_body(std::string & body); - virtual void get_body(function)> chunk_reader, size_t size); + virtual void get_destination(std::string & destination) const; + virtual void get_source(std::string & source) const; + virtual void get_headers(function inserter) const; + virtual void get_headers(std::string const & name, function inserter) const; + virtual void get_headers(function predicate, function inserter) const; + virtual void get_body(std::string & body) const; + virtual void get_body(function)> chunk_reader, size_t size) const; // From request_base... // Setters @@ -46,12 +46,12 @@ struct request : request_base { virtual void set_uri(network::uri::uri const &uri); // Getters - virtual void get_uri(network::uri::uri &uri); - virtual void get_uri(std::string &uri); - virtual void get_method(std::string & method); - virtual void get_status(std::string & status); - virtual void get_status_message(std::string & status_message); - virtual void get_body_stream(body_stream & output_stream); + virtual void get_uri(network::uri::uri &uri) const; + virtual void get_uri(std::string &uri) const; + virtual void get_method(std::string & method) const; + virtual void get_status(std::string & status) const; + virtual void get_status_message(std::string & status_message) const; + virtual void get_body_stream(body_stream & output_stream) const; virtual ~request(); private: diff --git a/boost/network/protocol/http/request/request_base.hpp b/boost/network/protocol/http/request/request_base.hpp index add874829..79ccbbe85 100644 --- a/boost/network/protocol/http/request/request_base.hpp +++ b/boost/network/protocol/http/request/request_base.hpp @@ -49,12 +49,12 @@ struct request_base : message_base, request_storage_base { virtual void set_uri(network::uri::uri const &uri) = 0; // Getters - virtual void get_uri(network::uri::uri &uri) = 0; - virtual void get_uri(std::string &uri) = 0; - virtual void get_method(std::string & method) = 0; - virtual void get_status(std::string & status) = 0; - virtual void get_status_message(std::string & status_message) = 0; - virtual void get_body_stream(body_stream & output_stream) = 0; + virtual void get_uri(network::uri::uri &uri) const = 0; + virtual void get_uri(std::string &uri) const = 0; + virtual void get_method(std::string & method) const = 0; + virtual void get_status(std::string & status) const = 0; + virtual void get_status_message(std::string & status_message) const = 0; + virtual void get_body_stream(body_stream & output_stream) const = 0; virtual ~request_base() = 0; }; diff --git a/boost/network/protocol/http/response/response.hpp b/boost/network/protocol/http/response/response.hpp index 7b22c0cac..412dfe3c3 100644 --- a/boost/network/protocol/http/response/response.hpp +++ b/boost/network/protocol/http/response/response.hpp @@ -24,20 +24,20 @@ struct response : response_base { virtual void append_body(std::string const & data); // Retrievers - virtual void get_destination(std::string & destination); - virtual void get_source(std::string & source); + virtual void get_destination(std::string & destination) const; + virtual void get_source(std::string & source) const; virtual void get_headers( - function inserter); + function inserter) const; virtual void get_headers( std::string const & name, - function inserter); + function inserter) const; virtual void get_headers( function predicate, - function inserter); - virtual void get_body(std::string & body); + function inserter) const; + virtual void get_body(std::string & body) const; virtual void get_body( function)> chunk_reader, - size_t size); + size_t size) const; // From response_base... virtual void set_status(std::string const & new_status); diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index c3101a62d..6b2599d9b 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -28,7 +28,11 @@ add_library(cppnetlib-message-wrappers ${CPP-NETLIB_MESSAGE_WRAPPERS_SRCS}) set(CPP-NETLIB_HTTP_MESSAGE_SRCS http/request.cpp http/response.cpp) add_library(cppnetlib-http-message ${CPP-NETLIB_HTTP_MESSAGE_SRCS}) -set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/client_connections.cpp) +set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS + http/client_connections.cpp + http/simple_connection_manager.cpp + http/simple_connection_factory.cpp + http/connection_delegate_factory.cpp) add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) set(CPP-NETLIB_UTILS_THREAD_POOL_SRCS utils/thread_pool.cpp) diff --git a/libs/network/src/http/connection_delegate_factory.cpp b/libs/network/src/http/connection_delegate_factory.cpp new file mode 100644 index 000000000..9c9cf31ee --- /dev/null +++ b/libs/network/src/http/connection_delegate_factory.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/simple_connection_factory.cpp b/libs/network/src/http/simple_connection_factory.cpp new file mode 100644 index 000000000..dc0bd6847 --- /dev/null +++ b/libs/network/src/http/simple_connection_factory.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/simple_connection_manager.cpp b/libs/network/src/http/simple_connection_manager.cpp new file mode 100644 index 000000000..d446ae037 --- /dev/null +++ b/libs/network/src/http/simple_connection_manager.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include From ed4d247d67243399aa2a9197e77f6e613e738217 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 26 Nov 2011 23:48:16 +1100 Subject: [PATCH 045/438] Progress on build of some tests. This resolves some dependency issues on the cppnetlib-http-client-connections lib. From here on out I'm moving on to the development of the meat of the client implementation, as well as the functionality. It looks like (at least optimistically) the event horizon is at least visible from this black hole. --- .../protocol/http/client/simple_connection_manager.ipp | 1 - boost/network/uri/accessors.hpp | 5 +++++ boost/network/uri/uri.hpp | 1 + libs/network/build/CMakeLists.txt | 9 +++++++++ libs/network/src/CMakeLists.txt | 4 ++++ libs/network/test/http/CMakeLists.txt | 6 ++++-- 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/boost/network/protocol/http/client/simple_connection_manager.ipp b/boost/network/protocol/http/client/simple_connection_manager.ipp index ff049ac92..e8042c374 100644 --- a/boost/network/protocol/http/client/simple_connection_manager.ipp +++ b/boost/network/protocol/http/client/simple_connection_manager.ipp @@ -55,7 +55,6 @@ struct simple_connection_manager_pimpl { bool cache_resolved_, follow_redirects_; optional openssl_certificate_, openssl_verify_path_; shared_ptr connection_factory_; - }; simple_connection_manager::simple_connection_manager(bool cache_resolved, diff --git a/boost/network/uri/accessors.hpp b/boost/network/uri/accessors.hpp index 7b71862b3..242caf218 100644 --- a/boost/network/uri/accessors.hpp +++ b/boost/network/uri/accessors.hpp @@ -51,6 +51,7 @@ Map &query_map(const uri &uri_, Map &map) { return map; } +inline std::string username(const uri &uri_) { uri::const_range_type user_info_range = uri_.user_info_range(); uri::const_iterator it(boost::begin(user_info_range)), end(boost::end(user_info_range)); @@ -62,6 +63,7 @@ std::string username(const uri &uri_) { return std::string(boost::begin(user_info_range), it); } +inline std::string password(const uri &uri_) { uri::const_range_type user_info_range = uri_.user_info_range(); uri::const_iterator it(boost::begin(user_info_range)), end(boost::end(user_info_range)); @@ -74,6 +76,7 @@ std::string password(const uri &uri_) { return std::string(it, boost::end(user_info_range)); } +inline std::string decoded_path(const uri &uri_) { uri::const_range_type path_range = uri_.path_range(); std::string decoded_path; @@ -81,6 +84,7 @@ std::string decoded_path(const uri &uri_) { return decoded_path; } +inline std::string decoded_query(const uri &uri_) { uri::const_range_type query_range = uri_.query_range(); std::string decoded_query; @@ -88,6 +92,7 @@ std::string decoded_query(const uri &uri_) { return decoded_query; } +inline std::string decoded_fragment(const uri &uri_) { uri::const_range_type fragment_range = uri_.fragment_range(); std::string decoded_fragment; diff --git a/boost/network/uri/uri.hpp b/boost/network/uri/uri.hpp index 31aae7c95..8fa4e07ad 100644 --- a/boost/network/uri/uri.hpp +++ b/boost/network/uri/uri.hpp @@ -292,6 +292,7 @@ bool is_hierarchical(const uri &uri_) { return false; } +inline bool is_opaque(const uri &uri_) { return false; } diff --git a/libs/network/build/CMakeLists.txt b/libs/network/build/CMakeLists.txt index 305bb82ce..931ab14de 100644 --- a/libs/network/build/CMakeLists.txt +++ b/libs/network/build/CMakeLists.txt @@ -13,3 +13,12 @@ add_library(cppnetlib-http-message STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/request.cpp ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/response.cpp) +add_library(cppnetlib-http-client-connections + STATIC + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/client_connections.cpp + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/simple_connection_manager.cpp + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/simple_connection_factory.cpp + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/connection_delegate_factory.cpp) +add_library(cppnetlib-http-client + STATIC + ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/http/client.cpp) diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 6b2599d9b..81e471882 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -35,5 +35,9 @@ set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/connection_delegate_factory.cpp) add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) +set(CPP-NETLIB_HTTP_CLIENT_SRCS + http/client.cpp) +add_library(cppnetlib-http-client ${CPP-NETLIB_HTTP_CLIENT_SRCS}) + set(CPP-NETLIB_UTILS_THREAD_POOL_SRCS utils/thread_pool.cpp) add_library(cppnetlib-utils-thread_pool ${CPP-NETLIB_UTILS_THREAD_POOL_SRCS}) diff --git a/libs/network/test/http/CMakeLists.txt b/libs/network/test/http/CMakeLists.txt index 5b04d0026..e71b8333f 100644 --- a/libs/network/test/http/CMakeLists.txt +++ b/libs/network/test/http/CMakeLists.txt @@ -35,14 +35,16 @@ if (Boost_FOUND) cppnetlib-uri cppnetlib-message cppnetlib-http-message - cppnetlib-client-connections) + cppnetlib-http-client + cppnetlib-http-client-connections) target_link_libraries(cpp-netlib-http-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri cppnetlib-message cppnetlib-http-message - cppnetlib-client-connections) + cppnetlib-http-client + cppnetlib-http-client-connections) if (OPENSSL_FOUND) target_link_libraries(cpp-netlib-http-${test} ${OPENSSL_LIBRARIES}) endif() From bcdf43c7141f1e1ccdd306870b0fdeaa2170bf80 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 26 Nov 2011 23:55:03 +1100 Subject: [PATCH 046/438] Step one: Client base compiles. This is the first step in filling out cppnetlib-http-client lib object files. --- boost/network/protocol/http/client/base.ipp | 10 ++++++---- libs/network/src/http/client.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 libs/network/src/http/client.cpp diff --git a/boost/network/protocol/http/client/base.ipp b/boost/network/protocol/http/client/base.ipp index 8140f67e4..34732b6d3 100644 --- a/boost/network/protocol/http/client/base.ipp +++ b/boost/network/protocol/http/client/base.ipp @@ -7,11 +7,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include #include #include +#include namespace boost { namespace network { namespace http { @@ -20,8 +22,8 @@ struct client_base_pimpl { function const &, system::error_code const &)> body_callback_function_type; client_base_pimpl(shared_ptr connection_manager_); - client_base_pimpl(io_service & service, shared_ptr connection_manager_); - response const request_skeleton(request const & request_, + client_base_pimpl(asio::io_service & service, shared_ptr connection_manager_); + response const request_skeleton(request_base const & request_, std::string const & method, bool get_body, body_callback_function_type callback); @@ -80,7 +82,7 @@ client_base_pimpl::client_base_pimpl(boost::asio::io_service & service, BOOST_THROW_EXCEPTION(std::runtime_error("Cannot allocate sentinel; not enough memory.")); } -~client_base_pimpl::client_base_pimpl() +client_base_pimpl::~client_base_pimpl() { sentinel_.reset(); connection_manager_->reset(); @@ -92,7 +94,7 @@ client_base_pimpl::client_base_pimpl(boost::asio::io_service & service, } response const client_base_pimpl::request_skeleton( - request const & request_, + request_base const & request_, std::string const & method, bool get_body, body_callback_function_type callback diff --git a/libs/network/src/http/client.cpp b/libs/network/src/http/client.cpp new file mode 100644 index 000000000..fe421c53d --- /dev/null +++ b/libs/network/src/http/client.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include From fab3b5f7844467f904e4ba6a54c61c83ed890fdb Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 27 Nov 2011 00:34:53 +1100 Subject: [PATCH 047/438] Step two: implement the resolver delegate factory. This moves out the policies into the client/connection/ directory and adds the necessary parts that deal with the creation of the async_resolver implementation. We now have wired the async_resolver to derive from a resolver_delegate type that the connections will use to resolve IP addresses of hosts. --- .../http/client/connection/async_normal.hpp | 2 +- .../http/client/connection/async_resolver.hpp | 43 +++++++++++++++++ .../connection}/async_resolver.ipp | 8 ++-- .../client/connection/resolver_delegate.hpp | 17 +++++++ .../client/connection/resolver_delegate.ipp | 23 +++++++++ .../connection/resolver_delegate_factory.hpp | 11 +++-- .../connection/resolver_delegate_factory.ipp | 32 +++++++++++++ .../protocol/http/policies/async_resolver.hpp | 48 ------------------- libs/network/src/CMakeLists.txt | 3 +- .../http/client_resolver_delegate_factory.cpp | 11 +++++ 10 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 boost/network/protocol/http/client/connection/async_resolver.hpp rename boost/network/protocol/http/{policies => client/connection}/async_resolver.ipp (92%) create mode 100644 boost/network/protocol/http/client/connection/resolver_delegate.ipp create mode 100644 boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp delete mode 100644 boost/network/protocol/http/policies/async_resolver.hpp create mode 100644 libs/network/src/http/client_resolver_delegate_factory.cpp diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index 51abe10a1..c31edba68 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -23,7 +23,7 @@ struct http_async_connection : client_connection , enable_shared_from_this { using client_connection::callback_type; - http_async_connection(shared_ptr resolver_delegate, + http_async_connection(shared_ptr resolver_delegate, shared_ptr connection_delegate, asio::io_service & io_service, bool follow_redirects); diff --git a/boost/network/protocol/http/client/connection/async_resolver.hpp b/boost/network/protocol/http/client/connection/async_resolver.hpp new file mode 100644 index 000000000..abc39a403 --- /dev/null +++ b/boost/network/protocol/http/client/connection/async_resolver.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_20111126 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_20111126 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +struct async_resolver_pimpl; + +struct async_resolver : resolver_delegate { + using resolver_delegate::resolve_completion_function; + + explicit async_resolver(asio::io_service & service); + virtual void resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved); // override + virtual void clear_resolved_cache(); // override + virtual ~async_resolver(); + + protected: + // We need a shared_ptr because the pimpl may live on long after the resolver + // delegate (instances of this type) is actually destroyed. + shared_ptr pimpl; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_20111126 diff --git a/boost/network/protocol/http/policies/async_resolver.ipp b/boost/network/protocol/http/client/connection/async_resolver.ipp similarity index 92% rename from boost/network/protocol/http/policies/async_resolver.ipp rename to boost/network/protocol/http/client/connection/async_resolver.ipp index d7082efad..0a1ac390c 100644 --- a/boost/network/protocol/http/policies/async_resolver.ipp +++ b/boost/network/protocol/http/client/connection/async_resolver.ipp @@ -1,5 +1,5 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 -#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_IPP_20110911 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_IPP_20111126 // Copyright 2011 Dean Michael Berris . // Copyright 2011 Google, Inc. @@ -39,6 +39,8 @@ async_resolver::~async_resolver() { // Do nothing } +// Define the actual implementation in a private implementation class. + struct async_resolver_pimpl : enable_shared_from_this { explicit async_resolver_pimpl(asio::io_service & service); void resolve(std::string const & host, @@ -121,4 +123,4 @@ void handle_resolve(std::string const & host, } /* boost */ -#endif /* BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_IPP_20110910 */ +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_RESOLVER_IPP_20111126 */ diff --git a/boost/network/protocol/http/client/connection/resolver_delegate.hpp b/boost/network/protocol/http/client/connection/resolver_delegate.hpp index 3acf2fd7b..dd2492db0 100644 --- a/boost/network/protocol/http/client/connection/resolver_delegate.hpp +++ b/boost/network/protocol/http/client/connection/resolver_delegate.hpp @@ -7,9 +7,22 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include +#include +#include + namespace boost { namespace network { namespace http { struct resolver_delegate { + typedef asio::ip::udp::resolver::iterator resolver_iterator; + typedef std::pair + iterator_pair; + typedef function + resolve_completion_function; + virtual void resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved) = 0; + virtual void clear_resolved_cache() = 0; virtual ~resolver_delegate() = 0; }; @@ -19,4 +32,8 @@ struct resolver_delegate { } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_HPP_20111016 */ diff --git a/boost/network/protocol/http/client/connection/resolver_delegate.ipp b/boost/network/protocol/http/client/connection/resolver_delegate.ipp new file mode 100644 index 000000000..4a9c06a2d --- /dev/null +++ b/boost/network/protocol/http/client/connection/resolver_delegate.ipp @@ -0,0 +1,23 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_IPP_20111126 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_IPP_20111126 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +resolver_delegate::~resolver_delegate() {} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_IPP_20111126 diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp index cb55bdb8e..4d8597819 100644 --- a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp @@ -8,16 +8,17 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include +#include namespace boost { namespace network { namespace http { -struct resolver_base; - struct resolver_delegate_factory { resolver_delegate_factory(); - virtual shared_ptr create_resolver_delegate( + virtual shared_ptr create_resolver_delegate( asio::io_service & service, request_base const & request); + virtual ~resolver_delegate_factory(); private: resolver_delegate_factory(resolver_delegate_factory const &); // = delete resolver_delegate_factory& operator=(resolver_delegate_factory); // = delete @@ -27,4 +28,8 @@ struct resolver_delegate_factory { } /* network */ } /* boost */ +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_HPP_20110930 */ diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp new file mode 100644 index 000000000..c74377258 --- /dev/null +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp @@ -0,0 +1,32 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_IPP_20111126 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_IPP_20111126 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +resolver_delegate_factory::resolver_delegate_factory() {} + +shared_ptr +resolver_delegate_factory::create_resolver_delegate(asio::io_service & service, + request_base const & request) { + shared_ptr resolver_(new (std::nothrow) async_resolver(service)); + return resolver_; +} + +resolver_delegate_factory::~resolver_delegate_factory() {} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_RESOLVER_DELEGATE_FACTORY_IPP_20111126 diff --git a/boost/network/protocol/http/policies/async_resolver.hpp b/boost/network/protocol/http/policies/async_resolver.hpp deleted file mode 100644 index c7cacfbdf..000000000 --- a/boost/network/protocol/http/policies/async_resolver.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 -#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 - -// Copyright 2011 Dean Michael Berris . -// Copyright 2011 Google, Inc. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -namespace boost { namespace network { namespace http { namespace policies { - -struct async_resolver_pimpl; - -struct async_resolver { - typedef asio::ip::udp::resolver::iterator resolver_iterator; - typedef std::pair - iterator_pair; - typedef function - resolve_completion_function; - - explicit async_resolver(asio::io_service & service); - void resolve(std::string const & host, - uint16_t port, - resolve_completion_function once_resolved); - void clear_resolved_cache(); - ~async_resolver(); - - protected: - shared_ptr pimpl; -}; - -} // namespace policies - -} // namespace http - -} // namespace network - -} // namespace boost - -#ifdef BOOST_NETWORK_NO_LIB -#include -#endif - -#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 81e471882..71a8ae918 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -32,7 +32,8 @@ set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/client_connections.cpp http/simple_connection_manager.cpp http/simple_connection_factory.cpp - http/connection_delegate_factory.cpp) + http/connection_delegate_factory.cpp + http/client_resolver_delegate_factory.cpp) add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) set(CPP-NETLIB_HTTP_CLIENT_SRCS diff --git a/libs/network/src/http/client_resolver_delegate_factory.cpp b/libs/network/src/http/client_resolver_delegate_factory.cpp new file mode 100644 index 000000000..06c82f2a8 --- /dev/null +++ b/libs/network/src/http/client_resolver_delegate_factory.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include From 9ad624aefb5a5b794a351b5394caba5ae9a5cb4f Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 27 Nov 2011 01:05:29 +1100 Subject: [PATCH 048/438] Getting the ducks in a neat row... First, we get the asynchronous resolver delegate into a cpp file that gets built and linked into the cppnetlib-client-connections lib. We then write it up in the connection factory and resolver delegate factory implementation so that we can create instances of these properly. Then lastly we have the default implementation of the pure virtual destructors for the pure interface types we use. --- .../http/client/connection/async_resolver.hpp | 2 +- .../http/client/connection/async_resolver.ipp | 77 +++++++++++-------- .../connection_delegate_factory.ipp | 2 + .../client/connection/connection_factory.ipp | 22 ++++++ .../connection/resolver_delegate_factory.hpp | 2 +- .../connection/resolver_delegate_factory.ipp | 5 +- .../connection/simple_connection_factory.ipp | 2 +- libs/network/src/CMakeLists.txt | 6 +- .../src/http/client_async_resolver.cpp | 11 +++ .../src/http/client_connection_delegates.cpp | 14 ++++ .../src/http/client_connection_factory.cpp | 11 +++ .../src/http/client_resolver_delegate.cpp | 11 +++ 12 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 boost/network/protocol/http/client/connection/connection_factory.ipp create mode 100644 libs/network/src/http/client_async_resolver.cpp create mode 100644 libs/network/src/http/client_connection_delegates.cpp create mode 100644 libs/network/src/http/client_connection_factory.cpp create mode 100644 libs/network/src/http/client_resolver_delegate.cpp diff --git a/boost/network/protocol/http/client/connection/async_resolver.hpp b/boost/network/protocol/http/client/connection/async_resolver.hpp index abc39a403..dc6dfd151 100644 --- a/boost/network/protocol/http/client/connection/async_resolver.hpp +++ b/boost/network/protocol/http/client/connection/async_resolver.hpp @@ -17,7 +17,7 @@ struct async_resolver_pimpl; struct async_resolver : resolver_delegate { using resolver_delegate::resolve_completion_function; - explicit async_resolver(asio::io_service & service); + async_resolver(asio::io_service & service, bool cache_resolved); virtual void resolve(std::string const & host, uint16_t port, resolve_completion_function once_resolved); // override diff --git a/boost/network/protocol/http/client/connection/async_resolver.ipp b/boost/network/protocol/http/client/connection/async_resolver.ipp index 0a1ac390c..90d980ed6 100644 --- a/boost/network/protocol/http/client/connection/async_resolver.ipp +++ b/boost/network/protocol/http/client/connection/async_resolver.ipp @@ -16,33 +16,16 @@ #include #include #include +#include +#include +#include +#include +#include namespace boost { namespace network { namespace http { - -async_resolver::async_resolver(asio::io_service & service) -: pimpl(new (std::nothrow) async_resolver_pimpl(service)) -{} - -void async_resolver::resolve(std::string const & host, - uint16_t port, - resolve_completion_function once_resolved) { - BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); - pimpl->resolve(host, port, once_resolved); -} - -void async_resolver::clear_resolved_cache() { - BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); - pimpl->clear_resolved_cache(); -} - -async_resolver::~async_resolver() { - // Do nothing -} - -// Define the actual implementation in a private implementation class. - struct async_resolver_pimpl : enable_shared_from_this { - explicit async_resolver_pimpl(asio::io_service & service); + typedef resolver_delegate::resolve_completion_function resolve_completion_function; + async_resolver_pimpl(asio::io_service & service, bool cache_resolved); void resolve(std::string const & host, uint16_t port, resolve_completion_function once_resolved); @@ -56,20 +39,30 @@ struct async_resolver_pimpl : enable_shared_from_this { endpoint_cache; endpoint_cache endpoint_cache_; scoped_ptr resolver_strand_; + + void handle_resolve(std::string const & host, + resolve_completion_function once_resolved, + system::error_code const & ec, + resolver_iterator endpoint_iterator); }; -async_resolver_pimpl::async_resolver_pimpl(asio::io_service & service) +async_resolver_pimpl::async_resolver_pimpl(asio::io_service & service, bool cache_resolved) : resolver_(service), - cache_resolved(cache_resolved), + cache_resolved_(cache_resolved), endpoint_cache_(), resolver_strand_(new(std::nothrow) asio::io_service::strand(service)) { // Do nothing } +void async_resolver_pimpl::clear_resolved_cache() { + if (cache_resolved_) + endpoint_cache().swap(endpoint_cache_); +} + void async_resolver_pimpl::resolve(std::string const & host, - boost::uint16_t port, - resolve_completion_function once_resolved) { + boost::uint16_t port, + resolve_completion_function once_resolved) { if (!resolver_strand_.get()) BOOST_THROW_EXCEPTION(std::runtime_error( "Uninitialized resolver strand, ran out of memory.")); @@ -98,10 +91,10 @@ void async_resolver_pimpl::resolve(std::string const & host, boost::asio::placeholders::iterator))); } -void handle_resolve(std::string const & host, - resolve_completion_function once_resolved, - boost::system::error_code const & ec, - resolver_iterator endpoint_iterator) { +void async_resolver_pimpl::handle_resolve(std::string const & host, + resolve_completion_function once_resolved, + boost::system::error_code const & ec, + resolver_iterator endpoint_iterator) { endpoint_cache::iterator iter; bool inserted = false; if (!ec && cache_resolved_) { @@ -116,6 +109,26 @@ void handle_resolve(std::string const & host, } } +async_resolver::async_resolver(asio::io_service & service, bool cache_resolved) +: pimpl(new (std::nothrow) async_resolver_pimpl(service, cache_resolved)) +{} + +void async_resolver::resolve(std::string const & host, + uint16_t port, + resolve_completion_function once_resolved) { + BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); + pimpl->resolve(host, port, once_resolved); +} + +void async_resolver::clear_resolved_cache() { + BOOST_ASSERT(pimpl.get() && "Uninitialized pimpl, probably ran out of memory."); + pimpl->clear_resolved_cache(); +} + +async_resolver::~async_resolver() { + // Do nothing +} + } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp b/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp index 4ac901457..64133e001 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp +++ b/boost/network/protocol/http/client/connection/connection_delegate_factory.ipp @@ -39,6 +39,8 @@ connection_delegate_factory::create_connection_delegate( return delegate; } +connection_delegate_factory::~connection_delegate_factory() {} + } /* http */ } /* network */ diff --git a/boost/network/protocol/http/client/connection/connection_factory.ipp b/boost/network/protocol/http/client/connection/connection_factory.ipp new file mode 100644 index 000000000..fb8004dcd --- /dev/null +++ b/boost/network/protocol/http/client/connection/connection_factory.ipp @@ -0,0 +1,22 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_IPP_20111126 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_IPP_20111126 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +connection_factory::~connection_factory() {} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_FACTORY_IPP_20111126 diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp index 4d8597819..3c21fa8d2 100644 --- a/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp @@ -17,7 +17,7 @@ struct resolver_delegate_factory { resolver_delegate_factory(); virtual shared_ptr create_resolver_delegate( asio::io_service & service, - request_base const & request); + bool cache_resolved); virtual ~resolver_delegate_factory(); private: resolver_delegate_factory(resolver_delegate_factory const &); // = delete diff --git a/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp b/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp index c74377258..ee3df204f 100644 --- a/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp +++ b/boost/network/protocol/http/client/connection/resolver_delegate_factory.ipp @@ -16,8 +16,9 @@ resolver_delegate_factory::resolver_delegate_factory() {} shared_ptr resolver_delegate_factory::create_resolver_delegate(asio::io_service & service, - request_base const & request) { - shared_ptr resolver_(new (std::nothrow) async_resolver(service)); + bool cache_resolved) { + shared_ptr resolver_( + new (std::nothrow) async_resolver(service, cache_resolved)); return resolver_; } diff --git a/boost/network/protocol/http/client/connection/simple_connection_factory.ipp b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp index 17fcced83..41eeea9ba 100644 --- a/boost/network/protocol/http/client/connection/simple_connection_factory.ipp +++ b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp @@ -32,7 +32,7 @@ struct simple_connection_factory_pimpl { bool https = to_lower_copy(scheme(uri_)) == "https"; shared_ptr conn_; conn_.reset(new (std::nothrow) http_async_connection( - res_delegate_factory_->create_resolver_delegate(service, request), + res_delegate_factory_->create_resolver_delegate(service, cache_resolved), conn_delegate_factory_->create_connection_delegate( service, https, openssl_certificate, openssl_verify_path), service, diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 71a8ae918..293fa90d8 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -33,7 +33,11 @@ set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/simple_connection_manager.cpp http/simple_connection_factory.cpp http/connection_delegate_factory.cpp - http/client_resolver_delegate_factory.cpp) + http/client_resolver_delegate.cpp + http/client_resolver_delegate_factory.cpp + http/client_connection_delegates.cpp + http/client_connection_factory.cpp + http/client_async_resolver.cpp) add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) set(CPP-NETLIB_HTTP_CLIENT_SRCS diff --git a/libs/network/src/http/client_async_resolver.cpp b/libs/network/src/http/client_async_resolver.cpp new file mode 100644 index 000000000..19ee682cd --- /dev/null +++ b/libs/network/src/http/client_async_resolver.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/client_connection_delegates.cpp b/libs/network/src/http/client_connection_delegates.cpp new file mode 100644 index 000000000..f596f841f --- /dev/null +++ b/libs/network/src/http/client_connection_delegates.cpp @@ -0,0 +1,14 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include +#ifdef BOOST_NETWORK_ENABLE_HTTPS +#include +#endif diff --git a/libs/network/src/http/client_connection_factory.cpp b/libs/network/src/http/client_connection_factory.cpp new file mode 100644 index 000000000..63f23e681 --- /dev/null +++ b/libs/network/src/http/client_connection_factory.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/client_resolver_delegate.cpp b/libs/network/src/http/client_resolver_delegate.cpp new file mode 100644 index 000000000..04b0bdd08 --- /dev/null +++ b/libs/network/src/http/client_resolver_delegate.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include From 7d932bfd0d81d4cac072245d8ced0053c1e1a7b4 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Mon, 28 Nov 2011 23:19:14 +1100 Subject: [PATCH 049/438] Updating client connection interfaces; some refactoring. --- .../http/client/client_connection.hpp | 1 + .../http/client/client_connection.ipp | 9 +- .../http/client/connection/async_normal.hpp | 8 +- .../http/client/connection/async_normal.ipp | 94 +++++++++++-------- 4 files changed, 66 insertions(+), 46 deletions(-) diff --git a/boost/network/protocol/http/client/client_connection.hpp b/boost/network/protocol/http/client/client_connection.hpp index 10556d14d..a6302ad4d 100644 --- a/boost/network/protocol/http/client/client_connection.hpp +++ b/boost/network/protocol/http/client/client_connection.hpp @@ -23,6 +23,7 @@ struct client_connection { request_base const & request, bool get_body, callback_type callback) = 0; + virtual client_connection * clone() const = 0; virtual void reset() = 0; virtual ~client_connection() = 0; }; diff --git a/boost/network/protocol/http/client/client_connection.ipp b/boost/network/protocol/http/client/client_connection.ipp index 989ad213b..ef0e147d2 100644 --- a/boost/network/protocol/http/client/client_connection.ipp +++ b/boost/network/protocol/http/client/client_connection.ipp @@ -8,11 +8,18 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include namespace boost { namespace network { namespace http { client_connection::~client_connection() { - // default implementation, for linkage only. + // For exposition only. + BOOST_ASSERT(false && "This should not ever be called."); +} + +client_connection * client_connection::clone() const { + // For exposition only. + BOOST_ASSERT(false && "This should not ever be called."); } diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index c31edba68..53e06bd81 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -19,14 +19,14 @@ namespace boost { namespace network { namespace http { struct http_async_connection_pimpl; -struct http_async_connection -: client_connection -, enable_shared_from_this { +struct http_async_connection : client_connection + , enable_shared_from_this { using client_connection::callback_type; http_async_connection(shared_ptr resolver_delegate, shared_ptr connection_delegate, asio::io_service & io_service, bool follow_redirects); + http_async_connection * clone() const; virtual response send_request(std::string const & method, request_base const & request, bool get_body, @@ -34,7 +34,7 @@ struct http_async_connection virtual void reset(); // override virtual ~http_async_connection(); private: - scoped_ptr pimpl; + shared_ptr pimpl; }; } // namespace http diff --git a/boost/network/protocol/http/client/connection/async_normal.ipp b/boost/network/protocol/http/client/connection/async_normal.ipp index 405e644c4..4d0408f5b 100644 --- a/boost/network/protocol/http/client/connection/async_normal.ipp +++ b/boost/network/protocol/http/client/connection/async_normal.ipp @@ -14,51 +14,50 @@ namespace boost { namespace network { namespace http { namespace placeholders = boost::asio::placeholders; -struct http_async_connection -: client_connection -, boost::enable_shared_from_this +struct http_async_connection_pimpl : boost::enable_shared_from_this { + http_async_connection_pimpl( + resolver_delegate_ptr resolver_delegate, + asio::io_service & io_service, + bool follow_redirect, + connection_delegate_ptr delegate) + : + follow_redirect_(follow_redirect), + request_strand_(io_service), + resolver_delegate_(resolver_delegate), + delegate_(delegate) {} - http_async_connection(resolver_delegate_ptr resolver_delegate, - asio::io_service & io_service, - bool follow_redirect, - connection_delegate_ptr delegate) - : - follow_redirect_(follow_redirect), - request_strand_(io_service), - resolver_delegate_(resolver_delegate), - delegate_(delegate) {} - - // This is the main entry point for the connection/request pipeline. We're - // overriding async_connection_base<...>::start(...) here which is called - // by the client. - virtual response start(request const & request, - string_type const & method, - bool get_body, - body_callback_function_type callback) { - response response_; - this->init_response(response_, get_body); - linearize(request, method, version_major, version_minor, - std::ostreambuf_iterator::type>(&command_streambuf)); - this->method = method; - boost::uint16_t port_ = port(request); - resolver_delegate_->resolve(host(request), - port_, - request_strand_.wrap( - boost::bind( - &this_type::handle_resolved, - this_type::shared_from_this(), - port_, - get_body, - callback, - _1, - _2))); - return response_; - } + // This is the main entry point for the connection/request pipeline. We're + // overriding async_connection_base<...>::start(...) here which is called + // by the client. + response start(request const & request, + string_type const & method, + bool get_body, + body_callback_function_type callback) { + response response_; + this->init_response(response_, get_body); + linearize(request, method, version_major, version_minor, + std::ostreambuf_iterator::type>(&command_streambuf)); + this->method = method; + boost::uint16_t port_ = port(request); + resolver_delegate_->resolve( + host(request), + port_, + request_strand_.wrap( + boost::bind( + &this_type::handle_resolved, + this_type::shared_from_this(), + port_, + get_body, + callback, + _1, + _2))); + return response_; + } -private: + private: - http_async_connection(http_async_connection const &); // = delete + http_async_connection_pimpl(http_async_connection_pimpl const &); // = delete void set_errors(boost::system::error_code const & ec) { boost::system::system_error error(ec); @@ -385,6 +384,19 @@ private: string_type method; }; +// END OF PIMPL DEFINITION + +http_async_connection::http_async_connection(shared_ptr resolver_delegate, + shared_ptr connection_delegate, + asio::io_service & io_service, + bool follow_redirects) +: pimpl(new (std::nothrow) http_async_connection_pimpl(resolver_delegate, + connection_delegate, + io_service, + follow_redirects)) +{} + +http_async_connection::http } /* http */ From 6a6875ab271e91ec99496c10cc10bdaec91a997b Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Mon, 28 Nov 2011 23:39:43 +1100 Subject: [PATCH 050/438] Mine Tripped: http::request and http::response. The thing I've been delaying for a long time already is something I now have to face. The good part about this is that there are concept requirements that I can use to keep the interface and semantics from changing. Unfortunately this also means that I need to come up with a working http::request and http::response implementation that *does the right thing* now that it's necessary. The http::http_async_normal_connection is undergoing a lot of changes especially now that the details of how the message stores the data has been abstracted out of the client. It used to be that the wiring of the promise objects and the future objects were evident in the http_async_connection implementation and the http::response objects. That was bad design and now we're going all good OOP with this implementation, which means we're going to have to hide these in the http::response implementation. This is yet another black hole I'm going to disappear in as I wire in an efficient non-std::string storage mechanism for efficient small and large payload processing in the http::response objects. The same goes for supporting streams in the http::request objects. Hang on tight, from here on out there will be a lot of changes that will pertain to the http::request and http::response implementations that may not be for the faint at heart. Cheers --- .../http/client/connection/async_normal.hpp | 1 + .../http/client/connection/async_normal.ipp | 82 ++++++++++--------- libs/network/src/CMakeLists.txt | 3 +- .../src/http/client_connection_normal.cpp | 11 +++ 4 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 libs/network/src/http/client_connection_normal.cpp diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index 53e06bd81..c4fc08e86 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/boost/network/protocol/http/client/connection/async_normal.ipp b/boost/network/protocol/http/client/connection/async_normal.ipp index 4d0408f5b..5f5ad5077 100644 --- a/boost/network/protocol/http/client/connection/async_normal.ipp +++ b/boost/network/protocol/http/client/connection/async_normal.ipp @@ -9,6 +9,8 @@ #include #include +#include +#include namespace boost { namespace network { namespace http { @@ -16,28 +18,31 @@ namespace placeholders = boost::asio::placeholders; struct http_async_connection_pimpl : boost::enable_shared_from_this { + typedef http_async_connection::callback_type body_callback_function_type; + typedef resolver_delegate::resolver_iterator resolver_iterator; + typedef resolver_delegate::iterator_pair resolver_iterator_pair; + http_async_connection_pimpl( - resolver_delegate_ptr resolver_delegate, + shared_ptr resolver_delegate, + shared_ptr connection_delegate, asio::io_service & io_service, - bool follow_redirect, - connection_delegate_ptr delegate) + bool follow_redirect) : follow_redirect_(follow_redirect), request_strand_(io_service), resolver_delegate_(resolver_delegate), - delegate_(delegate) {} + connection_delegate_(connection_delegate) {} // This is the main entry point for the connection/request pipeline. We're // overriding async_connection_base<...>::start(...) here which is called // by the client. response start(request const & request, - string_type const & method, + std::string const & method, bool get_body, body_callback_function_type callback) { response response_; - this->init_response(response_, get_body); - linearize(request, method, version_major, version_minor, - std::ostreambuf_iterator::type>(&command_streambuf)); + linearize(request, method, 1, 1, + std::ostreambuf_iterator(&command_streambuf)); this->method = method; boost::uint16_t port_ = port(request); resolver_delegate_->resolve( @@ -61,13 +66,14 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisversion_promise.set_exception(boost::copy_exception(error)); - this->status_promise.set_exception(boost::copy_exception(error)); - this->status_message_promise.set_exception(boost::copy_exception(error)); - this->headers_promise.set_exception(boost::copy_exception(error)); - this->source_promise.set_exception(boost::copy_exception(error)); - this->destination_promise.set_exception(boost::copy_exception(error)); - this->body_promise.set_exception(boost::copy_exception(error)); + // FIXME: Wire up the response object for errors. +// this->version_promise.set_exception(boost::copy_exception(error)); +// this->status_promise.set_exception(boost::copy_exception(error)); +// this->status_message_promise.set_exception(boost::copy_exception(error)); +// this->headers_promise.set_exception(boost::copy_exception(error)); +// this->source_promise.set_exception(boost::copy_exception(error)); +// this->destination_promise.set_exception(boost::copy_exception(error)); +// this->body_promise.set_exception(boost::copy_exception(error)); } void handle_resolved(boost::uint16_t port, @@ -80,7 +86,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisendpoint().address(), port); - delegate_->connect(endpoint, + connection_delegate_->connect(endpoint, request_strand_.wrap( boost::bind( &this_type::handle_connected, @@ -102,8 +108,8 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thiswrite(command_streambuf, + BOOST_ASSERT(connection_delegate_.get() != 0); + connection_delegate_->write(command_streambuf, request_strand_.wrap( boost::bind( &this_type::handle_sent_request, @@ -116,7 +122,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisendpoint().address(), port); - delegate_->connect(endpoint, + connection_delegate_->connect(endpoint, request_strand_.wrap( boost::bind( &this_type::handle_connected, @@ -142,7 +148,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisread_some( + connection_delegate_->read_some( boost::asio::mutable_buffers_1(this->part.c_array(), this->part.size()), request_strand_.wrap( @@ -163,7 +169,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_version(delegate_, + this->parse_version(connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -175,7 +181,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_status(delegate_, + this->parse_status(connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -187,7 +193,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_status_message(delegate_, + this->parse_status_message(connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -205,7 +211,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_headers(delegate_, + this->parse_headers(connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -251,7 +257,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisread_some( + connection_delegate_->read_some( boost::asio::mutable_buffers_1(this->part.c_array(), this->part.size()), request_strand_.wrap( @@ -266,7 +272,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_body( - delegate_, + connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -295,7 +301,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thispartial_parsed); body_string.append( this->part.begin() @@ -319,7 +325,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisread_some( + connection_delegate_->read_some( boost::asio::mutable_buffers_1( this->part.c_array(), this->part.size()), @@ -337,7 +343,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_body(delegate_, + this->parse_body(connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -360,16 +366,16 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisdestination_promise.set_exception(boost::copy_exception(error)); switch (state) { case version: - this->version_promise.set_exception(boost::copy_exception(error)); +// this->version_promise.set_exception(boost::copy_exception(error)); case status: - this->status_promise.set_exception(boost::copy_exception(error)); +// this->status_promise.set_exception(boost::copy_exception(error)); case status_message: - this->status_message_promise.set_exception(boost::copy_exception(error)); +// this->status_message_promise.set_exception(boost::copy_exception(error)); case headers: - this->headers_promise.set_exception(boost::copy_exception(error)); +// this->headers_promise.set_exception(boost::copy_exception(error)); case body: - this->body_promise.set_exception(boost::copy_exception(error)); - break; +// this->body_promise.set_exception(boost::copy_exception(error)); +// break; default: BOOST_ASSERT(false && "Bug, report this to the developers!"); } @@ -378,10 +384,10 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this resolver_delegate_; + shared_ptr connection_delegate_; boost::asio::streambuf command_streambuf; - string_type method; + std::string method; }; // END OF PIMPL DEFINITION diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index 293fa90d8..a231213e9 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -37,7 +37,8 @@ set(CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS http/client_resolver_delegate_factory.cpp http/client_connection_delegates.cpp http/client_connection_factory.cpp - http/client_async_resolver.cpp) + http/client_async_resolver.cpp + http/client_connection_normal.cpp) add_library(cppnetlib-http-client-connections ${CPP-NETLIB_HTTP_CLIENT_CONNECTIONS_SRCS}) set(CPP-NETLIB_HTTP_CLIENT_SRCS diff --git a/libs/network/src/http/client_connection_normal.cpp b/libs/network/src/http/client_connection_normal.cpp new file mode 100644 index 000000000..48b8ac7c4 --- /dev/null +++ b/libs/network/src/http/client_connection_normal.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include From a573a4cc9491083045debe8b54ef853fe391b218 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Thu, 1 Dec 2011 17:37:43 +1100 Subject: [PATCH 051/438] Updating the Concepts. Due to the changes in the interfaces and removal for the requirement of static tag-based dispatch, the concepts had to be updated to reflect the now minimal requirements. This applies to the Message concept and the ClientRequest and ServerRequest concepts. For the same reason the modifiers for HTTP messages had to be updated to reflect the interface. Same goes for the wrappers that deal specifically with HTTP request objects. The steps taken here will allow for more forward progress in making the library more modular. Extension at a later time may require membership in the hierarchy but this should make it more familiar using OOP techniques. If it proves useful the wrappers, modifiers, and directives can be written in a generic approach -- the meat though of the message types would benefit from having a dynamic implementation for preserving binary compatibility. --- boost/network/message/message_concept.hpp | 17 ++++--- boost/network/message/modifiers.hpp | 17 +++++++ .../http/client/connection/async_resolver.ipp | 1 + .../connection/simple_connection_factory.ipp | 1 + .../http/client/simple_connection_manager.ipp | 4 +- .../protocol/http/message/directives.hpp | 16 +++++++ .../protocol/http/message/modifiers.hpp | 16 +++++++ .../protocol/http/message/modifiers/uri.hpp | 15 ++++--- .../protocol/http/message/wrappers.hpp | 24 ++++++++++ .../protocol/http/message/wrappers/anchor.hpp | 35 ++++++--------- .../protocol/http/message/wrappers/host.hpp | 41 ++++++----------- .../protocol/http/message/wrappers/path.hpp | 41 ++++++----------- .../protocol/http/message/wrappers/port.hpp | 45 ++++++------------- .../http/message/wrappers/protocol.hpp | 35 ++++++--------- .../protocol/http/message/wrappers/query.hpp | 42 ++++++----------- .../protocol/http/message/wrappers/uri.hpp | 12 ++--- .../network/protocol/http/request/request.hpp | 24 ++++++++++ .../protocol/http/request/request_concept.hpp | 39 +++++++--------- 18 files changed, 222 insertions(+), 203 deletions(-) create mode 100644 boost/network/message/modifiers.hpp create mode 100644 boost/network/protocol/http/message/directives.hpp create mode 100644 boost/network/protocol/http/message/modifiers.hpp create mode 100644 boost/network/protocol/http/message/wrappers.hpp diff --git a/boost/network/message/message_concept.hpp b/boost/network/message/message_concept.hpp index 2016c806f..d3731f3e1 100644 --- a/boost/network/message/message_concept.hpp +++ b/boost/network/message/message_concept.hpp @@ -13,14 +13,13 @@ #include #include #include +#include namespace boost { namespace network { template struct Message : DefaultConstructible, CopyConstructible, Assignable { - typedef typename M::string_type string_type; - typedef typename M::headers_container_type headers_container_type; BOOST_CONCEPT_USAGE(Message) { M message_; @@ -31,18 +30,18 @@ namespace boost { namespace network { typedef std::string header_key_type; typedef std::string header_value_type; - headers_container_type headers_ = headers(message); - string_type body_ = body(message); - string_type source_ = source(message); - string_type destination_ = destination(message); + std::multimap headers_ = headers(message); + std::string body_ = body(message); + std::string source_ = source(message); + std::string destination_ = destination(message); message << source(source_type()) << destination(destination_type()) - << header(string_type(), string_type()) + << header(std::string(), std::string()) << body(body_type()); - add_header(message, string_type(), string_type()); - remove_header(message, string_type()); + add_header(message, std::string(), std::string()); + remove_header(message, std::string()); clear_headers(message); source(message, source_type()); destination(message, destination_type()); diff --git a/boost/network/message/modifiers.hpp b/boost/network/message/modifiers.hpp new file mode 100644 index 000000000..95e998044 --- /dev/null +++ b/boost/network/message/modifiers.hpp @@ -0,0 +1,17 @@ +#ifndef BOOST_NETWORK_MESSAGE_MODIFIERS_HPP_20111201 +#define BOOST_NETWORK_MESSAGE_MODIFIERS_HPP_20111201 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_MESSAGE_MODIFIERS_HPP_20111201 diff --git a/boost/network/protocol/http/client/connection/async_resolver.ipp b/boost/network/protocol/http/client/connection/async_resolver.ipp index 90d980ed6..e5dad6151 100644 --- a/boost/network/protocol/http/client/connection/async_resolver.ipp +++ b/boost/network/protocol/http/client/connection/async_resolver.ipp @@ -20,6 +20,7 @@ #include #include #include +#include #include namespace boost { namespace network { namespace http { diff --git a/boost/network/protocol/http/client/connection/simple_connection_factory.ipp b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp index 41eeea9ba..f271e6e1b 100644 --- a/boost/network/protocol/http/client/connection/simple_connection_factory.ipp +++ b/boost/network/protocol/http/client/connection/simple_connection_factory.ipp @@ -37,6 +37,7 @@ struct simple_connection_factory_pimpl { service, https, openssl_certificate, openssl_verify_path), service, follow_redirects)); + return conn_; } private: diff --git a/boost/network/protocol/http/client/simple_connection_manager.ipp b/boost/network/protocol/http/client/simple_connection_manager.ipp index e8042c374..8f65b215d 100644 --- a/boost/network/protocol/http/client/simple_connection_manager.ipp +++ b/boost/network/protocol/http/client/simple_connection_manager.ipp @@ -17,7 +17,7 @@ struct simple_connection_manager_pimpl { optional openssl_certificate, optional openssl_verify_path, shared_ptr connection_factory) - : cache_resolved_(cache_resolved_) + : cache_resolved_(cache_resolved) , follow_redirects_(follow_redirects) , openssl_certificate_(openssl_certificate) , openssl_verify_path_(openssl_verify_path) @@ -29,7 +29,7 @@ struct simple_connection_manager_pimpl { std::string const & openssl_certificate, std::string const & openssl_verify_path, shared_ptr connection_factory) - : cache_resolved_(cache_resolved_) + : cache_resolved_(cache_resolved) , follow_redirects_(follow_redirects) , openssl_certificate_(openssl_certificate) , openssl_verify_path_(openssl_verify_path) diff --git a/boost/network/protocol/http/message/directives.hpp b/boost/network/protocol/http/message/directives.hpp new file mode 100644 index 000000000..a923e716f --- /dev/null +++ b/boost/network/protocol/http/message/directives.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_HPP_20111201 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_HPP_20111201 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_HPP_20111201 diff --git a/boost/network/protocol/http/message/modifiers.hpp b/boost/network/protocol/http/message/modifiers.hpp new file mode 100644 index 000000000..e14a3ff0a --- /dev/null +++ b/boost/network/protocol/http/message/modifiers.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_HPP_20111201 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_HPP_20111201 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_HPP_20111201 diff --git a/boost/network/protocol/http/message/modifiers/uri.hpp b/boost/network/protocol/http/message/modifiers/uri.hpp index e96525df5..298ffb4fa 100644 --- a/boost/network/protocol/http/message/modifiers/uri.hpp +++ b/boost/network/protocol/http/message/modifiers/uri.hpp @@ -3,21 +3,22 @@ // Copyright 2010 (c) Dean Michael Berris // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { namespace http { - template - struct basic_request; +inline void uri(request_base & request, std::string const & value) { + request.set_uri(value); +} - template - void uri(basic_request & request, T const & value) { - request.uri(value); - } +inline void uri(request_base & request, uri::uri const & value) { + request.set_uri(value); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers.hpp b/boost/network/protocol/http/message/wrappers.hpp new file mode 100644 index 000000000..cc75c9e32 --- /dev/null +++ b/boost/network/protocol/http/message/wrappers.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HPP_20111201 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HPP_20111201 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HPP_20111201 diff --git a/boost/network/protocol/http/message/wrappers/anchor.hpp b/boost/network/protocol/http/message/wrappers/anchor.hpp index 4a6e85f15..7a23b74c5 100644 --- a/boost/network/protocol/http/message/wrappers/anchor.hpp +++ b/boost/network/protocol/http/message/wrappers/anchor.hpp @@ -3,33 +3,26 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + namespace boost { namespace network { namespace http { - template - struct basic_request; - - namespace impl { - template - struct anchor_wrapper { - basic_request const & message_; - anchor_wrapper(basic_request const & message) - : message_(message) {} - typedef typename basic_request::string_type string_type; - operator string_type() { - return message_.anchor(); - } - }; - } - - template inline - impl::anchor_wrapper - anchor(basic_request const & request) { - return impl::anchor_wrapper(request); - } +struct anchor_wrapper { + explicit anchor_wrapper(request_base const & request); + operator std::string () const; + private: + request_base const & request_; +}; + +inline anchor_wrapper const +anchor(request_base const & request) { + return anchor_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/host.hpp b/boost/network/protocol/http/message/wrappers/host.hpp index 876beb352..0b33511d4 100644 --- a/boost/network/protocol/http/message/wrappers/host.hpp +++ b/boost/network/protocol/http/message/wrappers/host.hpp @@ -3,39 +3,26 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -namespace boost { namespace network { namespace http { - - template - struct basic_request; - - namespace impl { - - template - struct host_wrapper { - basic_request const & message_; +#include - host_wrapper(basic_request const & message) - : message_(message) {} - - typedef typename basic_request::string_type string_type; - - operator string_type() { - return message_.host(); - } - }; - - } +namespace boost { namespace network { namespace http { - template - inline - impl::host_wrapper - host(basic_request const & request) { - return impl::host_wrapper(request); - } +struct host_wrapper { + explicit host_wrapper(request_base const & request); + operator std::string () const; + private: + request_base const & request_; +}; + +inline host_wrapper const +host(request_base const & request) { + return host_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/path.hpp b/boost/network/protocol/http/message/wrappers/path.hpp index 818b55c2f..8adfe608d 100644 --- a/boost/network/protocol/http/message/wrappers/path.hpp +++ b/boost/network/protocol/http/message/wrappers/path.hpp @@ -3,39 +3,26 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -namespace boost { namespace network { namespace http { - - template - struct basic_request; - - namespace impl { - - template - struct path_wrapper { - basic_request const & message_; +#include - path_wrapper(basic_request const & message) - : message_(message) {} - - typedef typename basic_request::string_type string_type; - - operator string_type() { - return message_.path(); - } - }; - - } +namespace boost { namespace network { namespace http { - template - inline - impl::path_wrapper - path(basic_request const & request) { - return impl::path_wrapper(request); - } +struct path_wrapper { + explicit path_wrapper(request_base const & request); + operator std::string () const; + private: + request_base const & request_; +}; + +inline path_wrapper const +path(request_base const & request) { + return path_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/port.hpp b/boost/network/protocol/http/message/wrappers/port.hpp index 786ce1e98..b74204da7 100644 --- a/boost/network/protocol/http/message/wrappers/port.hpp +++ b/boost/network/protocol/http/message/wrappers/port.hpp @@ -3,45 +3,28 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include namespace boost { namespace network { namespace http { - template - struct basic_request; - - namespace impl { - - template - struct port_wrapper { - basic_request const & message_; - - port_wrapper(basic_request const & message) - : message_(message) {} - - typedef typename basic_request::port_type port_type; - - operator port_type() { - return message_.port(); - } - - operator boost::optional () { - return uri::port_us(message_.uri()); - } - }; - - } // namespace impl - - template - inline - impl::port_wrapper - port(basic_request const & request) { - return impl::port_wrapper(request); - } +struct port_wrapper { + port_wrapper(request_base const & request); + operator boost::uint16_t () const; + operator boost::optional () const; + private: + request_base const & message_; +}; + +inline port_wrapper const +port(request_base const & request) { + return port_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/protocol.hpp b/boost/network/protocol/http/message/wrappers/protocol.hpp index bca206c68..0a069fe4a 100644 --- a/boost/network/protocol/http/message/wrappers/protocol.hpp +++ b/boost/network/protocol/http/message/wrappers/protocol.hpp @@ -3,33 +3,26 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + namespace boost { namespace network { namespace http { - template - struct basic_request; - - namespace impl { - template - struct protocol_wrapper { - basic_request const & message_; - protocol_wrapper(basic_request const & message) - : message_(message) {} - typedef typename basic_request::string_type string_type; - operator string_type() { - return message_.protocol(); - } - }; - } - - template inline - impl::protocol_wrapper - protocol(basic_request const & request) { - return impl::protocol_wrapper(request); - } +struct protocol_wrapper { + explicit protocol_wrapper(request_base const & request); + operator std::string () const; + private: + request_base const & request_; +}; + +inline protocol_wrapper const +protocol(request_base const & request) { + return protocol_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/query.hpp b/boost/network/protocol/http/message/wrappers/query.hpp index 594e6720f..d3f04e157 100644 --- a/boost/network/protocol/http/message/wrappers/query.hpp +++ b/boost/network/protocol/http/message/wrappers/query.hpp @@ -3,40 +3,26 @@ // Copyright 2010 (c) Dean Michael Berris. // Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Google, Inc. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -namespace boost { namespace network { namespace http { - - template - struct basic_request; - - namespace impl { - - template - struct query_wrapper { - basic_request const & message_; +#include - query_wrapper(basic_request const & message) - : message_(message) {} - - typedef typename basic_request::string_type string_type; - - operator string_type () { - return message_.query(); - } - - }; - - } // namespace impl +namespace boost { namespace network { namespace http { - template - inline - impl::query_wrapper - query(basic_request const & request) { - return impl::query_wrapper(request); - } +struct query_wrapper { + explicit query_wrapper(request_base const & request); + operator std::string () const; + private: + request_base const & request_; +}; + +inline query_wrapper const +query(request_base const & request) { + return query_wrapper(request); +} } // namespace http diff --git a/boost/network/protocol/http/message/wrappers/uri.hpp b/boost/network/protocol/http/message/wrappers/uri.hpp index 505ebc078..191bbf9af 100644 --- a/boost/network/protocol/http/message/wrappers/uri.hpp +++ b/boost/network/protocol/http/message/wrappers/uri.hpp @@ -12,22 +12,18 @@ namespace boost { namespace network { namespace http { -namespace impl { - struct uri_wrapper { - explicit uri_wrapper(request_base & request_); + explicit uri_wrapper(request_base const & request_); operator std::string() const; operator boost::network::uri::uri() const; private: request_base & request_; }; -} // namespace impl - inline -impl::uri_wrapper -uri(request_base & request) { - return impl::uri_wrapper(request); +uri_wrapper const +uri(request_base const & request) { + return uri_wrapper(request); } } // namespace http diff --git a/boost/network/protocol/http/request/request.hpp b/boost/network/protocol/http/request/request.hpp index eb01a25d9..549aefeca 100644 --- a/boost/network/protocol/http/request/request.hpp +++ b/boost/network/protocol/http/request/request.hpp @@ -8,6 +8,8 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include +#include namespace boost { namespace network { namespace http { @@ -16,6 +18,14 @@ struct request_pimpl; struct request : request_base { // FIXME Implement all these! + // We support full value semantics. + request(); + explicit request(std::string url); + explicit request(uri::uri url); + request(request const &); + request& operator=(request); + void swap(request & other); + // From message_base... // Mutators virtual void set_destination(std::string const & destination); @@ -65,6 +75,10 @@ request_base & operator<< (request_base & request, return request; } +inline void swap(request &l, request &r) { + l.swap(r); +} + } // namespace http } // namespace network @@ -75,5 +89,15 @@ request_base & operator<< (request_base & request, #include #endif +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_NETWORK_DEBUG +BOOST_CONCEPT_ASSERT((boost::network::http::ClientRequest)); +#endif #endif /* BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_REQUEST_HPP_20111021 */ diff --git a/boost/network/protocol/http/request/request_concept.hpp b/boost/network/protocol/http/request/request_concept.hpp index 5b0ee99eb..e868b3a31 100644 --- a/boost/network/protocol/http/request/request_concept.hpp +++ b/boost/network/protocol/http/request/request_concept.hpp @@ -12,21 +12,19 @@ #include #include #include +#include +#include namespace boost { namespace network { namespace http { template struct ServerRequest { - typedef typename R::string_type string_type; - typedef typename R::tag tag; - typedef typename R::headers_container_type headers_container_type; - BOOST_CONCEPT_USAGE(ServerRequest) { - string_type source_, method_, destination_; + std::string source_, method_, destination_; boost::uint8_t major_version_, minor_version_; - headers_container_type headers_; - string_type body_; + std::multimap headers_; + std::string body_; source_ = source(request); method_ = method(request); @@ -42,12 +40,12 @@ namespace boost { namespace network { namespace http { major_version(request, major_version_); minor_version(request, minor_version_); headers(request, headers_); - add_header(request, string_type(), string_type()); - remove_header(request, string_type()); + add_header(request, std::string(), std::string()); + remove_header(request, std::string()); clear_headers(request); body(request, body_); - string_type name, value; + std::string name, value; request << ::boost::network::source(source_) << ::boost::network::destination(destination_) @@ -70,24 +68,21 @@ namespace boost { namespace network { namespace http { struct ClientRequest : boost::network::Message { - typedef typename R::string_type string_type; - typedef typename R::port_type port_type; - BOOST_CONCEPT_USAGE(ClientRequest) { - string_type tmp; + std::string tmp; R request_(tmp); swap(request, request_); // swappable via ADL - string_type host_ = host(request); - port_type port_ = port(request); - string_type path_ = path(request); - string_type query_ = query(request); - string_type anchor_ = anchor(request); - string_type protocol_ = protocol(request); + std::string host_ = host(request); + boost::uint16_t port_ = port(request); + std::string path_ = path(request); + std::string query_ = query(request); + std::string anchor_ = anchor(request); + std::string protocol_ = protocol(request); - request << uri(string_type()); + request << uri(std::string()); - boost::network::http::uri(request, string_type()); + boost::network::http::uri(request, std::string()); (void)host_; (void)port_; From 891c29fd70353095c5e7a920fe8616800571167b Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 3 Dec 2011 01:09:39 +1100 Subject: [PATCH 052/438] HTTP Connections Building. After a few changes to the core body and headers wrappers in the message implementation and the request linearization algorithm (to fix a bug that makes the implementation not rely on the concept constraints) the asynchronous HTTP connection implementation now compiles! The bad news here is that the async_normal implementation still needs to be cleaned up as much of the work here involved moving the protocol_handler implementation into the actual connection implementation. There's still a lot to do here to make the code more readable which may mean just more documentation -- which I will be very happy with as soon as things settle down. This commit also limits the accessibility of the response field setting interface that deals with futures and promises. Along with it is the fix for the incremental parser's mis-handling of the edge case where the range passed to the parse_until function is actually empty. --- boost/network/message/wrappers/body.hpp | 6 +- boost/network/message/wrappers/headers.hpp | 14 +- .../protocol/http/algorithms/linearize.hpp | 42 +- .../http/client/connection/async_normal.ipp | 380 ++++++++++++- .../connection/async_protocol_handler.hpp | 50 +- boost/network/protocol/http/impl/access.hpp | 40 ++ boost/network/protocol/http/impl/access.ipp | 45 ++ .../protocol/http/parser/incremental.hpp | 498 +++++++++--------- .../protocol/http/response/response.hpp | 23 + 9 files changed, 770 insertions(+), 328 deletions(-) create mode 100644 boost/network/protocol/http/impl/access.hpp create mode 100644 boost/network/protocol/http/impl/access.ipp diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index cf0b37d78..2a76497f9 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -16,14 +16,14 @@ namespace boost { namespace network { namespace impl { struct body_wrapper { - explicit body_wrapper(message_base & message); + explicit body_wrapper(message_base const & message); operator std::string () const; std::size_t size() const; operator iterator_range () const; std::string::const_iterator begin() const; std::string::const_iterator end() const; private: - message_base & message_; + message_base const & message_; mutable optional cache_; }; @@ -35,7 +35,7 @@ inline std::ostream & operator<<(std::ostream & os, body_wrapper const & body) { } // namespace impl inline impl::body_wrapper const -body(message_base & message_) { +body(message_base const & message_) { return impl::body_wrapper(message_); } diff --git a/boost/network/message/wrappers/headers.hpp b/boost/network/message/wrappers/headers.hpp index ba71860eb..a7a44aeae 100644 --- a/boost/network/message/wrappers/headers.hpp +++ b/boost/network/message/wrappers/headers.hpp @@ -15,8 +15,6 @@ namespace boost { namespace network { -namespace impl { - /** headers wrapper for messages. * * This exposes an interface similar to a map, indexable @@ -30,7 +28,7 @@ struct headers_wrapper { typedef shared_container_iterator iterator; typedef iterator_range range_type; - explicit headers_wrapper(message_base & message); + explicit headers_wrapper(message_base const & message); range_type operator[] (std::string const & key) const; operator range_type () const; operator container_type () const; @@ -40,16 +38,14 @@ struct headers_wrapper { iterator end() const; private: void init_cache_all() const; - message_base & message_; + message_base const & message_; mutable shared_ptr cache_; }; -} // namespace impl - /// Factory method to create the right wrapper object -inline impl::headers_wrapper const -headers(message_base & message_) { - return impl::headers_wrapper(message_); +inline headers_wrapper const +headers(message_base const & message_) { + return headers_wrapper(message_); } } // namespace network diff --git a/boost/network/protocol/http/algorithms/linearize.hpp b/boost/network/protocol/http/algorithms/linearize.hpp index f109640b2..6c2a66b66 100644 --- a/boost/network/protocol/http/algorithms/linearize.hpp +++ b/boost/network/protocol/http/algorithms/linearize.hpp @@ -49,7 +49,7 @@ namespace boost { namespace network { namespace http { (OutputIterator) ) linearize( Request const & request, - typename Request::string_type const & method, + std::string const & method, unsigned version_major, unsigned version_minor, OutputIterator oi @@ -64,22 +64,31 @@ namespace boost { namespace network { namespace http { , accept_encoding = consts::accept_encoding() , default_accept_encoding = consts::default_accept_encoding() , crlf = consts::crlf() - , host = consts::host() + , host_const = consts::host() , connection = consts::connection() , close = consts::close() ; boost::copy(method, oi); *oi = consts::space_char(); - if (request.path().empty() || request.path()[0] != consts::slash_char()) - *oi = consts::slash_char(); - boost::copy(request.path(), oi); - if (!request.query().empty()) { - *oi = consts::question_mark_char(); - boost::copy(request.query(), oi); + { + std::string path_ = path(request); + if (path_.empty() || path_[0] != consts::slash_char()) + *oi = consts::slash_char(); + boost::copy(path_, oi); } - if (!request.anchor().empty()) { + { + std::string query_ = query(request); + if (!query_.empty()) { + *oi = consts::question_mark_char(); + boost::copy(query_, oi); + } + } + { + std::string anchor_ = anchor(request); + if (!anchor_.empty()) { *oi = consts::hash_char(); - boost::copy(request.anchor(), oi); + boost::copy(anchor_, oi); + } } *oi = consts::space_char(); boost::copy(http_slash, oi); @@ -89,10 +98,13 @@ namespace boost { namespace network { namespace http { *oi = consts::dot_char(); boost::copy(version_minor_str, oi); boost::copy(crlf, oi); - boost::copy(host, oi); + boost::copy(host_const, oi); *oi = consts::colon_char(); *oi = consts::space_char(); - boost::copy(request.host(), oi); + { + std::string host_ = host(request); + boost::copy(host_, oi); + } boost::optional port_ = port(request); if (port_) { string_type port_str = boost::lexical_cast(*port_); @@ -112,9 +124,9 @@ namespace boost { namespace network { namespace http { boost::copy(default_accept_encoding, oi); boost::copy(crlf, oi); } - typedef boost::iterator_range::const_iterator> headers_range; + typedef headers_wrapper::range_type headers_range; typedef typename range_iterator::type headers_iterator; - headers_range request_headers = headers(request); + headers_range request_headers = boost::network::headers(request); headers_iterator iterator = boost::begin(request_headers), end = boost::end(request_headers); for (; iterator != end; ++iterator) { @@ -128,7 +140,7 @@ namespace boost { namespace network { namespace http { } boost::copy(crlf, oi); boost::iterator_range body_data = - body(request); + boost::network::body(request); return boost::copy(body_data, oi); } diff --git a/boost/network/protocol/http/client/connection/async_normal.ipp b/boost/network/protocol/http/client/connection/async_normal.ipp index 5f5ad5077..e57e8b016 100644 --- a/boost/network/protocol/http/client/connection/async_normal.ipp +++ b/boost/network/protocol/http/client/connection/async_normal.ipp @@ -9,8 +9,11 @@ #include #include +#include #include +#include #include +#include namespace boost { namespace network { namespace http { @@ -21,6 +24,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this resolver_delegate, @@ -41,6 +45,10 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisinit_response(response_); + // Use HTTP/1.1 -- at some point we might want to implement a different + // connection type just for HTTP/1.0. + // TODO: Implement a different connection type and factory for HTTP/1.0. linearize(request, method, 1, 1, std::ostreambuf_iterator(&command_streambuf)); this->method = method; @@ -64,16 +72,26 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thissource_promise = accessor.get_source_promise(r); + this->destination_promise = accessor.get_destination_promise(r); + this->headers_promise = accessor.get_headers_promise(r); + this->body_promise = accessor.get_body_promise(r); + this->version_promise = accessor.get_version_promise(r); + this->status_promise = accessor.get_status_promise(r); + this->status_message_promise = accessor.get_status_message_promise(r); + } + void set_errors(boost::system::error_code const & ec) { boost::system::system_error error(ec); - // FIXME: Wire up the response object for errors. -// this->version_promise.set_exception(boost::copy_exception(error)); -// this->status_promise.set_exception(boost::copy_exception(error)); -// this->status_message_promise.set_exception(boost::copy_exception(error)); -// this->headers_promise.set_exception(boost::copy_exception(error)); -// this->source_promise.set_exception(boost::copy_exception(error)); -// this->destination_promise.set_exception(boost::copy_exception(error)); -// this->body_promise.set_exception(boost::copy_exception(error)); + this->version_promise.set_exception(boost::copy_exception(error)); + this->status_promise.set_exception(boost::copy_exception(error)); + this->status_message_promise.set_exception(boost::copy_exception(error)); + this->headers_promise.set_exception(boost::copy_exception(error)); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + this->body_promise.set_exception(boost::copy_exception(error)); } void handle_resolved(boost::uint16_t port, @@ -169,8 +187,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_version(connection_delegate_, - request_strand_.wrap( + this->parse_version(request_strand_.wrap( boost::bind( &this_type::handle_received_data, this_type::shared_from_this(), @@ -181,8 +198,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_status(connection_delegate_, - request_strand_.wrap( + this->parse_status(request_strand_.wrap( boost::bind( &this_type::handle_received_data, this_type::shared_from_this(), @@ -193,7 +209,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_status_message(connection_delegate_, + this->parse_status_message( request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -211,7 +227,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_headers(connection_delegate_, + this->parse_headers( request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -243,8 +259,8 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thispart_begin; - typename protocol_base::buffer_type::const_iterator end = begin; + buffer_type::const_iterator begin = this->part_begin; + buffer_type::const_iterator end = begin; std::advance(end, remainder); // We're setting the body promise here to an empty string because @@ -272,7 +288,6 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_body( - connection_delegate_, request_strand_.wrap( boost::bind( &this_type::handle_received_data, @@ -291,7 +306,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thispart.begin(), end = begin; std::advance(end, bytes_transferred); @@ -321,8 +336,8 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thispart.begin(); - typename protocol_base::buffer_type::const_iterator end = begin; + buffer_type::const_iterator begin = this->part.begin(); + buffer_type::const_iterator end = begin; std::advance(end, bytes_transferred); callback(make_iterator_range(begin, end), ec); connection_delegate_->read_some( @@ -343,8 +358,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisparse_body(connection_delegate_, - request_strand_.wrap( + this->parse_body(request_strand_.wrap( boost::bind( &this_type::handle_received_data, this_type::shared_from_this(), @@ -382,12 +396,330 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this(input); + string.append(escaped_stream.str()); + } + } else { + string.push_back(input); + } + } + }; +#endif + + struct to_http_headers { + template + std::string const operator() (U const & pair) const { + std::ostringstream header_line; + header_line << pair.first + << constants::colon() + << constants::space() + << pair.second + << constants::crlf(); + return header_line.str(); + } + }; + + logic::tribool parse_version( + function callback, + size_t bytes) { + logic::tribool parsed_ok; + part_begin = part.begin(); + buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser::http_version_done, + input_range); + if (parsed_ok == true) { + std::string version; + std::swap(version, partial_parsed); + version.append(boost::begin(result_range), + boost::end(result_range)); + algorithm::trim(version); + version_promise.set_value(version); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + std::string escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" + << response_parser_.state() + << "] buffer contents: \"" + << escaped + << "\""); +#endif + std::runtime_error error("Invalid Version Part."); + version_promise.set_exception(boost::copy_exception(error)); + status_promise.set_exception(boost::copy_exception(error)); + status_message_promise.set_exception( + boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append( + boost::begin(result_range), + boost::end(result_range) + ); + part_begin = part.begin(); + connection_delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback + ); + } + return parsed_ok; + } + + logic::tribool parse_status( + function callback, + size_t bytes) { + logic::tribool parsed_ok; + buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + boost::iterator_range< buffer_type::const_iterator> + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser::http_status_done, + input_range); + if (parsed_ok == true) { + std::string status; + std::swap(status, partial_parsed); + status.append(boost::begin(result_range), + boost::end(result_range)); + trim(status); + boost::uint16_t status_int = + lexical_cast(status); + status_promise.set_value(status_int); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + std::string escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" + << response_parser_.state() + << "] buffer contents: \"" + << escaped + << "\""); +#endif + std::runtime_error error("Invalid status part."); + status_promise.set_exception(boost::copy_exception(error)); + status_message_promise.set_exception( + boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append( + boost::begin(result_range), + boost::end(result_range) + ); + part_begin = part.begin(); + connection_delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback + ); + } + return parsed_ok; + } + + logic::tribool parse_status_message( + function callback, + size_t bytes) { + logic::tribool parsed_ok; + buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + boost::iterator_range< buffer_type::const_iterator> + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser::http_status_message_done, + input_range); + if (parsed_ok == true) { + std::string status_message; + std::swap(status_message, partial_parsed); + status_message.append(boost::begin(result_range), + boost::end(result_range)); + algorithm::trim(status_message); + status_message_promise.set_value(status_message); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + std::string escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" + << response_parser_.state() + << "] buffer contents: \"" + << escaped + << "\""); +#endif + std::runtime_error error("Invalid status message part."); + status_message_promise.set_exception( + boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append( + boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + connection_delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback + ); + } + return parsed_ok; + } + + void parse_headers_real(std::string & headers_part) { + boost::iterator_range< std::string::const_iterator> + input_range = boost::make_iterator_range(headers_part) + , result_range; + logic::tribool parsed_ok; + response_parser headers_parser( + response_parser::http_header_line_done); + std::multimap headers; + std::pair header_pair; + while (!boost::empty(input_range)) { + fusion::tie(parsed_ok, result_range) = + headers_parser.parse_until( + response_parser::http_header_colon, + input_range); + if (headers_parser.state() + != response_parser::http_header_colon) + break; + header_pair.first = std::string(boost::begin(result_range), + boost::end(result_range)); + input_range.advance_begin(boost::distance(result_range)); + fusion::tie(parsed_ok, result_range) = + headers_parser.parse_until( + response_parser::http_header_line_done, + input_range); + header_pair.second = std::string(boost::begin(result_range), + boost::end(result_range)); + input_range.advance_begin(boost::distance(result_range)); + + trim(header_pair.first); + if (header_pair.first.size() > 1) { + header_pair.first.erase( + header_pair.first.size() - 1 + ); + } + trim(header_pair.second); + headers.insert(header_pair); + } + headers_promise.set_value(headers); + } + + fusion::tuple parse_headers( + function callback, + size_t bytes) { + logic::tribool parsed_ok; + buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser::http_headers_done, + input_range); + if (parsed_ok == true) { + std::string headers_string; + std::swap(headers_string, partial_parsed); + headers_string.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = boost::end(result_range); + this->parse_headers_real(headers_string); + } else if (parsed_ok == false) { + // We want to output the contents of the buffer that caused + // the error in debug builds. +#ifdef BOOST_NETWORK_DEBUG + std::string escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" + << response_parser_.state() + << "] buffer contents: \"" + << escaped + << "\" consumed length: " + << boost::distance(result_range)); +#endif + std::runtime_error error("Invalid header part."); + headers_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + connection_delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback + ); + } + return fusion::make_tuple( + parsed_ok, + std::distance( + boost::end(result_range) + , part_end + ) + ); + } + + void parse_body(function callback, size_t bytes) { + // TODO: we should really not use a string for the partial body + // buffer. + partial_parsed.append(part_begin, bytes); + part_begin = part.begin(); + connection_delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback + ); + } + bool follow_redirect_; boost::asio::io_service::strand request_strand_; shared_ptr resolver_delegate_; shared_ptr connection_delegate_; boost::asio::streambuf command_streambuf; std::string method; + response_parser response_parser_; + boost::promise version_promise; + boost::promise status_promise; + boost::promise status_message_promise; + boost::promise > headers_promise; + boost::promise source_promise; + boost::promise destination_promise; + boost::promise body_promise; + typedef boost::array buffer_type; + buffer_type part; + buffer_type::const_iterator part_begin; + std::string partial_parsed; }; // END OF PIMPL DEFINITION @@ -402,12 +734,10 @@ http_async_connection::http_async_connection(shared_ptr resol follow_redirects)) {} -http_async_connection::http - } /* http */ } /* network */ } /* boost */ -#endbooif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_NORMAL_IPP_20111123 */ +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_ASYNC_NORMAL_IPP_20111123 */ diff --git a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp index 6109c4ae2..9f706635b 100644 --- a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp +++ b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -13,7 +13,6 @@ namespace boost { namespace network { namespace http { namespace impl { - template struct http_async_protocol_handler { protected: @@ -24,7 +23,7 @@ namespace boost { namespace network { namespace http { namespace impl { : string(string_) {} debug_escaper(debug_escaper const & other) : string(other.string) {} - void operator()(typename std::string::value_type input) { + void operator()( std::string::value_type input) { if (!algorithm::is_print()(input)) { std::ostringstream escaped_stream; if (input == '\r') { @@ -42,8 +41,7 @@ namespace boost { namespace network { namespace http { namespace impl { }; #endif - template - void init_response(ResponseType & response_, bool get_body) { + void init_response(response & response_) { boost::shared_future source_future( source_promise.get_future()); source(response_, source_future); @@ -86,13 +84,13 @@ namespace boost { namespace network { namespace http { namespace impl { size_t bytes) { logic::tribool parsed_ok; part_begin = part.begin(); - typename buffer_type::const_iterator part_end = part.begin(); + buffer_type::const_iterator part_end = part.begin(); std::advance(part_end, bytes); - typename boost::iterator_range + boost::iterator_range< buffer_type::const_iterator> result_range, input_range = boost::make_iterator_range(part_begin, part_end); fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( - response_parser_type::http_version_done, + response_parser::http_version_done, input_range); if (parsed_ok == true) { std::string version; @@ -141,13 +139,13 @@ namespace boost { namespace network { namespace http { namespace impl { Callback callback, size_t bytes) { logic::tribool parsed_ok; - typename buffer_type::const_iterator part_end = part.begin(); + buffer_type::const_iterator part_end = part.begin(); std::advance(part_end, bytes); - typename boost::iterator_range + boost::iterator_range< buffer_type::const_iterator> result_range, input_range = boost::make_iterator_range(part_begin, part_end); fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( - response_parser_type::http_status_done, + response_parser::http_status_done, input_range); if (parsed_ok == true) { std::string status; @@ -197,13 +195,13 @@ namespace boost { namespace network { namespace http { namespace impl { Callback callback, size_t bytes) { logic::tribool parsed_ok; - typename buffer_type::const_iterator part_end = part.begin(); + buffer_type::const_iterator part_end = part.begin(); std::advance(part_end, bytes); - typename boost::iterator_range + boost::iterator_range< buffer_type::const_iterator> result_range, input_range = boost::make_iterator_range(part_begin, part_end); fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( - response_parser_type::http_status_message_done, + response_parser::http_status_message_done, input_range); if (parsed_ok == true) { std::string status_message; @@ -245,28 +243,28 @@ namespace boost { namespace network { namespace http { namespace impl { } void parse_headers_real(std::string & headers_part) { - typename boost::iterator_range + boost::iterator_range< std::string::const_iterator> input_range = boost::make_iterator_range(headers_part) , result_range; logic::tribool parsed_ok; - response_parser_type headers_parser( - response_parser_type::http_header_line_done); + response_parser headers_parser( + response_parser::http_header_line_done); std::multimap headers; std::pair header_pair; while (!boost::empty(input_range)) { fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( - response_parser_type::http_header_colon, + response_parser::http_header_colon, input_range); if (headers_parser.state() - != response_parser_type::http_header_colon) + != response_parser::http_header_colon) break; header_pair.first = std::string(boost::begin(result_range), boost::end(result_range)); input_range.advance_begin(boost::distance(result_range)); fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( - response_parser_type::http_header_line_done, + response_parser::http_header_line_done, input_range); header_pair.second = std::string(boost::begin(result_range), boost::end(result_range)); @@ -289,13 +287,13 @@ namespace boost { namespace network { namespace http { namespace impl { Callback callback, size_t bytes) { logic::tribool parsed_ok; - typename buffer_type::const_iterator part_end = part.begin(); + buffer_type::const_iterator part_end = part.begin(); std::advance(part_end, bytes); - typename boost::iterator_range + boost::iterator_range< buffer_type::const_iterator> result_range, input_range = boost::make_iterator_range(part_begin, part_end); fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( - response_parser_type::http_headers_done, + response_parser::http_headers_done, input_range); if (parsed_ok == true) { std::string headers_string; @@ -353,10 +351,7 @@ namespace boost { namespace network { namespace http { namespace impl { ); } - typedef response_parser response_parser_type; - typedef boost::array buffer_type; - - response_parser_type response_parser_; + response_parser response_parser_; boost::promise version_promise; boost::promise status_promise; boost::promise status_message_promise; @@ -364,8 +359,9 @@ namespace boost { namespace network { namespace http { namespace impl { boost::promise source_promise; boost::promise destination_promise; boost::promise body_promise; + typedef boost::array buffer_type; buffer_type part; - typename buffer_type::const_iterator part_begin; + buffer_type::const_iterator part_begin; std::string partial_parsed; }; diff --git a/boost/network/protocol/http/impl/access.hpp b/boost/network/protocol/http/impl/access.hpp new file mode 100644 index 000000000..f32bfd661 --- /dev/null +++ b/boost/network/protocol/http/impl/access.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_HPP_20111202 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_HPP_20111202 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost { namespace network { namespace http { + +struct response; + +namespace impl { + +struct setter_access { + promise get_version_promise(response &r); + promise get_status_promise(response &r); + promise get_status_message_promise(response &r); + promise > get_headers_promise(response &r); + promise get_source_promise(response &r); + promise get_destination_promise(response &r); + promise get_body_promise(response &r); +}; + +} // namespace impl + +} // namespace http + +} // namespace network + +} // namespace boost + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_HPP_20111202 diff --git a/boost/network/protocol/http/impl/access.ipp b/boost/network/protocol/http/impl/access.ipp new file mode 100644 index 000000000..944d4d2b7 --- /dev/null +++ b/boost/network/protocol/http/impl/access.ipp @@ -0,0 +1,45 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_IPP_20111202 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_IPP_20111202 + +#include + +namespace boost { namespace network { namespace http { namespace impl { + +promise setter_access::get_version_promise(response &r) { + return r.get_version_promise(); +} + +promise setter_access::get_status_promise(response &r) { + return r.get_status_promise(); +} + +promise setter_access::get_status_message_promise(response &r) { + return r.get_status_message_promise(); +} + +promise > +setter_access::get_headers_promise(response &r) { + return r.get_headers_promise(); +} + +promise setter_access::get_source_promise(response &r) { + return r.get_source_promise(); +} + +promise setter_access::get_destination_promise(response &r) { + return r.get_destination_promise(); +} + +promise setter_access::get_body_promise(response &r) { + return r.get_body_promise(); +} + +} // namespace impl + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ACCESS_IPP_20111202 diff --git a/boost/network/protocol/http/parser/incremental.hpp b/boost/network/protocol/http/parser/incremental.hpp index 58c16ca8c..ca07db0b7 100644 --- a/boost/network/protocol/http/parser/incremental.hpp +++ b/boost/network/protocol/http/parser/incremental.hpp @@ -16,267 +16,267 @@ namespace boost { namespace network { namespace http { - template - struct response_parser { +struct response_parser { - enum state_t { - http_response_begin, - http_version_h, - http_version_t1, - http_version_t2, - http_version_p, - http_version_slash, - http_version_major, - http_version_dot, - http_version_minor, - http_version_done, - http_status_digit, - http_status_done, - http_status_message_char, - http_status_message_cr, - http_status_message_done, - http_header_name_char, - http_header_colon, - http_header_value_char, - http_header_line_cr, - http_header_line_done, - http_headers_end_cr, - http_headers_done - }; + enum state_t { + http_response_begin, + http_version_h, + http_version_t1, + http_version_t2, + http_version_p, + http_version_slash, + http_version_major, + http_version_dot, + http_version_minor, + http_version_done, + http_status_digit, + http_status_done, + http_status_message_char, + http_status_message_cr, + http_status_message_done, + http_header_name_char, + http_header_colon, + http_header_value_char, + http_header_line_cr, + http_header_line_done, + http_headers_end_cr, + http_headers_done + }; - explicit response_parser (state_t state=http_response_begin) - : state_(state) {} + explicit response_parser (state_t state=http_response_begin) + : state_(state) {} - response_parser (response_parser const & other) - : state_(other.state_) {} + response_parser (response_parser const & other) + : state_(other.state_) {} - ~response_parser () {} + ~response_parser () {} - void swap(response_parser & other) { - std::swap(other.state_, this->state_); - } - - response_parser & operator=(response_parser rhs) { - rhs.swap(*this); - return *this; - } + void swap(response_parser & other) { + std::swap(other.state_, this->state_); + } - template - fusion::tuple > parse_until(state_t stop_state, Range & range_) { - logic::tribool parsed_ok(logic::indeterminate); - typename Range::const_iterator start = boost::begin(range_), - current = start, - end = boost::end(range_); - boost::iterator_range - local_range = boost::make_iterator_range(start, end); - while (!boost::empty(local_range) && indeterminate(parsed_ok)) { - current = boost::begin(local_range); - if (state_ == stop_state) { - parsed_ok = true; - } else { - switch(state_) { - case http_response_begin: - if (*current == ' ' || *current == '\r' || *current == '\n') { - // skip valid leading whitespace - ++start; - ++current; - } else if (*current == 'H') { - state_ = http_version_h; - start = current; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_h: - if (*current == 'T') { - state_ = http_version_t1; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_t1: - if (*current == 'T') { - state_ = http_version_t2; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_t2: - if (*current == 'P') { - state_ = http_version_p; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_p: - if (*current == '/') { - state_ = http_version_slash; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_slash: - if (algorithm::is_digit()(*current)) { - state_ = http_version_major; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_major: - if (*current == '.') { - state_ = http_version_dot; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_dot: - if (algorithm::is_digit()(*current)) { - state_ = http_version_minor; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_minor: - if (*current == ' ') { - state_ = http_version_done; - ++current; - } else { - parsed_ok = false; - } - break; - case http_version_done: - if (algorithm::is_digit()(*current)) { - state_ = http_status_digit; - ++current; - } else { - parsed_ok = false; - } - break; - case http_status_digit: - if (algorithm::is_digit()(*current)) { - ++current; - } else if (*current == ' ') { - state_ = http_status_done; - ++current; - } else { - parsed_ok = false; - } - break; - case http_status_done: - if (algorithm::is_alnum()(*current)) { - state_ = http_status_message_char; - ++current; - } else { - parsed_ok = false; - } - break; - case http_status_message_char: - if (algorithm::is_alnum()(*current) || algorithm::is_punct()(*current) || (*current == ' ')) { - ++current; - } else if (*current == '\r') { - state_ = http_status_message_cr; - ++current; - } else { - parsed_ok = false; - } - break; - case http_status_message_cr: - if (*current == '\n') { - state_ = http_status_message_done; - ++current; - } else { - parsed_ok = false; - } - break; - case http_status_message_done: - case http_header_line_done: - if (algorithm::is_alnum()(*current)) { - state_ = http_header_name_char; - ++current; - } else if (*current == '\r') { - state_ = http_headers_end_cr; - ++current; - } else { - parsed_ok = false; - } - break; - case http_header_name_char: - if (*current == ':') { - state_ = http_header_colon; - ++current; - } else if (algorithm::is_alnum()(*current) || algorithm::is_space()(*current) || algorithm::is_punct()(*current)) { - ++current; - } else { - parsed_ok = false; - } - break; - case http_header_colon: - if (algorithm::is_space()(*current)) { - ++current; - } else if (algorithm::is_alnum()(*current) || algorithm::is_punct()(*current)) { - state_ = http_header_value_char; - ++current; - } else { - parsed_ok = false; - } - break; - case http_header_value_char: - if (*current == '\r') { - state_ = http_header_line_cr; - ++current; - } else if (algorithm::is_cntrl()(*current)) { - parsed_ok = false; - } else { - ++current; - } - break; - case http_header_line_cr: - if (*current == '\n') { - state_ = http_header_line_done; - ++current; - } else { - parsed_ok = false; - } - break; - case http_headers_end_cr: - if (*current == '\n') { - state_ = http_headers_done; - ++current; - } else { - parsed_ok = false; - } - break; - default: - parsed_ok = false; - } - } + response_parser & operator=(response_parser rhs) { + rhs.swap(*this); + return *this; + } - local_range = boost::make_iterator_range(current, end); - } - if (state_ == stop_state) parsed_ok = true; - return fusion::make_tuple(parsed_ok,boost::make_iterator_range(start, current)); + template + fusion::tuple > parse_until(state_t stop_state, Range & range_) { + logic::tribool parsed_ok(logic::indeterminate); + typename Range::const_iterator start = boost::begin(range_), + current = start, + end = boost::end(range_); + boost::iterator_range + local_range = boost::make_iterator_range(start, end); + if (boost::empty(local_range)) parsed_ok = false; + while (!boost::empty(local_range) && indeterminate(parsed_ok)) { + current = boost::begin(local_range); + if (state_ == stop_state) { + parsed_ok = true; + } else { + switch(state_) { + case http_response_begin: + if (*current == ' ' || *current == '\r' || *current == '\n') { + // skip valid leading whitespace + ++start; + ++current; + } else if (*current == 'H') { + state_ = http_version_h; + start = current; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_h: + if (*current == 'T') { + state_ = http_version_t1; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_t1: + if (*current == 'T') { + state_ = http_version_t2; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_t2: + if (*current == 'P') { + state_ = http_version_p; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_p: + if (*current == '/') { + state_ = http_version_slash; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_slash: + if (algorithm::is_digit()(*current)) { + state_ = http_version_major; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_major: + if (*current == '.') { + state_ = http_version_dot; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_dot: + if (algorithm::is_digit()(*current)) { + state_ = http_version_minor; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_minor: + if (*current == ' ') { + state_ = http_version_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_done: + if (algorithm::is_digit()(*current)) { + state_ = http_status_digit; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_digit: + if (algorithm::is_digit()(*current)) { + ++current; + } else if (*current == ' ') { + state_ = http_status_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_done: + if (algorithm::is_alnum()(*current)) { + state_ = http_status_message_char; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_message_char: + if (algorithm::is_alnum()(*current) || algorithm::is_punct()(*current) || (*current == ' ')) { + ++current; + } else if (*current == '\r') { + state_ = http_status_message_cr; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_message_cr: + if (*current == '\n') { + state_ = http_status_message_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_message_done: + case http_header_line_done: + if (algorithm::is_alnum()(*current)) { + state_ = http_header_name_char; + ++current; + } else if (*current == '\r') { + state_ = http_headers_end_cr; + ++current; + } else { + parsed_ok = false; + } + break; + case http_header_name_char: + if (*current == ':') { + state_ = http_header_colon; + ++current; + } else if (algorithm::is_alnum()(*current) || algorithm::is_space()(*current) || algorithm::is_punct()(*current)) { + ++current; + } else { + parsed_ok = false; + } + break; + case http_header_colon: + if (algorithm::is_space()(*current)) { + ++current; + } else if (algorithm::is_alnum()(*current) || algorithm::is_punct()(*current)) { + state_ = http_header_value_char; + ++current; + } else { + parsed_ok = false; + } + break; + case http_header_value_char: + if (*current == '\r') { + state_ = http_header_line_cr; + ++current; + } else if (algorithm::is_cntrl()(*current)) { + parsed_ok = false; + } else { + ++current; + } + break; + case http_header_line_cr: + if (*current == '\n') { + state_ = http_header_line_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_headers_end_cr: + if (*current == '\n') { + state_ = http_headers_done; + ++current; + } else { + parsed_ok = false; + } + break; + default: + parsed_ok = false; } + } - state_t state() { - return state_; - } + local_range = boost::make_iterator_range(current, end); + } + if (state_ == stop_state) parsed_ok = true; + return fusion::make_tuple(parsed_ok,boost::make_iterator_range(start, current)); + } - void reset(state_t new_state = http_response_begin) { - state_ = new_state; - } + state_t state() { + return state_; + } + + void reset(state_t new_state = http_response_begin) { + state_ = new_state; + } - private: - state_t state_; + private: + state_t state_; - }; +}; } /* http */ diff --git a/boost/network/protocol/http/response/response.hpp b/boost/network/protocol/http/response/response.hpp index 412dfe3c3..c184759c5 100644 --- a/boost/network/protocol/http/response/response.hpp +++ b/boost/network/protocol/http/response/response.hpp @@ -7,10 +7,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include +#include + namespace boost { namespace network { namespace http { struct response : response_base { // FIXME implement all these! + response(); + response(response const &); + response& operator=(response); + void swap(response &); // From message_base... // Mutators @@ -44,8 +51,24 @@ struct response : response_base { virtual void set_status_message(std::string const & new_status_message); virtual void set_version(std::string const & new_version); virtual ~response(); + + private: + friend class impl::setter_access; // Hide access through accessor class. + // These methods are unique to the response type which will allow for creating + // promises that can be set appropriately. + promise get_version_promise(); + promise get_status_promise(); + promise get_status_message_promise(); + promise > get_headers_promise(); + promise get_source_promise(); + promise get_destination_promise(); + promise get_body_promise(); }; +inline void swap(response &l, response &r) { + l.swap(r); +} + template response & operator<<( response & message, From cfccb144f6a3d2bd7bbf9525a1b2d327e4ccc69f Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sat, 3 Dec 2011 23:57:55 +1100 Subject: [PATCH 053/438] HTTP Client Connections now Build! More changes in the message wrapper implementations but this is mostly for consistency. This means though that it breaks backwards compatibility for usage of these wrappers. Ultimately this commit gets the asynchronous connection implementation to a state where it actually builds and links. Next steps involve the actual chore of making the request and result implementations work as expected. --- boost/network/message/wrappers/body.hpp | 8 ++--- boost/network/message/wrappers/body.ipp | 5 ++- .../network/message/wrappers/destination.hpp | 12 +++---- .../network/message/wrappers/destination.ipp | 4 +-- boost/network/message/wrappers/headers.ipp | 6 ++-- boost/network/message/wrappers/source.hpp | 12 +++---- boost/network/message/wrappers/source.ipp | 4 +-- boost/network/protocol/http/client/base.hpp | 2 +- boost/network/protocol/http/client/base.ipp | 8 ++--- .../http/client/client_connection.hpp | 4 +-- .../http/client/connection/async_normal.hpp | 3 +- .../http/client/connection/async_normal.ipp | 36 +++++++++++++++++-- libs/network/test/http/CMakeLists.txt | 2 ++ libs/network/test/message_test.cpp | 3 +- libs/network/test/message_transform_test.cpp | 24 ++++++++----- 15 files changed, 83 insertions(+), 50 deletions(-) diff --git a/boost/network/message/wrappers/body.hpp b/boost/network/message/wrappers/body.hpp index 2a76497f9..fffe9277d 100644 --- a/boost/network/message/wrappers/body.hpp +++ b/boost/network/message/wrappers/body.hpp @@ -13,8 +13,6 @@ namespace boost { namespace network { -namespace impl { - struct body_wrapper { explicit body_wrapper(message_base const & message); operator std::string () const; @@ -32,11 +30,9 @@ inline std::ostream & operator<<(std::ostream & os, body_wrapper const & body) { return os; } -} // namespace impl - -inline impl::body_wrapper const +inline body_wrapper const body(message_base const & message_) { - return impl::body_wrapper(message_); + return body_wrapper(message_); } } // namespace network diff --git a/boost/network/message/wrappers/body.ipp b/boost/network/message/wrappers/body.ipp index 0c24f67bc..6cda77129 100644 --- a/boost/network/message/wrappers/body.ipp +++ b/boost/network/message/wrappers/body.ipp @@ -9,9 +9,9 @@ #include -namespace boost { namespace network { namespace impl { +namespace boost { namespace network { -body_wrapper::body_wrapper(message_base & message): +body_wrapper::body_wrapper(message_base const & message): message_(message) {} body_wrapper::operator std::string () const { @@ -64,7 +64,6 @@ std::string::const_iterator body_wrapper::end() const { return cache_->end(); } -} /* impl */ } /* network */ } /* boost */ diff --git a/boost/network/message/wrappers/destination.hpp b/boost/network/message/wrappers/destination.hpp index 1f3f44330..3b269a489 100644 --- a/boost/network/message/wrappers/destination.hpp +++ b/boost/network/message/wrappers/destination.hpp @@ -11,8 +11,6 @@ namespace boost { namespace network { -namespace impl { - struct destination_wrapper { explicit destination_wrapper(message_base const & message); operator std::string () const; @@ -21,11 +19,13 @@ struct destination_wrapper { mutable optional cache_; }; -} // namespace impl - -inline std::string const +inline destination_wrapper const destination(message_base const & message_) { - return impl::destination_wrapper(message_); + return destination_wrapper(message_); +} + +inline std::ostream & operator<< (std::ostream &os, destination_wrapper const &d) { + return os << static_cast(d); } } // namespace network diff --git a/boost/network/message/wrappers/destination.ipp b/boost/network/message/wrappers/destination.ipp index 99c1d73ff..8c25cc1d4 100644 --- a/boost/network/message/wrappers/destination.ipp +++ b/boost/network/message/wrappers/destination.ipp @@ -9,7 +9,7 @@ #include -namespace boost { namespace network { namespace impl { +namespace boost { namespace network { destination_wrapper::destination_wrapper(message_base const & message): message_(message) {} @@ -24,8 +24,6 @@ destination_wrapper::operator std::string () const { return *cache_; } -} /* impl */ - } /* network */ } /* boost */ diff --git a/boost/network/message/wrappers/headers.ipp b/boost/network/message/wrappers/headers.ipp index 80825fd23..38d917189 100644 --- a/boost/network/message/wrappers/headers.ipp +++ b/boost/network/message/wrappers/headers.ipp @@ -10,9 +10,9 @@ #include #include -namespace boost { namespace network { namespace impl { +namespace boost { namespace network { -headers_wrapper::headers_wrapper(message_base & message) +headers_wrapper::headers_wrapper(message_base const & message) : message_(message) {} @@ -76,8 +76,6 @@ void headers_wrapper::init_cache_all() const { } } -} /* impl */ - } /* network */ } /* boost */ diff --git a/boost/network/message/wrappers/source.hpp b/boost/network/message/wrappers/source.hpp index 84c7f6fe8..05dfac024 100644 --- a/boost/network/message/wrappers/source.hpp +++ b/boost/network/message/wrappers/source.hpp @@ -11,8 +11,6 @@ namespace boost { namespace network { -namespace impl { - struct source_wrapper { explicit source_wrapper(message_base & message); operator std::string () const; @@ -21,11 +19,13 @@ struct source_wrapper { mutable boost::optional cache_; }; -} // namespace impl - -inline std::string const +inline source_wrapper const source(message_base & message_) { - return impl::source_wrapper(message_); + return source_wrapper(message_); +} + +inline std::ostream & operator<<(std::ostream &os, source_wrapper const &s) { + return os << static_cast(s); } } // namespace network diff --git a/boost/network/message/wrappers/source.ipp b/boost/network/message/wrappers/source.ipp index 829d3876f..d6219b876 100644 --- a/boost/network/message/wrappers/source.ipp +++ b/boost/network/message/wrappers/source.ipp @@ -9,7 +9,7 @@ #include -namespace boost { namespace network { namespace impl { +namespace boost { namespace network { source_wrapper::source_wrapper(message_base & message): message_(message) {} @@ -24,8 +24,6 @@ source_wrapper::operator std::string () const { return *cache_; } -} /* impl */ - } /* network */ } /* boost */ diff --git a/boost/network/protocol/http/client/base.hpp b/boost/network/protocol/http/client/base.hpp index b5b381e49..a75823069 100644 --- a/boost/network/protocol/http/client/base.hpp +++ b/boost/network/protocol/http/client/base.hpp @@ -27,7 +27,7 @@ struct client_base { client_base(asio::io_service & service, shared_ptr connection_manager_); ~client_base(); - response const request_skeleton(request_base const & request_, + response const request_skeleton(request const & request_, std::string const & method, bool get_body, body_callback_function_type callback); diff --git a/boost/network/protocol/http/client/base.ipp b/boost/network/protocol/http/client/base.ipp index 34732b6d3..730bf1c7f 100644 --- a/boost/network/protocol/http/client/base.ipp +++ b/boost/network/protocol/http/client/base.ipp @@ -13,7 +13,7 @@ #include #include #include -#include +#include namespace boost { namespace network { namespace http { @@ -23,7 +23,7 @@ struct client_base_pimpl { body_callback_function_type; client_base_pimpl(shared_ptr connection_manager_); client_base_pimpl(asio::io_service & service, shared_ptr connection_manager_); - response const request_skeleton(request_base const & request_, + response const request_skeleton(request const & request_, std::string const & method, bool get_body, body_callback_function_type callback); @@ -45,7 +45,7 @@ client_base::client_base(asio::io_service & service, : pimpl(new (std::nothrow) client_base_pimpl(service, connection_manager_)) {} -response const client_base::request_skeleton(request_base const & request_, +response const client_base::request_skeleton(request const & request_, std::string const & method, bool get_body, body_callback_function_type callback) { @@ -94,7 +94,7 @@ client_base_pimpl::~client_base_pimpl() } response const client_base_pimpl::request_skeleton( - request_base const & request_, + request const & request_, std::string const & method, bool get_body, body_callback_function_type callback diff --git a/boost/network/protocol/http/client/client_connection.hpp b/boost/network/protocol/http/client/client_connection.hpp index a6302ad4d..e161c93c2 100644 --- a/boost/network/protocol/http/client/client_connection.hpp +++ b/boost/network/protocol/http/client/client_connection.hpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include namespace boost { namespace network { namespace http { @@ -20,7 +20,7 @@ struct client_connection { system::error_code const &)> callback_type; virtual response send_request(std::string const & method, - request_base const & request, + request const & request, bool get_body, callback_type callback) = 0; virtual client_connection * clone() const = 0; diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index c4fc08e86..3e44600d3 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -29,12 +29,13 @@ struct http_async_connection : client_connection bool follow_redirects); http_async_connection * clone() const; virtual response send_request(std::string const & method, - request_base const & request, + request const & request, bool get_body, callback_type callback); // override virtual void reset(); // override virtual ~http_async_connection(); private: + explicit http_async_connection(shared_ptr); shared_ptr pimpl; }; diff --git a/boost/network/protocol/http/client/connection/async_normal.ipp b/boost/network/protocol/http/client/connection/async_normal.ipp index e57e8b016..285d742f0 100644 --- a/boost/network/protocol/http/client/connection/async_normal.ipp +++ b/boost/network/protocol/http/client/connection/async_normal.ipp @@ -68,6 +68,18 @@ struct http_async_connection_pimpl : boost::enable_shared_from_thisresolver_delegate_, + this->connection_delegate_, + request_strand_.get_io_service(), + follow_redirect_); + } + + void reset() { + // FIXME Perform the actual re-set of the internal state and pending stuff. + } + private: http_async_connection_pimpl(http_async_connection_pimpl const &); // = delete @@ -731,8 +743,28 @@ http_async_connection::http_async_connection(shared_ptr resol : pimpl(new (std::nothrow) http_async_connection_pimpl(resolver_delegate, connection_delegate, io_service, - follow_redirects)) -{} + follow_redirects)) {} + +http_async_connection::http_async_connection(shared_ptr new_pimpl) +: pimpl(new_pimpl) {} + +http_async_connection::~http_async_connection() {} + +http_async_connection * http_async_connection::clone() const { + shared_ptr new_pimpl(pimpl->clone()); + return new (std::nothrow) http_async_connection(new_pimpl); +} + +response http_async_connection::send_request(std::string const & method, + request const & request, + bool get_body, + callback_type callback) { + return pimpl->start(request, method, get_body, callback); +} + +void http_async_connection::reset() { + pimpl->reset(); // NOTE: We're not resetting the pimpl, just the internal state. +} } /* http */ diff --git a/libs/network/test/http/CMakeLists.txt b/libs/network/test/http/CMakeLists.txt index e71b8333f..01a4bfdad 100644 --- a/libs/network/test/http/CMakeLists.txt +++ b/libs/network/test/http/CMakeLists.txt @@ -34,6 +34,7 @@ if (Boost_FOUND) add_dependencies(cpp-netlib-http-${test} cppnetlib-uri cppnetlib-message + cppnetlib-message-wrappers cppnetlib-http-message cppnetlib-http-client cppnetlib-http-client-connections) @@ -42,6 +43,7 @@ if (Boost_FOUND) ${CMAKE_THREAD_LIBS_INIT} cppnetlib-uri cppnetlib-message + cppnetlib-message-wrappers cppnetlib-http-message cppnetlib-http-client cppnetlib-http-client-connections) diff --git a/libs/network/test/message_test.cpp b/libs/network/test/message_test.cpp index 92a6b9103..d5f50fbf9 100644 --- a/libs/network/test/message_test.cpp +++ b/libs/network/test/message_test.cpp @@ -60,7 +60,8 @@ BOOST_AUTO_TEST_CASE(source_directive_test) { BOOST_AUTO_TEST_CASE(destination_directive_test) { message instance; instance << destination("destination"); - BOOST_CHECK ( destination(instance) == "destination" ); + std::string const & destination_ = destination(instance); + BOOST_CHECK ( destination_ == "destination" ); } BOOST_AUTO_TEST_CASE(remove_header_directive_test) { diff --git a/libs/network/test/message_transform_test.cpp b/libs/network/test/message_transform_test.cpp index c1be57148..9f77d014c 100644 --- a/libs/network/test/message_transform_test.cpp +++ b/libs/network/test/message_transform_test.cpp @@ -15,13 +15,17 @@ BOOST_AUTO_TEST_CASE ( message_transform_toupper ) { message msg; msg << source("me"); - BOOST_CHECK_EQUAL ( source(msg), "me" ); + std::string const & source_orig = source(msg); + BOOST_CHECK_EQUAL ( source_orig, "me" ); msg << transform(to_upper_, source_); - BOOST_CHECK_EQUAL ( source(msg), "ME" ); + std::string const & source_upper = source(msg); + BOOST_CHECK_EQUAL ( source_upper, "ME" ); msg << destination("you"); - BOOST_CHECK_EQUAL ( destination(msg), "you"); + std::string const & destination_orig = destination(msg); + BOOST_CHECK_EQUAL ( destination_orig, "you"); msg << transform(to_upper_, destination_); - BOOST_CHECK_EQUAL ( destination(msg), "YOU"); + std::string const & destination_upper = destination(msg); + BOOST_CHECK_EQUAL ( destination_upper, "YOU"); } BOOST_AUTO_TEST_CASE ( message_transform_tolower ) { @@ -29,12 +33,16 @@ BOOST_AUTO_TEST_CASE ( message_transform_tolower ) { message msg; msg << source("ME"); - BOOST_CHECK_EQUAL ( source(msg), "ME" ); + std::string const & source_orig = source(msg); + BOOST_CHECK_EQUAL ( source_orig, "ME" ); msg << transform(to_lower_, source_); - BOOST_CHECK_EQUAL ( source(msg), "me" ); + std::string const & source_lower = source(msg); + BOOST_CHECK_EQUAL ( source_lower, "me" ); msg << destination("YOU"); - BOOST_CHECK_EQUAL ( destination(msg), "YOU" ); + std::string const & destination_orig = destination(msg); + BOOST_CHECK_EQUAL ( destination_orig, "YOU" ); msg << transform(to_lower_, destination_); - BOOST_CHECK_EQUAL ( destination(msg), "you" ); + std::string const & destination_lower = destination(msg); + BOOST_CHECK_EQUAL ( destination_lower, "you" ); } From eeb590cd99c01b7972892deb302de08a1848a358 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Sun, 4 Dec 2011 21:30:18 +1100 Subject: [PATCH 054/438] More Wrapper Implementations. Here are a few more implementations of the wrappers required to get the necessary bits of the implementation out of the way. This clears up some fo the linker errors for the easier things that need to be dealt with. We also introduce a new lib for the constants used throughout the library. At some point later we're going to have to consolidate these constants not only from the HTTP implementation but also the URI implementation. --- boost/network/constants.ipp | 2 + .../protocol/http/message/wrappers/anchor.ipp | 30 +++++++++++++++ .../protocol/http/message/wrappers/host.ipp | 30 +++++++++++++++ .../protocol/http/message/wrappers/path.ipp | 30 +++++++++++++++ .../protocol/http/message/wrappers/port.hpp | 2 +- .../protocol/http/message/wrappers/port.ipp | 37 +++++++++++++++++++ .../protocol/http/message/wrappers/query.ipp | 30 +++++++++++++++ libs/network/src/CMakeLists.txt | 3 ++ libs/network/src/constants.cpp | 11 ++++++ libs/network/src/http/client_connections.cpp | 1 + libs/network/src/http/request.cpp | 5 +++ libs/network/test/http/CMakeLists.txt | 2 + 12 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 boost/network/protocol/http/message/wrappers/anchor.ipp create mode 100644 boost/network/protocol/http/message/wrappers/host.ipp create mode 100644 boost/network/protocol/http/message/wrappers/path.ipp create mode 100644 boost/network/protocol/http/message/wrappers/port.ipp create mode 100644 boost/network/protocol/http/message/wrappers/query.ipp create mode 100644 libs/network/src/constants.cpp diff --git a/boost/network/constants.ipp b/boost/network/constants.ipp index 86ac0ffc8..e6e10cd4d 100644 --- a/boost/network/constants.ipp +++ b/boost/network/constants.ipp @@ -7,6 +7,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include + namespace boost { namespace network { char const * constants::crlf() { diff --git a/boost/network/protocol/http/message/wrappers/anchor.ipp b/boost/network/protocol/http/message/wrappers/anchor.ipp new file mode 100644 index 000000000..b439b9c58 --- /dev/null +++ b/boost/network/protocol/http/message/wrappers/anchor.ipp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_IPP_20111204 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_IPP_20111204 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Googl,Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +anchor_wrapper::anchor_wrapper(request_base const & request) +: request_(request) {} + +anchor_wrapper::operator std::string () const { + uri::uri uri_; + request_.get_uri(uri_); + return fragment(uri_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_IPP_20111204 diff --git a/boost/network/protocol/http/message/wrappers/host.ipp b/boost/network/protocol/http/message/wrappers/host.ipp new file mode 100644 index 000000000..db047655b --- /dev/null +++ b/boost/network/protocol/http/message/wrappers/host.ipp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_IPP_20111204 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_IPP_20111204 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +host_wrapper::host_wrapper(request_base const & request) +: request_(request) {} + +host_wrapper::operator std::string () const { + uri::uri uri_; + request_.get_uri(uri_); + return host(uri_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_IPP_20111204 diff --git a/boost/network/protocol/http/message/wrappers/path.ipp b/boost/network/protocol/http/message/wrappers/path.ipp new file mode 100644 index 000000000..5427fa2a8 --- /dev/null +++ b/boost/network/protocol/http/message/wrappers/path.ipp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PATH_IPP_20111204 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PATH_IPP_20111204 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +path_wrapper::path_wrapper(request_base const & request) +: request_(request) {} + +path_wrapper::operator std::string () const { + uri::uri uri_; + request_.get_uri(uri_); + return path(uri_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PATH_IPP_20111204 diff --git a/boost/network/protocol/http/message/wrappers/port.hpp b/boost/network/protocol/http/message/wrappers/port.hpp index b74204da7..62a3e45ba 100644 --- a/boost/network/protocol/http/message/wrappers/port.hpp +++ b/boost/network/protocol/http/message/wrappers/port.hpp @@ -18,7 +18,7 @@ struct port_wrapper { operator boost::uint16_t () const; operator boost::optional () const; private: - request_base const & message_; + request_base const & request_; }; inline port_wrapper const diff --git a/boost/network/protocol/http/message/wrappers/port.ipp b/boost/network/protocol/http/message/wrappers/port.ipp new file mode 100644 index 000000000..6a4472fa5 --- /dev/null +++ b/boost/network/protocol/http/message/wrappers/port.ipp @@ -0,0 +1,37 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PORT_IPP_20111204 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PORT_IPP_20111204 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +port_wrapper::port_wrapper(request_base const & request) +: request_(request) {} + +port_wrapper::operator boost::uint16_t () const { + uri::uri uri_; + request_.get_uri(uri_); + optional optional_port = port_us(uri_); + return optional_port ? *optional_port : 80u; +} + +port_wrapper::operator optional () const { + uri::uri uri_; + request_.get_uri(uri_); + return port_us(uri_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PORT_IPP_20111204 diff --git a/boost/network/protocol/http/message/wrappers/query.ipp b/boost/network/protocol/http/message/wrappers/query.ipp new file mode 100644 index 000000000..806f0314d --- /dev/null +++ b/boost/network/protocol/http/message/wrappers/query.ipp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_IPP_20111204 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_IPP_20111204 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +namespace boost { namespace network { namespace http { + +query_wrapper::query_wrapper(request_base const & request) +: request_(request) {} + +query_wrapper::operator std::string () const { + uri::uri uri_; + request_.get_uri(uri_); + return query(uri_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_IPP_20111204 diff --git a/libs/network/src/CMakeLists.txt b/libs/network/src/CMakeLists.txt index a231213e9..81b19d561 100644 --- a/libs/network/src/CMakeLists.txt +++ b/libs/network/src/CMakeLists.txt @@ -47,3 +47,6 @@ add_library(cppnetlib-http-client ${CPP-NETLIB_HTTP_CLIENT_SRCS}) set(CPP-NETLIB_UTILS_THREAD_POOL_SRCS utils/thread_pool.cpp) add_library(cppnetlib-utils-thread_pool ${CPP-NETLIB_UTILS_THREAD_POOL_SRCS}) + +set(CPP-NETLIB_CONSTANTS_SRCS constants.cpp) +add_library(cppnetlib-constants ${CPP-NETLIB_CONSTANTS_SRCS}) diff --git a/libs/network/src/constants.cpp b/libs/network/src/constants.cpp new file mode 100644 index 000000000..f8674a076 --- /dev/null +++ b/libs/network/src/constants.cpp @@ -0,0 +1,11 @@ +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_NETWORK_NO_LIB +#undef BOOST_NETWORK_NO_LIB +#endif + +#include diff --git a/libs/network/src/http/client_connections.cpp b/libs/network/src/http/client_connections.cpp index 06cb0df22..0ad39c4a8 100644 --- a/libs/network/src/http/client_connections.cpp +++ b/libs/network/src/http/client_connections.cpp @@ -10,3 +10,4 @@ #include #include +#include diff --git a/libs/network/src/http/request.cpp b/libs/network/src/http/request.cpp index 983880dc4..a1f1ff481 100644 --- a/libs/network/src/http/request.cpp +++ b/libs/network/src/http/request.cpp @@ -9,3 +9,8 @@ #endif #include +#include +#include +#include +#include +#include diff --git a/libs/network/test/http/CMakeLists.txt b/libs/network/test/http/CMakeLists.txt index 01a4bfdad..d5bc63cd5 100644 --- a/libs/network/test/http/CMakeLists.txt +++ b/libs/network/test/http/CMakeLists.txt @@ -32,6 +32,7 @@ if (Boost_FOUND) endif() add_executable(cpp-netlib-http-${test} ${test}.cpp) add_dependencies(cpp-netlib-http-${test} + cppnetlib-constants cppnetlib-uri cppnetlib-message cppnetlib-message-wrappers @@ -41,6 +42,7 @@ if (Boost_FOUND) target_link_libraries(cpp-netlib-http-${test} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + cppnetlib-constants cppnetlib-uri cppnetlib-message cppnetlib-message-wrappers From dfdcaa82362424e8d410ab2350ad8ca0a43cb5d3 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris Date: Wed, 7 Dec 2011 01:54:03 +1100 Subject: [PATCH 055/438] Attempt at linking happiness. But no dice. I'm running into the issue of not being able to properly move/return lvalue promises. I might have to change the API of this but I'm committing things now just for recording forward progress. I should really get some sleep now. --- .../http/message/modifiers/status.hpp | 2 +- .../protocol/http/response/response.hpp | 10 +- .../protocol/http/response/response.ipp | 344 ++++++++++++++++++ .../protocol/http/response/response_base.hpp | 5 +- libs/network/src/http/response.cpp | 1 + 5 files changed, 358 insertions(+), 4 deletions(-) create mode 100644 boost/network/protocol/http/response/response.ipp diff --git a/boost/network/protocol/http/message/modifiers/status.hpp b/boost/network/protocol/http/message/modifiers/status.hpp index 66675fa8e..cb33820bd 100644 --- a/boost/network/protocol/http/message/modifiers/status.hpp +++ b/boost/network/protocol/http/message/modifiers/status.hpp @@ -11,7 +11,7 @@ namespace boost { namespace network { namespace http { -inline void status(response_base & response, std::string const & value) { +inline void status(response_base & response, boost::uint16_t value) { response.set_status(value); } diff --git a/boost/network/protocol/http/response/response.hpp b/boost/network/protocol/http/response/response.hpp index c184759c5..8855122d1 100644 --- a/boost/network/protocol/http/response/response.hpp +++ b/boost/network/protocol/http/response/response.hpp @@ -12,8 +12,9 @@ namespace boost { namespace network { namespace http { +struct response_pimpl; + struct response : response_base { - // FIXME implement all these! response(); response(response const &); response& operator=(response); @@ -47,9 +48,12 @@ struct response : response_base { size_t size) const; // From response_base... - virtual void set_status(std::string const & new_status); + virtual void set_status(boost::uint16_t new_status); virtual void set_status_message(std::string const & new_status_message); virtual void set_version(std::string const & new_version); + virtual void get_status(boost::uint16_t &status) const; + virtual void get_status_message(std::string &status_message) const; + virtual void get_version(std::string &version) const; virtual ~response(); private: @@ -63,6 +67,8 @@ struct response : response_base { promise get_source_promise(); promise get_destination_promise(); promise get_body_promise(); + + scoped_ptr pimpl_; }; inline void swap(response &l, response &r) { diff --git a/boost/network/protocol/http/response/response.ipp b/boost/network/protocol/http/response/response.ipp new file mode 100644 index 000000000..62db26844 --- /dev/null +++ b/boost/network/protocol/http/response/response.ipp @@ -0,0 +1,344 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_IPP_20111206 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_IPP_20111206 + +// Copyright 2011 Dean Michael Berris . +// Copyright 2011 Google, Inc. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +namespace boost { namespace network { namespace http { + +struct response_pimpl { + response_pimpl() {} + response_pimpl * clone() { + response_pimpl * new_pimpl = new (std::nothrow) response_pimpl; + new_pimpl->source_future_ = source_future_; + new_pimpl->destination_future_ = destination_future_; + new_pimpl->headers_future_ = headers_future_; + new_pimpl->status_future_ = status_future_; + new_pimpl->status_message_future_ = status_message_future_; + new_pimpl->version_future_ = version_future_; + new_pimpl->body_future_ = body_future_; + return new_pimpl; + } + + void set_destination(std::string const &destination) { + promise destination_promise; + unique_future tmp_future = destination_promise.get_future(); + destination_future_ = move(tmp_future); + destination_promise.set_value(destination); + } + + void get_destination(std::string &destination) { + if (!destination_future_) { + destination = ""; + } else { + destination = destination_future_->get(); + } + } + + void set_source(std::string const &source) { + promise source_promise; + unique_future tmp_future = source_promise.get_future(); + source_future_ = move(tmp_future); + source_promise.set_value(source); + } + + void get_source(std::string &source) { + if (!source_future_) { + source = ""; + } else { + source = source_future_->get(); + } + } + + void append_header(std::string const & name, + std::string const & value) { + // FIXME do something! + } + + void remove_headers(std::string const &name) { + // FIXME do something! + } + + void remove_headers() { + // FIXME do something! + } + + void get_headers( + function inserter) { /* FIXME: Do something! */ } + void get_headers( + std::string const & name, + function inserter) { /* FIXME: Do something! */ } + void get_headers( + function predicate, + function inserter) { /* FIXME: Do something! */ } + + void set_body(std::string const &body) { + promise body_promise; + unique_future tmp_future = body_promise.get_future(); + body_future_ = move(tmp_future); + body_promise.set_value(body); + } + + void append_body(std::string const & data) { /* FIXME: Do something! */ } + + void get_body(std::string &body) { + if (!body_future_) { + body = ""; + } else { + body = body_future_->get(); + } + } + + void get_body( + function)> chunk_reader, + size_t size) { /* FIXME: Do something! */ } + + void set_status(boost::uint16_t status) { + promise status_promise; + unique_future tmp_future = status_promise.get_future(); + status_future_ = move(tmp_future); + status_promise.set_value(status); + } + + void get_status(boost::uint16_t &status) { + if (!status_future_) { + status = 0u; + } else { + status = status_future_->get(); + } + } + + void set_status_message(std::string const &status_message) { + promise status_message_promise_; + unique_future tmp_future = status_message_promise_.get_future(); + status_message_future_ = move(tmp_future); + status_message_promise_.set_value(status_message); + } + + void get_status_message(std::string &status_message) { + if (!status_message_future_) { + status_message = ""; + } else { + status_message = status_message_future_->get(); + } + } + + void set_version(std::string const &version) { + promise version_promise; + unique_future tmp_future = version_promise.get_future(); + version_future_ = move(tmp_future); + version_promise.set_value(version); + } + + void get_version(std::string &version) { + if (!version_future_) { + version = ""; + } else { + version = version_future_->get(); + } + } + + promise get_source_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + source_future_ = move(tmp_future); + return move(promise_); + } + + promise get_destination_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + destination_future_ = move(tmp_future); + return move(promise_); + } + + promise > get_headers_promise() { + promise > promise_; + unique_future > tmp_future = promise_.get_future(); + headers_future_ = move(tmp_future); + return promise_; + } + + promise get_status_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + status_future_ = move(tmp_future); + return promise_; + } + + promise get_status_message_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + status_message_future_ = move(tmp_future); + return promise_; + } + + promise get_version_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + version_future_ = move(tmp_future); + return promise_; + } + + promise get_body_promise() { + promise promise_; + unique_future tmp_future = promise_.get_future(); + body_future_ = move(tmp_future); + return promise_; + } + + private: + optional > source_future_; + optional > destination_future_; + optional > > + headers_future_; + optional > status_future_; + optional > status_message_future_; + optional