| 942 | } |
| 943 | |
| 944 | static int on_headers_complete(http_parser* p) |
| 945 | { |
| 946 | StreamingRequestDecoder* decoder = (StreamingRequestDecoder*) p->data; |
| 947 | |
| 948 | // This asserts not only that `on_message_begin` has been previously called, |
| 949 | // but also that `on_headers_complete` is not called more than once. |
| 950 | CHECK_NOTNULL(decoder->request); |
| 951 | |
| 952 | // Add final header. |
| 953 | decoder->request->headers[decoder->field] = decoder->value; |
| 954 | decoder->field.clear(); |
| 955 | decoder->value.clear(); |
| 956 | |
| 957 | decoder->request->method = |
| 958 | http_method_str((http_method) decoder->parser.method); |
| 959 | |
| 960 | decoder->request->keepAlive = http_should_keep_alive(&decoder->parser) != 0; |
| 961 | |
| 962 | // Parse the URL. This data was incrementally built up during calls |
| 963 | // to `on_url`. |
| 964 | http_parser_url url; |
| 965 | http_parser_url_init(&url); |
| 966 | int parse_url = |
| 967 | http_parser_parse_url(decoder->url.data(), decoder->url.size(), 0, &url); |
| 968 | |
| 969 | if (parse_url != 0) { |
| 970 | decoder->failure = true; |
| 971 | return parse_url; |
| 972 | } |
| 973 | |
| 974 | if (url.field_set & (1 << UF_PATH)) { |
| 975 | decoder->request->url.path = std::string( |
| 976 | decoder->url.data() + url.field_data[UF_PATH].off, |
| 977 | url.field_data[UF_PATH].len); |
| 978 | } |
| 979 | |
| 980 | if (url.field_set & (1 << UF_FRAGMENT)) { |
| 981 | decoder->request->url.fragment = std::string( |
| 982 | decoder->url.data() + url.field_data[UF_FRAGMENT].off, |
| 983 | url.field_data[UF_FRAGMENT].len); |
| 984 | } |
| 985 | |
| 986 | if (url.field_set & (1 << UF_QUERY)) { |
| 987 | decoder->query = std::string( |
| 988 | decoder->url.data() + url.field_data[UF_QUERY].off, |
| 989 | url.field_data[UF_QUERY].len); |
| 990 | } |
| 991 | |
| 992 | // Parse the query key/values. |
| 993 | Try<hashmap<std::string, std::string>> decoded = |
| 994 | http::query::decode(decoder->query); |
| 995 | |
| 996 | if (decoded.isError()) { |
| 997 | decoder->failure = true; |
| 998 | return http_parsing::FAILURE; |
| 999 | } |
| 1000 | |
| 1001 | decoder->request->url.query = std::move(decoded.get()); |