Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 8215:38c0898b6df7 quic
HTTP/3.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 13 Mar 2020 19:36:33 +0300 |
parents | 6bc18966b8c1 |
children | 1307308c3cf1 |
comparison
equal
deleted
inserted
replaced
8214:6fd2cce50fe2 | 8215:38c0898b6df7 |
---|---|
62 #if (NGX_HTTP_SSL) | 62 #if (NGX_HTTP_SSL) |
63 static void ngx_http_ssl_handshake(ngx_event_t *rev); | 63 static void ngx_http_ssl_handshake(ngx_event_t *rev); |
64 static void ngx_http_ssl_handshake_handler(ngx_connection_t *c); | 64 static void ngx_http_ssl_handshake_handler(ngx_connection_t *c); |
65 #endif | 65 #endif |
66 | 66 |
67 #if (NGX_HTTP_V3) | |
67 static void ngx_http_quic_stream_handler(ngx_connection_t *c); | 68 static void ngx_http_quic_stream_handler(ngx_connection_t *c); |
69 #endif | |
68 | 70 |
69 static char *ngx_http_client_errors[] = { | 71 static char *ngx_http_client_errors[] = { |
70 | 72 |
71 /* NGX_HTTP_PARSE_INVALID_METHOD */ | 73 /* NGX_HTTP_PARSE_INVALID_METHOD */ |
72 "client sent invalid method", | 74 "client sent invalid method", |
217 #if (NGX_HAVE_INET6) | 219 #if (NGX_HAVE_INET6) |
218 struct sockaddr_in6 *sin6; | 220 struct sockaddr_in6 *sin6; |
219 ngx_http_in6_addr_t *addr6; | 221 ngx_http_in6_addr_t *addr6; |
220 #endif | 222 #endif |
221 | 223 |
222 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); | 224 #if (NGX_HTTP_V3) |
225 if (c->type == SOCK_DGRAM) { | |
226 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_connection_t)); | |
227 hc->quic = 1; | |
228 | |
229 } else | |
230 #endif | |
231 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); | |
232 | |
223 if (hc == NULL) { | 233 if (hc == NULL) { |
224 ngx_http_close_connection(c); | 234 ngx_http_close_connection(c); |
225 return; | 235 return; |
226 } | 236 } |
227 | 237 |
327 | 337 |
328 if (c->shared) { | 338 if (c->shared) { |
329 rev->ready = 1; | 339 rev->ready = 1; |
330 } | 340 } |
331 | 341 |
332 #if (NGX_HTTP_SSL) | 342 #if (NGX_HTTP_V3) |
333 if (hc->addr_conf->http3) { | 343 if (hc->quic) { |
334 ngx_http_ssl_srv_conf_t *sscf; | 344 ngx_http_ssl_srv_conf_t *sscf; |
335 | |
336 hc->quic = 1; | |
337 | 345 |
338 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); | 346 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); |
339 | 347 |
340 ngx_quic_run(c, &sscf->ssl, c->listening->post_accept_timeout, | 348 ngx_quic_run(c, &sscf->ssl, c->listening->post_accept_timeout, |
341 ngx_http_quic_stream_handler); | 349 ngx_http_quic_stream_handler); |
388 return; | 396 return; |
389 } | 397 } |
390 } | 398 } |
391 | 399 |
392 | 400 |
401 #if (NGX_HTTP_V3) | |
402 | |
393 static void | 403 static void |
394 ngx_http_quic_stream_handler(ngx_connection_t *c) | 404 ngx_http_quic_stream_handler(ngx_connection_t *c) |
395 { | 405 { |
396 ngx_quic_stream_t *qs = c->qs; | 406 ngx_event_t *rev; |
397 | 407 ngx_connection_t *pc; |
398 // STUB for stream read/write | 408 ngx_http_log_ctx_t *ctx; |
409 ngx_http_connection_t *hc; | |
410 ngx_http_v3_connection_t *h3c; | |
411 | |
412 pc = c->qs->parent; | |
413 h3c = pc->data; | |
414 | |
415 if (c->qs->unidirectional) { | |
416 ngx_http_v3_handle_client_uni_stream(c); | |
417 return; | |
418 } | |
419 | |
420 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); | |
421 if (hc == NULL) { | |
422 ngx_http_close_connection(c); | |
423 return; | |
424 } | |
425 | |
426 ngx_memcpy(hc, h3c, sizeof(ngx_http_connection_t)); | |
427 c->data = hc; | |
428 | |
429 ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); | |
430 if (ctx == NULL) { | |
431 ngx_http_close_connection(c); | |
432 return; | |
433 } | |
434 | |
435 ctx->connection = c; | |
436 ctx->request = NULL; | |
437 ctx->current_request = NULL; | |
438 | |
439 c->log->connection = c->number; | |
440 c->log->handler = ngx_http_log_error; | |
441 c->log->data = ctx; | |
442 c->log->action = "waiting for request"; | |
443 | |
444 c->log_error = NGX_ERROR_INFO; | |
399 | 445 |
400 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 446 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
401 "quic stream: 0x%uXL", qs->id); | 447 "http3 new stream id:0x%uXL", c->qs->id); |
402 ssize_t n; | 448 |
403 ngx_buf_t b; | 449 rev = c->read; |
404 | 450 rev->handler = ngx_http_wait_request_handler; |
405 u_char buf[512]; | 451 c->write->handler = ngx_http_empty_handler; |
406 | 452 |
407 b.start = buf; | 453 rev->handler(rev); |
408 b.end = buf + 512; | 454 } |
409 b.pos = b.last = b.start; | 455 |
410 | 456 #endif |
411 n = c->recv(c, b.pos, b.end - b.start); | |
412 if (n < 0) { | |
413 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream read failed"); | |
414 return; | |
415 } | |
416 | |
417 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
418 "quic stream: 0x%uXL %ui bytes read", qs->id, n); | |
419 | |
420 b.last += n; | |
421 | |
422 n = c->send(c, b.start, n); | |
423 | |
424 if (n < 0) { | |
425 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream write failed"); | |
426 return; | |
427 } | |
428 | |
429 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
430 "quic stream: 0x%uXL %ui bytes written", qs->id, n); | |
431 } | |
432 | 457 |
433 | 458 |
434 static void | 459 static void |
435 ngx_http_wait_request_handler(ngx_event_t *rev) | 460 ngx_http_wait_request_handler(ngx_event_t *rev) |
436 { | 461 { |
676 r->start_sec = tp->sec; | 701 r->start_sec = tp->sec; |
677 r->start_msec = tp->msec; | 702 r->start_msec = tp->msec; |
678 | 703 |
679 r->method = NGX_HTTP_UNKNOWN; | 704 r->method = NGX_HTTP_UNKNOWN; |
680 r->http_version = NGX_HTTP_VERSION_10; | 705 r->http_version = NGX_HTTP_VERSION_10; |
706 | |
707 #if (NGX_HTTP_V3) | |
708 if (hc->quic) { | |
709 r->http_version = NGX_HTTP_VERSION_30; | |
710 r->filter_need_in_memory = 1; | |
711 } | |
712 #endif | |
681 | 713 |
682 r->headers_in.content_length_n = -1; | 714 r->headers_in.content_length_n = -1; |
683 r->headers_in.keep_alive_n = -1; | 715 r->headers_in.keep_alive_n = -1; |
684 r->headers_out.content_length_n = -1; | 716 r->headers_out.content_length_n = -1; |
685 r->headers_out.last_modified_time = -1; | 717 r->headers_out.last_modified_time = -1; |
1126 if (n == NGX_AGAIN || n == NGX_ERROR) { | 1158 if (n == NGX_AGAIN || n == NGX_ERROR) { |
1127 break; | 1159 break; |
1128 } | 1160 } |
1129 } | 1161 } |
1130 | 1162 |
1131 rc = ngx_http_parse_request_line(r, r->header_in); | 1163 switch (r->http_version) { |
1164 #if (NGX_HTTP_V3) | |
1165 case NGX_HTTP_VERSION_30: | |
1166 rc = ngx_http_v3_parse_header(r, r->header_in, 1); | |
1167 break; | |
1168 #endif | |
1169 | |
1170 default: /* HTTP/1.x */ | |
1171 rc = ngx_http_parse_request_line(r, r->header_in); | |
1172 } | |
1132 | 1173 |
1133 if (rc == NGX_OK) { | 1174 if (rc == NGX_OK) { |
1134 | 1175 |
1135 /* the request line has been parsed successfully */ | 1176 /* the request line has been parsed successfully */ |
1136 | 1177 |
1139 r->request_length = r->header_in->pos - r->request_start; | 1180 r->request_length = r->header_in->pos - r->request_start; |
1140 | 1181 |
1141 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1182 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1142 "http request line: \"%V\"", &r->request_line); | 1183 "http request line: \"%V\"", &r->request_line); |
1143 | 1184 |
1144 r->method_name.len = r->method_end - r->request_start + 1; | 1185 r->method_name.len = r->method_end - r->method_start; |
1145 r->method_name.data = r->request_line.data; | 1186 r->method_name.data = r->method_start; |
1146 | 1187 |
1147 if (r->http_protocol.data) { | 1188 if (r->http_protocol.data) { |
1148 r->http_protocol.len = r->request_end - r->http_protocol.data; | 1189 r->http_protocol.len = r->request_end - r->http_protocol.data; |
1149 } | 1190 } |
1150 | 1191 |
1207 | 1248 |
1208 c->log->action = "reading client request headers"; | 1249 c->log->action = "reading client request headers"; |
1209 | 1250 |
1210 rev->handler = ngx_http_process_request_headers; | 1251 rev->handler = ngx_http_process_request_headers; |
1211 ngx_http_process_request_headers(rev); | 1252 ngx_http_process_request_headers(rev); |
1253 | |
1254 break; | |
1255 } | |
1256 | |
1257 if (rc == NGX_DONE) { | |
1258 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
1259 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1260 return; | |
1261 } | |
1212 | 1262 |
1213 break; | 1263 break; |
1214 } | 1264 } |
1215 | 1265 |
1216 if (rc != NGX_AGAIN) { | 1266 if (rc != NGX_AGAIN) { |
1401 return; | 1451 return; |
1402 } | 1452 } |
1403 | 1453 |
1404 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 1454 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
1405 | 1455 |
1406 rc = NGX_AGAIN; | 1456 rc = NGX_OK; |
1407 | 1457 |
1408 for ( ;; ) { | 1458 for ( ;; ) { |
1409 | 1459 |
1410 if (rc == NGX_AGAIN) { | 1460 if (rc == NGX_AGAIN) { |
1411 | 1461 |
1455 } | 1505 } |
1456 | 1506 |
1457 /* the host header could change the server configuration context */ | 1507 /* the host header could change the server configuration context */ |
1458 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 1508 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
1459 | 1509 |
1460 rc = ngx_http_parse_header_line(r, r->header_in, | 1510 switch (r->http_version) { |
1461 cscf->underscores_in_headers); | 1511 #if (NGX_HTTP_V3) |
1512 case NGX_HTTP_VERSION_30: | |
1513 rc = ngx_http_v3_parse_header(r, r->header_in, 0); | |
1514 break; | |
1515 #endif | |
1516 | |
1517 default: /* HTTP/1.x */ | |
1518 rc = ngx_http_parse_header_line(r, r->header_in, | |
1519 cscf->underscores_in_headers); | |
1520 } | |
1462 | 1521 |
1463 if (rc == NGX_OK) { | 1522 if (rc == NGX_OK) { |
1464 | 1523 |
1524 /* XXX */ | |
1465 r->request_length += r->header_in->pos - r->header_name_start; | 1525 r->request_length += r->header_in->pos - r->header_name_start; |
1466 | 1526 |
1467 if (r->invalid_header && cscf->ignore_invalid_headers) { | 1527 if (r->invalid_header && cscf->ignore_invalid_headers) { |
1468 | 1528 |
1469 /* there was error while a header line parsing */ | 1529 /* there was error while a header line parsing */ |
1485 | 1545 |
1486 h->hash = r->header_hash; | 1546 h->hash = r->header_hash; |
1487 | 1547 |
1488 h->key.len = r->header_name_end - r->header_name_start; | 1548 h->key.len = r->header_name_end - r->header_name_start; |
1489 h->key.data = r->header_name_start; | 1549 h->key.data = r->header_name_start; |
1490 h->key.data[h->key.len] = '\0'; | 1550 //h->key.data[h->key.len] = '\0'; |
1491 | 1551 |
1492 h->value.len = r->header_end - r->header_start; | 1552 h->value.len = r->header_end - r->header_start; |
1493 h->value.data = r->header_start; | 1553 h->value.data = r->header_start; |
1494 h->value.data[h->value.len] = '\0'; | 1554 //h->value.data[h->value.len] = '\0'; |
1495 | 1555 |
1496 h->lowcase_key = ngx_pnalloc(r->pool, h->key.len); | 1556 h->lowcase_key = ngx_pnalloc(r->pool, h->key.len); |
1497 if (h->lowcase_key == NULL) { | 1557 if (h->lowcase_key == NULL) { |
1498 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 1558 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
1499 break; | 1559 break; |
1640 r->header_in->last = r->header_in->start; | 1700 r->header_in->last = r->header_in->start; |
1641 | 1701 |
1642 return NGX_OK; | 1702 return NGX_OK; |
1643 } | 1703 } |
1644 | 1704 |
1645 old = request_line ? r->request_start : r->header_name_start; | 1705 old = request_line ? r->request_start : r->header_name_start; /* XXX */ |
1646 | 1706 |
1647 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 1707 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
1648 | 1708 |
1649 if (r->state != 0 | 1709 if (r->state != 0 |
1650 && (size_t) (r->header_in->pos - old) | 1710 && (size_t) (r->header_in->pos - old) |
1719 | 1779 |
1720 if (r->request_end) { | 1780 if (r->request_end) { |
1721 r->request_end = new + (r->request_end - old); | 1781 r->request_end = new + (r->request_end - old); |
1722 } | 1782 } |
1723 | 1783 |
1724 r->method_end = new + (r->method_end - old); | 1784 if (r->method_start >= old && r->method_start < r->header_in->pos) { |
1725 | 1785 r->method_start = new + (r->method_start - old); |
1726 r->uri_start = new + (r->uri_start - old); | 1786 r->method_end = new + (r->method_end - old); |
1727 r->uri_end = new + (r->uri_end - old); | 1787 } |
1728 | 1788 |
1729 if (r->schema_start) { | 1789 if (r->uri_start >= old && r->uri_start < r->header_in->pos) { |
1790 r->uri_start = new + (r->uri_start - old); | |
1791 r->uri_end = new + (r->uri_end - old); | |
1792 } | |
1793 | |
1794 if (r->schema_start >= old && r->schema_start < r->header_in->pos) { | |
1730 r->schema_start = new + (r->schema_start - old); | 1795 r->schema_start = new + (r->schema_start - old); |
1731 r->schema_end = new + (r->schema_end - old); | 1796 r->schema_end = new + (r->schema_end - old); |
1732 } | 1797 } |
1733 | 1798 |
1734 if (r->host_start) { | 1799 if (r->host_start >= old && r->host_start < r->header_in->pos) { |
1735 r->host_start = new + (r->host_start - old); | 1800 r->host_start = new + (r->host_start - old); |
1736 if (r->host_end) { | 1801 if (r->host_end) { |
1737 r->host_end = new + (r->host_end - old); | 1802 r->host_end = new + (r->host_end - old); |
1738 } | 1803 } |
1739 } | 1804 } |
1740 | 1805 |
1741 if (r->port_start) { | 1806 if (r->port_start >= old && r->port_start < r->header_in->pos) { |
1742 r->port_start = new + (r->port_start - old); | 1807 r->port_start = new + (r->port_start - old); |
1743 r->port_end = new + (r->port_end - old); | 1808 r->port_end = new + (r->port_end - old); |
1744 } | 1809 } |
1745 | 1810 |
1746 if (r->uri_ext) { | 1811 if (r->uri_ext >= old && r->uri_ext < r->header_in->pos) { |
1747 r->uri_ext = new + (r->uri_ext - old); | 1812 r->uri_ext = new + (r->uri_ext - old); |
1748 } | 1813 } |
1749 | 1814 |
1750 if (r->args_start) { | 1815 if (r->args_start >= old && r->args_start < r->header_in->pos) { |
1751 r->args_start = new + (r->args_start - old); | 1816 r->args_start = new + (r->args_start - old); |
1752 } | 1817 } |
1753 | 1818 |
1754 if (r->http_protocol.data) { | 1819 if (r->http_protocol.data >= old |
1820 && r->http_protocol.data < r->header_in->pos) | |
1821 { | |
1755 r->http_protocol.data = new + (r->http_protocol.data - old); | 1822 r->http_protocol.data = new + (r->http_protocol.data - old); |
1756 } | 1823 } |
1757 | 1824 |
1758 } else { | 1825 } else { |
1759 r->header_name_start = new; | 1826 if (r->header_name_start >= old |
1760 r->header_name_end = new + (r->header_name_end - old); | 1827 && r->header_name_start < r->header_in->pos) |
1761 r->header_start = new + (r->header_start - old); | 1828 { |
1762 r->header_end = new + (r->header_end - old); | 1829 r->header_name_start = new; |
1830 r->header_name_end = new + (r->header_name_end - old); | |
1831 } | |
1832 | |
1833 if (r->header_start >= old && r->header_start < r->header_in->pos) { | |
1834 r->header_start = new + (r->header_start - old); | |
1835 r->header_end = new + (r->header_end - old); | |
1836 } | |
1763 } | 1837 } |
1764 | 1838 |
1765 r->header_in = b; | 1839 r->header_in = b; |
1766 | 1840 |
1767 return NGX_OK; | 1841 return NGX_OK; |
1982 == NGX_ERROR) | 2056 == NGX_ERROR) |
1983 { | 2057 { |
1984 return NGX_ERROR; | 2058 return NGX_ERROR; |
1985 } | 2059 } |
1986 | 2060 |
1987 if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) { | 2061 if (r->headers_in.host == NULL && r->http_version == NGX_HTTP_VERSION_11) { |
1988 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 2062 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1989 "client sent HTTP/1.1 request without \"Host\" header"); | 2063 "client sent HTTP/1.1 request without \"Host\" header"); |
1990 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | 2064 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
1991 return NGX_ERROR; | 2065 return NGX_ERROR; |
1992 } | 2066 } |