| 206 | } |
| 207 | |
| 208 | static int on_message_complete(http_parser* p) |
| 209 | { |
| 210 | DataDecoder* decoder = (DataDecoder*) p->data; |
| 211 | |
| 212 | CHECK_NOTNULL(decoder->request); |
| 213 | |
| 214 | // Parse the URL. This data was incrementally built up during calls |
| 215 | // to `on_url`. |
| 216 | http_parser_url url; |
| 217 | http_parser_url_init(&url); |
| 218 | int parse_url = |
| 219 | http_parser_parse_url(decoder->url.data(), decoder->url.size(), 0, &url); |
| 220 | |
| 221 | if (parse_url != 0) { |
| 222 | decoder->failure = true; |
| 223 | return parse_url; |
| 224 | } |
| 225 | |
| 226 | if (url.field_set & (1 << UF_PATH)) { |
| 227 | decoder->request->url.path = std::string( |
| 228 | decoder->url.data() + url.field_data[UF_PATH].off, |
| 229 | url.field_data[UF_PATH].len); |
| 230 | } |
| 231 | |
| 232 | if (url.field_set & (1 << UF_FRAGMENT)) { |
| 233 | decoder->request->url.fragment = std::string( |
| 234 | decoder->url.data() + url.field_data[UF_FRAGMENT].off, |
| 235 | url.field_data[UF_FRAGMENT].len); |
| 236 | } |
| 237 | |
| 238 | if (url.field_set & (1 << UF_QUERY)) { |
| 239 | decoder->query = std::string( |
| 240 | decoder->url.data() + url.field_data[UF_QUERY].off, |
| 241 | url.field_data[UF_QUERY].len); |
| 242 | } |
| 243 | |
| 244 | // Parse the query key/values. |
| 245 | Try<hashmap<std::string, std::string>> decoded = |
| 246 | http::query::decode(decoder->query); |
| 247 | |
| 248 | if (decoded.isError()) { |
| 249 | decoder->failure = true; |
| 250 | return http_parsing::FAILURE; |
| 251 | } |
| 252 | |
| 253 | decoder->request->url.query = decoded.get(); |
| 254 | |
| 255 | Option<std::string> encoding = |
| 256 | decoder->request->headers.get("Content-Encoding"); |
| 257 | |
| 258 | if (encoding.isSome() && encoding.get() == "gzip") { |
| 259 | Try<std::string> decompressed = gzip::decompress(decoder->request->body); |
| 260 | if (decompressed.isError()) { |
| 261 | decoder->failure = true; |
| 262 | return http_parsing::FAILURE; |
| 263 | } |
| 264 | decoder->request->body = decompressed.get(); |
| 265 | |