comparison src/http/v3/ngx_http_v3_request.c @ 8489:5d2e285677a7 quic

HTTP/3: generate Location response header for absolute redirects.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 23 Jul 2020 12:31:40 +0300
parents 79125ef2e39f
children e24f7b50ba1d
comparison
equal deleted inserted replaced
8488:79125ef2e39f 8489:5d2e285677a7
12 12
13 /* static table indices */ 13 /* static table indices */
14 #define NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO 4 14 #define NGX_HTTP_V3_HEADER_CONTENT_LENGTH_ZERO 4
15 #define NGX_HTTP_V3_HEADER_DATE 6 15 #define NGX_HTTP_V3_HEADER_DATE 6
16 #define NGX_HTTP_V3_HEADER_LAST_MODIFIED 10 16 #define NGX_HTTP_V3_HEADER_LAST_MODIFIED 10
17 #define NGX_HTTP_V3_HEADER_LOCATION 12
17 #define NGX_HTTP_V3_HEADER_STATUS_200 25 18 #define NGX_HTTP_V3_HEADER_STATUS_200 25
18 #define NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN 53 19 #define NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN 53
19 #define NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING 59 20 #define NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING 59
20 #define NGX_HTTP_V3_HEADER_SERVER 92 21 #define NGX_HTTP_V3_HEADER_SERVER 92
21 22
424 ngx_http_v3_create_header(ngx_http_request_t *r) 425 ngx_http_v3_create_header(ngx_http_request_t *r)
425 { 426 {
426 u_char *p; 427 u_char *p;
427 size_t len, n; 428 size_t len, n;
428 ngx_buf_t *b; 429 ngx_buf_t *b;
429 ngx_uint_t i; 430 ngx_str_t host;
431 ngx_uint_t i, port;
430 ngx_chain_t *hl, *cl, *bl; 432 ngx_chain_t *hl, *cl, *bl;
431 ngx_list_part_t *part; 433 ngx_list_part_t *part;
432 ngx_table_elt_t *header; 434 ngx_table_elt_t *header;
433 ngx_connection_t *c; 435 ngx_connection_t *c;
434 ngx_http_core_loc_conf_t *clcf; 436 ngx_http_core_loc_conf_t *clcf;
437 ngx_http_core_srv_conf_t *cscf;
438 u_char addr[NGX_SOCKADDR_STRLEN];
435 439
436 c = r->connection; 440 c = r->connection;
437 441
438 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header"); 442 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header");
439 443
504 len += ngx_http_v3_encode_header_lri(NULL, 0, 508 len += ngx_http_v3_encode_header_lri(NULL, 0,
505 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL, 509 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL,
506 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1); 510 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
507 } 511 }
508 512
509 /* XXX location */ 513 if (r->headers_out.location
514 && r->headers_out.location->value.len
515 && r->headers_out.location->value.data[0] == '/'
516 && clcf->absolute_redirect)
517 {
518 r->headers_out.location->hash = 0;
519
520 if (clcf->server_name_in_redirect) {
521 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
522 host = cscf->server_name;
523
524 } else if (r->headers_in.server.len) {
525 host = r->headers_in.server;
526
527 } else {
528 host.len = NGX_SOCKADDR_STRLEN;
529 host.data = addr;
530
531 if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) {
532 return NULL;
533 }
534 }
535
536 port = ngx_inet_get_port(c->local_sockaddr);
537
538 n = sizeof("https://") - 1 + host.len
539 + r->headers_out.location->value.len;
540
541 if (clcf->port_in_redirect) {
542 port = (port == 443) ? 0 : port;
543
544 } else {
545 port = 0;
546 }
547
548 if (port) {
549 n += sizeof(":65535") - 1;
550 }
551
552 len += ngx_http_v3_encode_header_lri(NULL, 0,
553 NGX_HTTP_V3_HEADER_LOCATION, NULL, n);
554
555 } else {
556 ngx_str_null(&host);
557 port = 0;
558 }
510 559
511 #if (NGX_HTTP_GZIP) 560 #if (NGX_HTTP_GZIP)
512 if (r->gzip_vary) { 561 if (r->gzip_vary) {
513 if (clcf->gzip_vary) { 562 if (clcf->gzip_vary) {
514 len += ngx_http_v3_encode_header_ri(NULL, 0, 563 len += ngx_http_v3_encode_header_ri(NULL, 0,
648 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1); 697 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
649 698
650 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time); 699 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
651 } 700 }
652 701
702 if (host.data) {
703 n = sizeof("https://") - 1 + host.len
704 + r->headers_out.location->value.len;
705
706 if (port) {
707 n += ngx_sprintf(b->last, ":%ui", port) - b->last;
708 }
709
710 b->last = (u_char *) ngx_http_v3_encode_header_lri(b->last, 0,
711 NGX_HTTP_V3_HEADER_LOCATION,
712 NULL, n);
713
714 p = b->last;
715 b->last = ngx_cpymem(b->last, "https://", sizeof("https://") - 1);
716 b->last = ngx_cpymem(b->last, host.data, host.len);
717
718 if (port) {
719 b->last = ngx_sprintf(b->last, ":%ui", port);
720 }
721
722 b->last = ngx_cpymem(b->last, r->headers_out.location->value.data,
723 r->headers_out.location->value.len);
724
725 /* update r->headers_out.location->value for possible logging */
726
727 r->headers_out.location->value.len = b->last - p;
728 r->headers_out.location->value.data = p;
729 ngx_str_set(&r->headers_out.location->key, "Location");
730 }
731
653 #if (NGX_HTTP_GZIP) 732 #if (NGX_HTTP_GZIP)
654 if (r->gzip_vary) { 733 if (r->gzip_vary) {
655 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0, 734 b->last = (u_char *) ngx_http_v3_encode_header_ri(b->last, 0,
656 NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING); 735 NGX_HTTP_V3_HEADER_VARY_ACCEPT_ENCODING);
657 } 736 }