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 }