7
7
#ifndef NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_IPP_20111206
8
8
#define NETWORK_PROTOCOL_HTTP_RESPONSE_RESPONSE_IPP_20111206
9
9
10
+ #include < boost/algorithm/string/predicate.hpp>
10
11
#include < network/protocol/http/response/response.hpp>
12
+
13
+ #include < algorithm>
11
14
#include < set>
15
+ #include < sstream>
12
16
13
17
namespace network {
14
18
namespace http {
@@ -91,7 +95,23 @@ struct response_pimpl {
91
95
void get_headers (
92
96
std::string const & name,
93
97
std::function<void (std::string const &, std::string const &)> inserter) {
94
- /* FIXME: Do something! */
98
+ if (removed_headers_.find (name) != removed_headers_.end ())
99
+ return ;
100
+
101
+ std::pair<std::multimap<std::string, std::string>::const_iterator,
102
+ std::multimap<std::string, std::string>::const_iterator>
103
+ range;
104
+ if (!headers_future_.valid ()) {
105
+ range = added_headers_.equal_range (name);
106
+ } else {
107
+ std::multimap<std::string, std::string> const & headers_ =
108
+ headers_future_.get ();
109
+ range = headers_.equal_range (name);
110
+ }
111
+
112
+ for (auto it = range.first ; it != range.second ; ++it) {
113
+ inserter (it->first , it->second );
114
+ }
95
115
}
96
116
void get_headers (
97
117
std::function<bool (std::string const &, std::string const &)> predicate,
@@ -113,7 +133,34 @@ struct response_pimpl {
113
133
if (!body_future_.valid ()) {
114
134
body = " " ;
115
135
} else {
116
- body = body_future_.get ();
136
+ std::string partial_parsed = body_future_.get ();
137
+ bool chunked = false ;
138
+ auto check = [&](std::string const & key, std::string const & value) {
139
+ chunked = chunked || boost::iequals (value, " chunked" );
140
+ };
141
+ get_headers (std::string (" Transfer-Encoding" ), check);
142
+ if (chunked) {
143
+ auto begin = partial_parsed.begin ();
144
+ std::string crlf = " \r\n " ;
145
+ for (auto iter = std::search (begin,partial_parsed.end (), crlf.begin (), crlf.end ());
146
+ iter != partial_parsed.end ();
147
+ iter = std::search (begin,partial_parsed.end (), crlf.begin (), crlf.end ())) {
148
+ std::string line (begin, iter);
149
+ if (line.empty ()) break ;
150
+ std::stringstream stream (line);
151
+ int len;
152
+ stream >> std::hex >> len;
153
+ iter += 2 ;
154
+ if (!len) break ;
155
+ if (len <= partial_parsed.end () - iter) {
156
+ body.insert (body.end (), iter, iter + len);
157
+ iter += len;
158
+ }
159
+ begin = iter;
160
+ }
161
+ } else {
162
+ std::swap (body, partial_parsed);
163
+ }
117
164
}
118
165
}
119
166
0 commit comments