# HG changeset patch # User Roman Arutyunyan # Date 1584552136 -10800 # Node ID 1e45c02f637651f8fcee04e56b36ebc5585e9b00 # Parent 253cf267f95a6198162d48aa65a95a5dad698d42 HTTP/3 $request_line variable. diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1177,7 +1177,7 @@ ngx_http_process_request_line(ngx_event_ r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; - r->request_length = r->header_in->pos - r->request_start; + r->request_length = r->header_in->pos - r->request_start; /* XXX */ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http request line: \"%V\"", &r->request_line); @@ -1593,7 +1593,7 @@ ngx_http_process_request_headers(ngx_eve ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http header done"); - r->request_length += r->header_in->pos - r->header_name_start; + r->request_length += r->header_in->pos - r->header_name_start; /* XXX */ r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c --- a/src/http/v3/ngx_http_v3_request.c +++ b/src/http/v3/ngx_http_v3_request.c @@ -40,6 +40,8 @@ struct { ngx_int_t ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b) { + size_t n; + u_char *p; ngx_int_t rc; ngx_str_t *name, *value; ngx_connection_t *c; @@ -97,23 +99,45 @@ ngx_http_v3_parse_header(ngx_http_reques name = &st->header_rep.header.name; value = &st->header_rep.header.value; - if (r->state == sw_start - && ngx_http_v3_process_pseudo_header(r, name, value) != NGX_OK) - { - if (rc == NGX_DONE) { + if (r->state == sw_start) { + + if (ngx_http_v3_process_pseudo_header(r, name, value) == NGX_OK) { + if (rc == NGX_OK) { + continue; + } + + r->state = sw_done; + + } else if (rc == NGX_OK) { + r->state = sw_prev; + + } else { r->state = sw_last; - } else { - r->state = sw_prev; + } + + n = (r->method_end - r->method_start) + 1 + + (r->uri_end - r->uri_start) + 1 + + sizeof("HTTP/3") - 1; + + p = ngx_pnalloc(c->pool, n); + if (p == NULL) { + goto failed; } + r->request_start = p; + + p = ngx_cpymem(p, r->method_start, r->method_end - r->method_start); + *p++ = ' '; + p = ngx_cpymem(p, r->uri_start, r->uri_end - r->uri_start); + *p++ = ' '; + p = ngx_cpymem(p, "HTTP/3", sizeof("HTTP/3") - 1); + + r->request_end = p; + } else if (rc == NGX_DONE) { r->state = sw_done; } - if (r->state == sw_start) { - continue; - } - r->header_name_start = name->data; r->header_name_end = name->data + name->len; r->header_start = value->data; @@ -139,533 +163,6 @@ done: return NGX_HTTP_PARSE_HEADER_DONE; } -#if 0 -ngx_int_t -ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b, ngx_uint_t pseudo) -{ - u_char *p, ch; - ngx_str_t name, value; - ngx_int_t rc; - ngx_uint_t length, index, insert_count, sign, base, delta_base, - huffman, dynamic, offset; - ngx_connection_t *c; - ngx_http_v3_header_t *h; - enum { - sw_start = 0, - sw_length, - sw_length_1, - sw_length_2, - sw_length_3, - sw_header_block, - sw_req_insert_count, - sw_delta_base, - sw_read_delta_base, - sw_header, - sw_old_header, - sw_header_ri, - sw_header_pbi, - sw_header_lri, - sw_header_lpbi, - sw_header_l_name_len, - sw_header_l_name, - sw_header_value_len, - sw_header_read_value_len, - sw_header_value - } state; - - c = r->connection; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 parse header, pseudo:%ui", pseudo); - - if (r->state == sw_old_header) { - r->state = sw_header; - return NGX_OK; - } - - length = r->h3_length; - index = r->h3_index; - insert_count = r->h3_insert_count; - sign = r->h3_sign; - delta_base = r->h3_delta_base; - huffman = r->h3_huffman; - dynamic = r->h3_dynamic; - offset = r->h3_offset; - - name.data = r->header_name_start; - name.len = r->header_name_end - r->header_name_start; - value.data = r->header_start; - value.len = r->header_end - r->header_start; - - if (r->state == sw_start) { - length = 1; - } - -again: - - state = r->state; - - if (state == sw_header && length == 0) { - r->state = sw_start; - return NGX_HTTP_PARSE_HEADER_DONE; - } - - for (p = b->pos; p < b->last; p++) { - - if (state >= sw_header_block && length-- == 0) { - goto failed; - } - - ch = *p; - - switch (state) { - - case sw_start: - - if (ch != NGX_HTTP_V3_FRAME_HEADERS) { - goto failed; - } - - r->request_start = p; - state = sw_length; - break; - - case sw_length: - - length = ch; - if (length & 0xc0) { - state = sw_length_1; - break; - } - - state = sw_header_block; - break; - - case sw_length_1: - - length = (length << 8) + ch; - if ((length & 0xc000) != 0x4000) { - state = sw_length_2; - break; - } - - length &= 0x3fff; - state = sw_header_block; - break; - - case sw_length_2: - - length = (length << 8) + ch; - if ((length & 0xc00000) != 0x800000) { - state = sw_length_3; - break; - } - - length &= 0x3fffff; - state = sw_header_block; - break; - - case sw_length_3: - - length = (length << 8) + ch; - length &= 0x3fffffff; - state = sw_header_block; - break; - - case sw_header_block: - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header block length:%ui", length); - - if (ch != 0xff) { - insert_count = ch; - state = sw_delta_base; - break; - } - - insert_count = 0; - state = sw_req_insert_count; - break; - - case sw_req_insert_count: - - insert_count = (insert_count << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - insert_count += 0xff; - state = sw_delta_base; - break; - - case sw_delta_base: - - sign = (ch & 0x80) ? 1 : 0; - delta_base = ch & 0x7f; - - if (delta_base != 0x7f) { - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header block " - "insert_count:%ui, sign:%ui, delta_base:%ui", - insert_count, sign, delta_base); - goto done; - } - - delta_base = 0; - state = sw_read_delta_base; - break; - - case sw_read_delta_base: - - delta_base = (delta_base << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - delta_base += 0x7f; - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header block " - "insert_count:%ui, sign:%ui, delta_base:%ui", - insert_count, sign, delta_base); - goto done; - - case sw_header: - - index = 0; - huffman = 0; - ngx_str_null(&name); - ngx_str_null(&value); - - if (ch & 0x80) { - /* Indexed Header Field */ - - dynamic = (ch & 0x40) ? 0 : 1; - index = ch & 0x3f; - - if (index != 0x3f) { - goto done; - } - - index = 0; - state = sw_header_ri; - break; - } - - if (ch & 0x40) { - /* Literal Header Field With Name Reference */ - - dynamic = (ch & 0x10) ? 0 : 1; - index = ch & 0x0f; - - if (index != 0x0f) { - state = sw_header_value_len; - break; - } - - index = 0; - state = sw_header_lri; - break; - } - - if (ch & 0x20) { - /* Literal Header Field Without Name Reference */ - - huffman = (ch & 0x08) ? 1 : 0; - name.len = ch & 0x07; - - if (name.len == 0) { - goto failed; - } - - if (name.len != 0x07) { - offset = 0; - state = sw_header_l_name; - break; - } - - name.len = 0; - state = sw_header_l_name_len; - break; - } - - if (ch & 10) { - /* Indexed Header Field With Post-Base Index */ - - dynamic = 2; - index = ch & 0x0f; - - if (index != 0x0f) { - goto done; - } - - index = 0; - state = sw_header_pbi; - break; - } - - /* Literal Header Field With Post-Base Name Reference */ - - dynamic = 2; - index = ch & 0x07; - - if (index != 0x07) { - state = sw_header_value_len; - break; - } - - index = 0; - state = sw_header_lpbi; - break; - - case sw_header_ri: - - index = (index << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - index += 0x3f; - goto done; - - case sw_header_pbi: - - index = (index << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - index += 0x0f; - goto done; - - case sw_header_lri: - - index = (index << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - index += 0x0f; - state = sw_header_value_len; - break; - - case sw_header_lpbi: - - index = (index << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - index += 0x07; - state = sw_header_value_len; - break; - - - case sw_header_l_name_len: - - name.len = (name.len << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - name.len += 0x07; - offset = 0; - state = sw_header_l_name; - break; - - case sw_header_l_name: - if (offset++ == 0) { - name.data = p; - } - - if (offset != name.len) { - break; - } - - if (huffman) { - if (ngx_http_v3_decode_huffman(c, &name) != NGX_OK) { - goto failed; - } - } - - state = sw_header_value_len; - break; - - case sw_header_value_len: - - huffman = (ch & 0x80) ? 1 : 0; - value.len = ch & 0x7f; - - if (value.len == 0) { - value.data = p; - goto done; - } - - if (value.len != 0x7f) { - offset = 0; - state = sw_header_value; - break; - } - - value.len = 0; - state = sw_header_read_value_len; - break; - - case sw_header_read_value_len: - - value.len = (value.len << 7) + (ch & 0x7f); - if (ch & 0x80) { - break; - } - - value.len += 0x7f; - offset = 0; - state = sw_header_value; - break; - - case sw_header_value: - - if (offset++ == 0) { - value.data = p; - } - - if (offset != value.len) { - break; - } - - if (huffman) { - if (ngx_http_v3_decode_huffman(c, &value) != NGX_OK) { - goto failed; - } - } - - goto done; - - case sw_old_header: - - break; - } - } - - b->pos = p; - r->state = state; - r->h3_length = length; - r->h3_index = index; - r->h3_insert_count = insert_count; - r->h3_sign = sign; - r->h3_delta_base = delta_base; - r->h3_huffman = huffman; - r->h3_dynamic = dynamic; - r->h3_offset = offset; - - /* XXX fix large reallocations */ - r->header_name_start = name.data; - r->header_name_end = name.data + name.len; - r->header_start = value.data; - r->header_end = value.data + value.len; - - /* XXX r->lowcase_index = i; */ - - return NGX_AGAIN; - -done: - - b->pos = p + 1; - r->state = sw_header; - r->h3_length = length; - r->h3_insert_count = insert_count; - r->h3_sign = sign; - r->h3_delta_base = delta_base; - - if (state < sw_header) { - if (ngx_http_v3_check_insert_count(c, insert_count) != NGX_OK) { - return NGX_DONE; - } - - goto again; - } - - if (sign == 0) { - base = insert_count + delta_base; - } else { - base = insert_count - delta_base - 1; - } - - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header %s[%ui], base:%ui, \"%V\":\"%V\"", - dynamic ? "dynamic" : "static", index, base, &name, &value); - - if (name.data == NULL) { - - if (dynamic == 2) { - index = base - index - 1; - } else if (dynamic == 1) { - index += base; - } - - h = ngx_http_v3_lookup_table(c, dynamic, index); - if (h == NULL) { - goto failed; - } - - name = h->name; - - if (value.data == NULL) { - value = h->value; - } - } - - /* XXX ugly reallocation for the trailing '\0' */ - - p = ngx_pnalloc(c->pool, name.len + value.len + 2); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, name.data, name.len); - name.data = p; - ngx_memcpy(p + name.len + 1, value.data, value.len); - value.data = p + name.len + 1; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header \"%V\":\"%V\"", &name, &value); - - if (pseudo) { - rc = ngx_http_v3_process_pseudo_header(r, &name, &value); - - if (rc == NGX_ERROR) { - goto failed; - } - - if (rc == NGX_OK) { - r->request_end = p + 1; - goto again; - } - - /* rc == NGX_DONE */ - - r->state = sw_old_header; - } - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http3 header left:%ui", length); - - r->header_name_start = name.data; - r->header_name_end = name.data + name.len; - r->header_start = value.data; - r->header_end = value.data + value.len; - r->header_hash = ngx_hash_key(name.data, name.len); /* XXX */ - - /* XXX r->lowcase_index = i; */ - - return NGX_OK; - -failed: - - return NGX_HTTP_PARSE_INVALID_REQUEST; -} -#endif - static ngx_int_t ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name, @@ -675,7 +172,7 @@ ngx_http_v3_process_pseudo_header(ngx_ht ngx_connection_t *c; if (name->len == 0 || name->data[0] != ':') { - return NGX_DECLINED; + return NGX_DONE; } c = r->connection;