1+
2+ // Copyright Dean Michael Berris 2007.
3+ // Distributed under the Boost Software License, Version 1.0.
4+ // (See accompanying file LICENSE_1_0.txt or copy at
5+ // http://www.boost.org/LICENSE_1_0.txt)
6+
7+ #ifndef __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__
8+ #define __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__
9+
10+ #include < boost/fusion/sequence/container/map.hpp>
11+ #include < boost/fusion/sequence/intrinsic/at_key.hpp>
12+ #include < boost/fusion/sequence/intrinsic/value_at_key.hpp>
13+
14+ #include < boost/spirit.hpp>
15+ #include < boost/spirit/phoenix.hpp>
16+
17+ namespace boost {namespace network {namespace http {
18+
19+ /* * request.hpp
20+ *
21+ * This file implements the basic request object required
22+ * by the HTTP client implementation. The basic_request
23+ * object encapsulates a URI which is parsed at runtime.
24+ * The data is broken up according to the URI specifications
25+ * RFC 3986 -- http://www.ietf.org/rfc/rfc3986.txt -- and
26+ * represented as a Fusion Map.
27+ */
28+
29+ template <class tag >
30+ class basic_request {
31+ struct tags {
32+ struct protocol { };
33+ struct host { };
34+ struct port { };
35+ struct path { };
36+ struct query { };
37+ struct anchor { };
38+ };
39+
40+ typedef fusion::map<
41+ fusion::pair<typename tags::protocol,typename tag::str_type>,
42+ fusion::pair<typename tags::host,typename tag::str_type>,
43+ fusion::pair<typename tags::port,unsigned int >,
44+ fusion::pair<typename tags::path,typename tag::str_type>,
45+ fusion::pair<typename tags::query,typename tag::str_type>,
46+ fusion::pair<typename tags::anchor,typename tag::str_type>
47+ > uri_parts_type;
48+
49+ mutable uri_parts_type uri_parts;
50+
51+ public:
52+ explicit basic_request (typename tag::str_typeconst & uri) {
53+ using namespace boost ::spirit;
54+ using namespace phoenix ;
55+
56+ fusion::at_key<typename tags::port>(uri_parts) =80u ;
57+
58+ parse (
59+ uri.begin (), uri.end (),
60+ // the parser
61+ str_p (" http" )[
62+ var (fusion::at_key<typename tags::protocol>(uri_parts))
63+ = construct_<typename tag::str_type>(arg1, arg2)
64+ ]
65+ >>str_p (" ://" )
66+ >> (+(alnum_p |' .' |' -' |' _' ))[
67+ var (fusion::at_key<typename tags::host>(uri_parts))
68+ = construct_<typename tag::str_type>(arg1, arg2)
69+ ]
70+ >> !(
71+ ch_p (' :' )
72+ >> uint_p[
73+ var (fusion::at_key<typename tags::port>(uri_parts))
74+ = arg1
75+ ]
76+ >> !ch_p (' /' )
77+ )
78+ >> (+(alnum_p |' /' |' %' |' _' |' -' |' .' ))[
79+ var (fusion::at_key<typename tags::path>(uri_parts))
80+ = construct_<typename tag::str_type>(arg1, arg2)
81+ ]
82+ >> !(ch_p (' ?' )
83+ >> (+(alnum_p |' &' |' =' |' %' |' _' ))[
84+ var (fusion::at_key<typename tags::query>(uri_parts))
85+ = construct_<typename tag::str_type>(arg1, arg2)
86+ ]
87+ )
88+ >> !(ch_p (' #' )
89+ >> (+(alnum_p |' _' |' %' |' -' ))[
90+ var (fusion::at_key<typename tags::anchor>(uri_parts))
91+ = construct_<typename tag::str_type>(arg1, arg2)
92+ ]
93+ )
94+ >> end_p
95+ ,
96+ nothing_p// no skip parser
97+ );
98+ };
99+
100+ // conversion from a message object into a basic_request
101+ basic_request (basic_message<tag>const & message_) {
102+ // TODO: contruct from a network message object
103+ };
104+
105+ basic_request (basic_requestconst & other) :
106+ uri_parts (other.uri_parts)
107+ { };
108+
109+ typename tag::str_typeconst host ()const {
110+ return fusion::at_key<tags::host>(uri_parts);
111+ };
112+
113+ unsigned int port ()const {
114+ return fusion::at_key<tags::port>(uri_parts);
115+ };
116+
117+ typename tag::str_typeconst path ()const {
118+ return fusion::at_key<tags::path>(uri_parts);
119+ };
120+
121+ typename tag::str_typeconst query ()const {
122+ return fusion::at_key<tags::query>(uri_parts);
123+ };
124+
125+ typename tag::str_typeconst anchor ()const {
126+ return fusion::at_key<tags::anchor>(uri_parts);
127+ };
128+ };
129+
130+ };// namespace http
131+
132+ };// namespace network
133+
134+ };// namespace boost
135+
136+ #endif // __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__