nghttp2_on_header_callback: Called when nghttp2 library emits single header name/value pair. */
| 686 | /* nghttp2_on_header_callback: Called when nghttp2 library emits |
| 687 | single header name/value pair. */ |
| 688 | static int on_header_callback(nghttp2_session *session, |
| 689 | const nghttp2_frame *frame, const uint8_t *name, |
| 690 | size_t namelen, const uint8_t *_value, |
| 691 | size_t valuelen, uint8_t flags, void *user_data) { |
| 692 | http2_stream_data *stream_data; |
| 693 | const char PATH[] = ":path", METHOD[] = ":method"; |
| 694 | char *value = (char *)_value; |
| 695 | (void)flags; |
| 696 | (void)user_data; |
| 697 | |
| 698 | if (frame->hd.type != NGHTTP2_HEADERS |
| 699 | || frame->headers.cat != NGHTTP2_HCAT_REQUEST) |
| 700 | return 0; |
| 701 | |
| 702 | stream_data = |
| 703 | nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); |
| 704 | if (!stream_data) { |
| 705 | LM_ERR("failed to fetch data for stream %d\n", frame->hd.stream_id); |
| 706 | return 0; |
| 707 | } |
| 708 | |
| 709 | LM_DBG("received hdr(%d) on stream %d: '%.*s' = '%.*s' (%p)\n", frame->hd.type, |
| 710 | stream_data->stream_id, (int)namelen, name, (int)valuelen, value, stream_data); |
| 711 | |
| 712 | if (stream_data->path) |
| 713 | goto store_hdr; |
| 714 | |
| 715 | if (namelen == sizeof(PATH) - 1 && memcmp(PATH, name, namelen) == 0) { |
| 716 | size_t j; |
| 717 | for (j = 0; j < valuelen && _value[j] != '?'; ++j) |
| 718 | ; |
| 719 | stream_data->path = percent_decode(_value, j); |
| 720 | |
| 721 | LM_DBG("detected ':path' header, decoded value: '%s'\n", stream_data->path); |
| 722 | |
| 723 | value = stream_data->path; |
| 724 | valuelen = strlen(value); |
| 725 | } |
| 726 | |
| 727 | store_hdr: |
| 728 | if (stream_data->hdrs_len + namelen + valuelen > max_headers_size) { |
| 729 | LM_ERR("max_headers_size exceeded (%d), skipping header: %s\n", |
| 730 | max_headers_size, name); |
| 731 | return 0; |
| 732 | } |
| 733 | |
| 734 | { |
| 735 | cJSON *val = cJSON_CreateStr(value, valuelen); |
| 736 | str key = {(char *)name, namelen}; |
| 737 | |
| 738 | if (!val) { |
| 739 | LM_ERR("oom\n"); |
| 740 | return 0; |
| 741 | } |
| 742 | |
| 743 | _cJSON_AddItemToObject(stream_data->hdrs, &key, val); |
| 744 | if (!val->string) { |
| 745 | LM_ERR("oom\n"); |
nothing calls this directly
no test coverage detected