99
1010#include < boost/network/protocol/http/request/request.hpp>
1111#include < boost/network/protocol/http/request/request_concept.hpp>
12+ #include < boost/scoped_array.hpp>
1213
1314#ifdef BOOST_NETWORK_DEBUG
1415BOOST_CONCEPT_ASSERT ((boost::network::http::ClientRequest<boost::network::http::request>));
@@ -21,6 +22,9 @@ struct request_pimpl {
2122
2223explicit request_pimpl (std::stringconst & url)
2324 : uri_(url)
25+ , read_offset_(0 )
26+ , source_()
27+ , headers_()
2428 {}
2529
2630 request_pimpl*clone () {
@@ -31,14 +35,78 @@ struct request_pimpl {
3135 uri_ = uri;
3236 }
3337
38+ void set_uri (uri::uriconst & uri) {
39+ uri_ = uri;
40+ }
41+
3442void get_uri (std::string &uri) {
3543 uri = uri_.string ();
3644 }
3745
46+ void get_uri (uri::uri &uri) {
47+ uri = uri_;
48+ }
49+
50+ void append_header (std::stringconst & name, std::stringconst & value) {
51+ headers_.insert (std::make_pair (name, value));
52+ }
53+
54+ void get_headers (function<bool (std::stringconst &, std::stringconst &)> predicate,
55+ function<void(std::stringconst &, std::stringconst &)> inserter)const {
56+ headers_type::const_iterator it = headers_.begin ();
57+ for (; it != headers_.end (); ++it) {
58+ if (predicate (it->first , it->second )) {
59+ inserter (it->first , it->second );
60+ }
61+ }
62+ }
63+
64+ void get_headers (function<void (std::stringconst &, std::stringconst &)> inserter)const {
65+ headers_type::const_iterator it = headers_.begin ();
66+ for (; it != headers_.end (); ++it) {
67+ inserter (it->first , it->second );
68+ }
69+ }
70+
71+ void get_headers (std::stringconst &name,
72+ function<void (std::stringconst &, std::stringconst &)> inserter)const {
73+ headers_type::const_iterator it = headers_.begin ();
74+ for (; it != headers_.end (); ++it) {
75+ if (it->first == name) {
76+ inserter (it->first , it->second );
77+ }
78+ }
79+ }
80+
81+ void set_source (std::stringconst &source) {
82+ source_ = source;
83+ }
84+
85+ void get_source (std::string &source)const {
86+ source = source_;
87+ }
88+
89+ size_t read_offset ()const {
90+ return read_offset_;
91+ }
92+
93+ void advance_read_offset (size_t bytes) {
94+ read_offset_ += bytes;
95+ }
96+
3897private:
98+ typedef std::multimap<std::string, std::string> headers_type;
99+
39100 uri::uri uri_;
101+ size_t read_offset_;
102+ std::string source_;
103+ headers_type headers_;
104+
40105request_pimpl (request_pimplconst &other)
41106 : uri_(other.uri_)
107+ , read_offset_(other.read_offset_)
108+ , source_(other.source_)
109+ , headers_(other.headers_)
42110 {}
43111};
44112
@@ -68,47 +136,113 @@ void request::swap(request & other) {
68136
69137// From message_base...
70138// Mutators
71- void request::set_destination (std::stringconst & destination){}
72- void request::set_source (std::stringconst & source){}
139+ void request::set_destination (std::stringconst & destination) {
140+ }
141+
142+ void request::set_source (std::stringconst & source) {
143+ pimpl_->set_source (source);
144+ }
145+
73146void request::append_header (std::stringconst & name,
74- std::stringconst & value){}
75- void request::remove_headers (std::stringconst & name){}
76- void request::remove_headers (){}
77- void request::set_body (std::stringconst & body){}
78- void request::append_body (std::stringconst & data){}
147+ std::stringconst & value) {
148+ pimpl_->append_header (name, value);
149+ }
150+
151+ void request::remove_headers (std::stringconst & name) {
152+ }
153+
154+ void request::remove_headers () {
155+ }
156+
157+ void request::set_body (std::stringconst & body) {
158+ this ->clear ();
159+ this ->append (body.data (), body.size ());
160+ }
161+
162+ void request::append_body (std::stringconst & data) {
163+ this ->append (data.data (), data.size ());
164+ }
79165
80166// Retrievers
81- void request::get_destination (std::string & destination)const {}
82- void request::get_source (std::string & source)const {}
83- void request::get_headers (function<void (std::stringconst &, std::stringconst &)> inserter)const {}
84- void request::get_headers (std::stringconst & name, function<void (std::stringconst &, std::stringconst &)> inserter)const {}
85- void request::get_headers (function<bool (std::stringconst &, std::stringconst &)> predicate, function<void(std::stringconst &, std::stringconst &)> inserter)const {}
86- void request::get_body (std::string & body)const {}
87- void request::get_body (function<void (iterator_range<char const *>)> chunk_reader, size_t size)const {}
167+ void request::get_destination (std::string & destination)const {
168+ }
169+
170+ void request::get_source (std::string & source)const {
171+ pimpl_->get_source (source);
172+ }
173+
174+ void request::get_headers (function<void (std::stringconst &, std::stringconst &)> inserter)const {
175+ pimpl_->get_headers (inserter);
176+ }
177+
178+ void request::get_headers (std::stringconst & name, function<void (std::stringconst &, std::stringconst &)> inserter)const {
179+ pimpl_->get_headers (name, inserter);
180+ }
181+
182+ void request::get_headers (function<bool (std::stringconst &, std::stringconst &)> predicate, function<void(std::stringconst &, std::stringconst &)> inserter)const {
183+ pimpl_->get_headers (predicate, inserter);
184+ }
185+
186+ void request::get_body (std::string & body)const {
187+ this ->flatten (body);
188+ }
189+
190+ void request::get_body (function<void (iterator_range<char const *>)> chunk_reader, size_t size)const {
191+ scoped_array<char >local_buffer (new (std::nothrow)char [size]);
192+ size_t bytes_read =this ->read (local_buffer.get (),
193+ pimpl_->read_offset (),
194+ size);
195+ pimpl_->advance_read_offset (bytes_read);
196+ char const * begin = local_buffer.get ();
197+ char const * end = local_buffer.get () + bytes_read;
198+ chunk_reader (make_iterator_range (begin, end));
199+ }
88200
89201// From request_base...
90202// Setters
91- void request::set_method (std::stringconst & method){}
92- void request::set_status (std::stringconst & status){}
93- void request::set_status_message (std::stringconst & status_message){}
94- void request::set_body_writer (function<void (char *,size_t )> writer){}
203+ void request::set_method (std::stringconst & method) {
204+ }
205+
206+ void request::set_status (std::stringconst & status) {
207+ }
208+
209+ void request::set_status_message (std::stringconst & status_message) {
210+ }
211+
212+ void request::set_body_writer (function<void (char *,size_t )> writer) {
213+ }
214+
95215void request::set_uri (std::stringconst &uri) {
96216 pimpl_->set_uri (uri);
97217}
98- void request::set_uri (network::uri::uriconst &uri){}
218+
219+ void request::set_uri (network::uri::uriconst &uri) {
220+ pimpl_->set_uri (uri);
221+ }
99222
100223// Getters
101- void request::get_uri (network::uri::uri &uri)const {}
224+ void request::get_uri (network::uri::uri &uri)const {
225+ pimpl_->get_uri (uri);
226+ }
102227
103228void request::get_uri (std::string &uri)const {
104229 pimpl_->get_uri (uri);
105230}
106231
107- void request::get_method (std::string & method)const {}
108- void request::get_status (std::string & status)const {}
109- void request::get_status_message (std::string & status_message)const {}
110- void request::get_body (function<void (char *,size_t )> chunk_reader)const {}
111- void request::get_body (std::stringconst & body)const {}
232+ void request::get_method (std::string & method)const {
233+ }
234+
235+ void request::get_status (std::string & status)const {
236+ }
237+
238+ void request::get_status_message (std::string & status_message)const {
239+ }
240+
241+ void request::get_body (function<void (char *,size_t )> chunk_reader)const {
242+ }
243+
244+ void request::get_body (std::stringconst & body)const {
245+ }
112246
113247}// namespace http
114248