Deleted
Added
nxt_h1proto.c (1127:e60606d72d6b) | nxt_h1proto.c (1131:ec7d924d8dfb) |
---|---|
1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_router.h> 8#include <nxt_http.h> | 1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_router.h> 8#include <nxt_http.h> |
9#include <nxt_h1proto.h> 10#include <nxt_websocket.h> 11#include <nxt_websocket_header.h> |
|
9 10 | 12 13 |
11struct nxt_h1proto_s { 12 nxt_http_request_parse_t parser; 13 14 uint8_t nbuffers; 15 uint8_t keepalive; /* 1 bit */ 16 uint8_t chunked; /* 1 bit */ 17 nxt_http_te_t transfer_encoding:8; /* 2 bits */ 18 19 uint32_t header_size; 20 21 nxt_http_request_t *request; 22 nxt_buf_t *buffers; 23 /* 24 * All fields before the conn field will 25 * be zeroed in a keep-alive connection. 26 */ 27 nxt_conn_t *conn; 28}; 29 30 | |
31/* 32 * nxt_http_conn_ and nxt_h1p_conn_ prefixes are used for connection handlers. 33 * nxt_h1p_idle_ prefix is used for idle connection handlers. 34 * nxt_h1p_request_ prefix is used for HTTP/1 protocol request methods. 35 */ 36 37#if (NXT_TLS) 38static ssize_t nxt_http_idle_io_read_handler(nxt_conn_t *c); 39static void nxt_http_conn_test(nxt_task_t *task, void *obj, void *data); 40#endif 41static ssize_t nxt_h1p_idle_io_read_handler(nxt_conn_t *c); 42static void nxt_h1p_conn_proto_init(nxt_task_t *task, void *obj, void *data); 43static void nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data); 44static void nxt_h1p_conn_request_header_parse(nxt_task_t *task, void *obj, 45 void *data); | 14/* 15 * nxt_http_conn_ and nxt_h1p_conn_ prefixes are used for connection handlers. 16 * nxt_h1p_idle_ prefix is used for idle connection handlers. 17 * nxt_h1p_request_ prefix is used for HTTP/1 protocol request methods. 18 */ 19 20#if (NXT_TLS) 21static ssize_t nxt_http_idle_io_read_handler(nxt_conn_t *c); 22static void nxt_http_conn_test(nxt_task_t *task, void *obj, void *data); 23#endif 24static ssize_t nxt_h1p_idle_io_read_handler(nxt_conn_t *c); 25static void nxt_h1p_conn_proto_init(nxt_task_t *task, void *obj, void *data); 26static void nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data); 27static void nxt_h1p_conn_request_header_parse(nxt_task_t *task, void *obj, 28 void *data); |
46static nxt_int_t nxt_h1p_header_process(nxt_h1proto_t *h1p, | 29static nxt_int_t nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p, |
47 nxt_http_request_t *r); 48static nxt_int_t nxt_h1p_header_buffer_test(nxt_task_t *task, 49 nxt_h1proto_t *h1p, nxt_conn_t *c, nxt_socket_conf_t *skcf); 50static nxt_int_t nxt_h1p_connection(void *ctx, nxt_http_field_t *field, 51 uintptr_t data); | 30 nxt_http_request_t *r); 31static nxt_int_t nxt_h1p_header_buffer_test(nxt_task_t *task, 32 nxt_h1proto_t *h1p, nxt_conn_t *c, nxt_socket_conf_t *skcf); 33static nxt_int_t nxt_h1p_connection(void *ctx, nxt_http_field_t *field, 34 uintptr_t data); |
35static nxt_int_t nxt_h1p_upgrade(void *ctx, nxt_http_field_t *field, 36 uintptr_t data); 37static nxt_int_t nxt_h1p_websocket_key(void *ctx, nxt_http_field_t *field, 38 uintptr_t data); 39static nxt_int_t nxt_h1p_websocket_version(void *ctx, nxt_http_field_t *field, 40 uintptr_t data); |
|
52static nxt_int_t nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, 53 uintptr_t data); 54static void nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r); 55static void nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, 56 void *data); 57static void nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r); 58static void nxt_h1p_request_header_send(nxt_task_t *task, 59 nxt_http_request_t *r); --- 5 unchanged lines hidden (view full) --- 65 nxt_http_proto_t proto); 66static void nxt_h1p_request_discard(nxt_task_t *task, nxt_http_request_t *r, 67 nxt_buf_t *last); 68static void nxt_h1p_conn_request_error(nxt_task_t *task, void *obj, void *data); 69static void nxt_h1p_conn_request_timeout(nxt_task_t *task, void *obj, 70 void *data); 71static void nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, 72 void *data); | 41static nxt_int_t nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, 42 uintptr_t data); 43static void nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r); 44static void nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, 45 void *data); 46static void nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r); 47static void nxt_h1p_request_header_send(nxt_task_t *task, 48 nxt_http_request_t *r); --- 5 unchanged lines hidden (view full) --- 54 nxt_http_proto_t proto); 55static void nxt_h1p_request_discard(nxt_task_t *task, nxt_http_request_t *r, 56 nxt_buf_t *last); 57static void nxt_h1p_conn_request_error(nxt_task_t *task, void *obj, void *data); 58static void nxt_h1p_conn_request_timeout(nxt_task_t *task, void *obj, 59 void *data); 60static void nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, 61 void *data); |
73static nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, 74 uintptr_t data); | |
75nxt_inline void nxt_h1p_request_error(nxt_task_t *task, nxt_h1proto_t *h1p, 76 nxt_http_request_t *r); 77static void nxt_h1p_request_close(nxt_task_t *task, nxt_http_proto_t proto, 78 nxt_socket_conf_joint_t *joint); 79static void nxt_h1p_conn_sent(nxt_task_t *task, void *obj, void *data); 80static void nxt_h1p_conn_close(nxt_task_t *task, void *obj, void *data); 81static void nxt_h1p_conn_error(nxt_task_t *task, void *obj, void *data); 82static nxt_msec_t nxt_h1p_conn_timer_value(nxt_conn_t *c, uintptr_t data); 83static void nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, 84 nxt_conn_t *c); 85static void nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data); 86static void nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data); 87static void nxt_h1p_idle_response(nxt_task_t *task, nxt_conn_t *c); 88static void nxt_h1p_idle_response_sent(nxt_task_t *task, void *obj, void *data); 89static void nxt_h1p_idle_response_timeout(nxt_task_t *task, void *obj, 90 void *data); 91static nxt_msec_t nxt_h1p_idle_response_timer_value(nxt_conn_t *c, 92 uintptr_t data); 93static void nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c); | 62nxt_inline void nxt_h1p_request_error(nxt_task_t *task, nxt_h1proto_t *h1p, 63 nxt_http_request_t *r); 64static void nxt_h1p_request_close(nxt_task_t *task, nxt_http_proto_t proto, 65 nxt_socket_conf_joint_t *joint); 66static void nxt_h1p_conn_sent(nxt_task_t *task, void *obj, void *data); 67static void nxt_h1p_conn_close(nxt_task_t *task, void *obj, void *data); 68static void nxt_h1p_conn_error(nxt_task_t *task, void *obj, void *data); 69static nxt_msec_t nxt_h1p_conn_timer_value(nxt_conn_t *c, uintptr_t data); 70static void nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, 71 nxt_conn_t *c); 72static void nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data); 73static void nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data); 74static void nxt_h1p_idle_response(nxt_task_t *task, nxt_conn_t *c); 75static void nxt_h1p_idle_response_sent(nxt_task_t *task, void *obj, void *data); 76static void nxt_h1p_idle_response_timeout(nxt_task_t *task, void *obj, 77 void *data); 78static nxt_msec_t nxt_h1p_idle_response_timer_value(nxt_conn_t *c, 79 uintptr_t data); 80static void nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c); |
81static void nxt_h1p_shutdown_(nxt_task_t *task, nxt_conn_t *c); 82static void nxt_h1p_conn_ws_shutdown(nxt_task_t *task, void *obj, void *data); |
|
94static void nxt_h1p_conn_closing(nxt_task_t *task, void *obj, void *data); 95static void nxt_h1p_conn_free(nxt_task_t *task, void *obj, void *data); 96 | 83static void nxt_h1p_conn_closing(nxt_task_t *task, void *obj, void *data); 84static void nxt_h1p_conn_free(nxt_task_t *task, void *obj, void *data); 85 |
97 | |
98#if (NXT_TLS) 99static const nxt_conn_state_t nxt_http_idle_state; 100static const nxt_conn_state_t nxt_h1p_shutdown_state; 101#endif 102static const nxt_conn_state_t nxt_h1p_idle_state; | 86#if (NXT_TLS) 87static const nxt_conn_state_t nxt_http_idle_state; 88static const nxt_conn_state_t nxt_h1p_shutdown_state; 89#endif 90static const nxt_conn_state_t nxt_h1p_idle_state; |
103static const nxt_conn_state_t nxt_h1p_idle_close_state; | |
104static const nxt_conn_state_t nxt_h1p_header_parse_state; 105static const nxt_conn_state_t nxt_h1p_read_body_state; 106static const nxt_conn_state_t nxt_h1p_request_send_state; 107static const nxt_conn_state_t nxt_h1p_timeout_response_state; 108static const nxt_conn_state_t nxt_h1p_keepalive_state; 109static const nxt_conn_state_t nxt_h1p_close_state; 110 111 112const nxt_http_proto_table_t nxt_http_proto[3] = { 113 /* NXT_HTTP_PROTO_H1 */ 114 { 115 .body_read = nxt_h1p_request_body_read, 116 .local_addr = nxt_h1p_request_local_addr, 117 .header_send = nxt_h1p_request_header_send, 118 .send = nxt_h1p_request_send, 119 .body_bytes_sent = nxt_h1p_request_body_bytes_sent, 120 .discard = nxt_h1p_request_discard, 121 .close = nxt_h1p_request_close, | 91static const nxt_conn_state_t nxt_h1p_header_parse_state; 92static const nxt_conn_state_t nxt_h1p_read_body_state; 93static const nxt_conn_state_t nxt_h1p_request_send_state; 94static const nxt_conn_state_t nxt_h1p_timeout_response_state; 95static const nxt_conn_state_t nxt_h1p_keepalive_state; 96static const nxt_conn_state_t nxt_h1p_close_state; 97 98 99const nxt_http_proto_table_t nxt_http_proto[3] = { 100 /* NXT_HTTP_PROTO_H1 */ 101 { 102 .body_read = nxt_h1p_request_body_read, 103 .local_addr = nxt_h1p_request_local_addr, 104 .header_send = nxt_h1p_request_header_send, 105 .send = nxt_h1p_request_send, 106 .body_bytes_sent = nxt_h1p_request_body_bytes_sent, 107 .discard = nxt_h1p_request_discard, 108 .close = nxt_h1p_request_close, |
109 .ws_frame_start = nxt_h1p_websocket_frame_start, |
|
122 }, 123 /* NXT_HTTP_PROTO_H2 */ 124 /* NXT_HTTP_PROTO_DEVNULL */ 125}; 126 127 128static nxt_lvlhsh_t nxt_h1p_fields_hash; 129 130static nxt_http_field_proc_t nxt_h1p_fields[] = { 131 { nxt_string("Connection"), &nxt_h1p_connection, 0 }, | 110 }, 111 /* NXT_HTTP_PROTO_H2 */ 112 /* NXT_HTTP_PROTO_DEVNULL */ 113}; 114 115 116static nxt_lvlhsh_t nxt_h1p_fields_hash; 117 118static nxt_http_field_proc_t nxt_h1p_fields[] = { 119 { nxt_string("Connection"), &nxt_h1p_connection, 0 }, |
120 { nxt_string("Upgrade"), &nxt_h1p_upgrade, 0 }, 121 { nxt_string("Sec-WebSocket-Key"), &nxt_h1p_websocket_key, 0 }, 122 { nxt_string("Sec-WebSocket-Version"), 123 &nxt_h1p_websocket_version, 0 }, |
|
132 { nxt_string("Transfer-Encoding"), &nxt_h1p_transfer_encoding, 0 }, 133 134 { nxt_string("Host"), &nxt_http_request_host, 0 }, 135 { nxt_string("Cookie"), &nxt_http_request_field, 136 offsetof(nxt_http_request_t, cookie) }, 137 { nxt_string("Referer"), &nxt_http_request_field, 138 offsetof(nxt_http_request_t, referer) }, 139 { nxt_string("User-Agent"), &nxt_http_request_field, --- 358 unchanged lines hidden (view full) --- 498 case NXT_DONE: 499 /* 500 * By default the keepalive mode is disabled in HTTP/1.0 and 501 * enabled in HTTP/1.1. The mode can be overridden later by 502 * the "Connection" field processed in nxt_h1p_connection(). 503 */ 504 h1p->keepalive = (h1p->parser.version.s.minor != '0'); 505 | 124 { nxt_string("Transfer-Encoding"), &nxt_h1p_transfer_encoding, 0 }, 125 126 { nxt_string("Host"), &nxt_http_request_host, 0 }, 127 { nxt_string("Cookie"), &nxt_http_request_field, 128 offsetof(nxt_http_request_t, cookie) }, 129 { nxt_string("Referer"), &nxt_http_request_field, 130 offsetof(nxt_http_request_t, referer) }, 131 { nxt_string("User-Agent"), &nxt_http_request_field, --- 358 unchanged lines hidden (view full) --- 490 case NXT_DONE: 491 /* 492 * By default the keepalive mode is disabled in HTTP/1.0 and 493 * enabled in HTTP/1.1. The mode can be overridden later by 494 * the "Connection" field processed in nxt_h1p_connection(). 495 */ 496 h1p->keepalive = (h1p->parser.version.s.minor != '0'); 497 |
506 ret = nxt_h1p_header_process(h1p, r); | 498 ret = nxt_h1p_header_process(task, h1p, r); |
507 508 if (nxt_fast_path(ret == NXT_OK)) { 509 510#if (NXT_TLS) 511 if (c->u.tls == NULL && r->conf->socket_conf->tls != NULL) { 512 status = NXT_HTTP_TO_HTTPS; 513 goto error; 514 } --- 31 unchanged lines hidden (view full) --- 546 break; 547 548 default: 549 case NXT_ERROR: 550 status = NXT_HTTP_INTERNAL_SERVER_ERROR; 551 break; 552 } 553 | 499 500 if (nxt_fast_path(ret == NXT_OK)) { 501 502#if (NXT_TLS) 503 if (c->u.tls == NULL && r->conf->socket_conf->tls != NULL) { 504 status = NXT_HTTP_TO_HTTPS; 505 goto error; 506 } --- 31 unchanged lines hidden (view full) --- 538 break; 539 540 default: 541 case NXT_ERROR: 542 status = NXT_HTTP_INTERNAL_SERVER_ERROR; 543 break; 544 } 545 |
554 (void) nxt_h1p_header_process(h1p, r); | 546 (void) nxt_h1p_header_process(task, h1p, r); |
555 556error: 557 558 h1p->keepalive = 0; 559 560 nxt_http_request_error(task, r, status); 561} 562 563 564static nxt_int_t | 547 548error: 549 550 h1p->keepalive = 0; 551 552 nxt_http_request_error(task, r, status); 553} 554 555 556static nxt_int_t |
565nxt_h1p_header_process(nxt_h1proto_t *h1p, nxt_http_request_t *r) | 557nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p, 558 nxt_http_request_t *r) |
566{ | 559{ |
560 u_char *m; 561 nxt_int_t ret; 562 |
|
567 r->target.start = h1p->parser.target_start; 568 r->target.length = h1p->parser.target_end - h1p->parser.target_start; 569 570 if (h1p->parser.version.ui64 != 0) { 571 r->version.start = h1p->parser.version.str; 572 r->version.length = sizeof(h1p->parser.version.str); 573 } 574 575 r->method = &h1p->parser.method; 576 r->path = &h1p->parser.path; 577 r->args = &h1p->parser.args; 578 579 r->fields = h1p->parser.fields; 580 | 563 r->target.start = h1p->parser.target_start; 564 r->target.length = h1p->parser.target_end - h1p->parser.target_start; 565 566 if (h1p->parser.version.ui64 != 0) { 567 r->version.start = h1p->parser.version.str; 568 r->version.length = sizeof(h1p->parser.version.str); 569 } 570 571 r->method = &h1p->parser.method; 572 r->path = &h1p->parser.path; 573 r->args = &h1p->parser.args; 574 575 r->fields = h1p->parser.fields; 576 |
581 return nxt_http_fields_process(r->fields, &nxt_h1p_fields_hash, r); | 577 ret = nxt_http_fields_process(r->fields, &nxt_h1p_fields_hash, r); 578 if (nxt_slow_path(ret != NXT_OK)) { 579 return ret; 580 } 581 582 if (h1p->connection_upgrade && h1p->upgrade_websocket) { 583 m = h1p->parser.method.start; 584 585 if (nxt_slow_path(h1p->parser.method.length != 3 586 || m[0] != 'G' 587 || m[1] != 'E' 588 || m[2] != 'T')) 589 { 590 nxt_log(task, NXT_LOG_INFO, "h1p upgrade: bad method"); 591 592 return NXT_HTTP_BAD_REQUEST; 593 } 594 595 if (nxt_slow_path(h1p->parser.version.s.minor != '1')) { 596 nxt_log(task, NXT_LOG_INFO, "h1p upgrade: bad protocol version"); 597 598 return NXT_HTTP_BAD_REQUEST; 599 } 600 601 if (nxt_slow_path(h1p->websocket_key == NULL)) { 602 nxt_log(task, NXT_LOG_INFO, "h1p upgrade: bad or absent websocket key"); 603 604 return NXT_HTTP_BAD_REQUEST; 605 } 606 607 if (nxt_slow_path(h1p->websocket_version_ok == 0)) { 608 nxt_log(task, NXT_LOG_INFO, "h1p upgrade: bad or absent websocket version"); 609 610 return NXT_HTTP_UPGRADE_REQUIRED; 611 } 612 613 r->websocket_handshake = 1; 614 } 615 616 return ret; |
582} 583 584 585static nxt_int_t 586nxt_h1p_header_buffer_test(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c, 587 nxt_socket_conf_t *skcf) 588{ 589 size_t size, used; --- 25 unchanged lines hidden (view full) --- 615 616 return NXT_OK; 617} 618 619 620static nxt_int_t 621nxt_h1p_connection(void *ctx, nxt_http_field_t *field, uintptr_t data) 622{ | 617} 618 619 620static nxt_int_t 621nxt_h1p_header_buffer_test(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c, 622 nxt_socket_conf_t *skcf) 623{ 624 size_t size, used; --- 25 unchanged lines hidden (view full) --- 650 651 return NXT_OK; 652} 653 654 655static nxt_int_t 656nxt_h1p_connection(void *ctx, nxt_http_field_t *field, uintptr_t data) 657{ |
623 nxt_http_request_t *r; | 658 nxt_http_request_t *r; 659 static const u_char *upgrade = (const u_char *) "upgrade"; |
624 625 r = ctx; 626 627 if (field->value_length == 5 && nxt_memcmp(field->value, "close", 5) == 0) { 628 r->proto.h1->keepalive = 0; | 660 661 r = ctx; 662 663 if (field->value_length == 5 && nxt_memcmp(field->value, "close", 5) == 0) { 664 r->proto.h1->keepalive = 0; |
665 666 } else if (field->value_length == 7 667 && nxt_memcasecmp(field->value, upgrade, 7) == 0) 668 { 669 r->proto.h1->connection_upgrade = 1; |
|
629 } 630 631 return NXT_OK; 632} 633 634 635static nxt_int_t | 670 } 671 672 return NXT_OK; 673} 674 675 676static nxt_int_t |
677nxt_h1p_upgrade(void *ctx, nxt_http_field_t *field, uintptr_t data) 678{ 679 nxt_http_request_t *r; 680 static const u_char *websocket = (const u_char *) "websocket"; 681 682 r = ctx; 683 684 if (field->value_length == 9 685 && nxt_memcasecmp(field->value, websocket, 9) == 0) 686 { 687 r->proto.h1->upgrade_websocket = 1; 688 } 689 690 return NXT_OK; 691} 692 693 694static nxt_int_t 695nxt_h1p_websocket_key(void *ctx, nxt_http_field_t *field, uintptr_t data) 696{ 697 nxt_http_request_t *r; 698 699 r = ctx; 700 701 if (field->value_length == 24) { 702 r->proto.h1->websocket_key = field; 703 } 704 705 return NXT_OK; 706} 707 708 709static nxt_int_t 710nxt_h1p_websocket_version(void *ctx, nxt_http_field_t *field, uintptr_t data) 711{ 712 nxt_http_request_t *r; 713 714 r = ctx; 715 716 if (field->value_length == 2 717 && field->value[0] == '1' && field->value[1] == '3') 718 { 719 r->proto.h1->websocket_version_ok = 1; 720 } 721 722 return NXT_OK; 723} 724 725 726static nxt_int_t |
|
636nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, uintptr_t data) 637{ 638 nxt_http_te_t te; 639 nxt_http_request_t *r; 640 641 r = ctx; 642 643 if (field->value_length == 7 --- 78 unchanged lines hidden (view full) --- 722 723 size = nxt_buf_mem_free_size(&b->mem); 724 725 nxt_debug(task, "h1p body rest: %uz", size); 726 727 if (size != 0) { 728 in->next = h1p->buffers; 729 h1p->buffers = in; | 727nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, uintptr_t data) 728{ 729 nxt_http_te_t te; 730 nxt_http_request_t *r; 731 732 r = ctx; 733 734 if (field->value_length == 7 --- 78 unchanged lines hidden (view full) --- 813 814 size = nxt_buf_mem_free_size(&b->mem); 815 816 nxt_debug(task, "h1p body rest: %uz", size); 817 818 if (size != 0) { 819 in->next = h1p->buffers; 820 h1p->buffers = in; |
821 h1p->nbuffers++; |
|
730 731 c = h1p->conn; 732 c->read = b; 733 c->read_state = &nxt_h1p_read_body_state; 734 735 nxt_conn_read(task->thread->engine, c); 736 return; 737 } --- 62 unchanged lines hidden (view full) --- 800 801static void 802nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r) 803{ 804 r->local = nxt_conn_local_addr(task, r->proto.h1->conn); 805} 806 807 | 822 823 c = h1p->conn; 824 c->read = b; 825 c->read_state = &nxt_h1p_read_body_state; 826 827 nxt_conn_read(task->thread->engine, c); 828 return; 829 } --- 62 unchanged lines hidden (view full) --- 892 893static void 894nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r) 895{ 896 r->local = nxt_conn_local_addr(task, r->proto.h1->conn); 897} 898 899 |
900#define NXT_HTTP_LAST_INFORMATIONAL \ 901 (NXT_HTTP_CONTINUE + nxt_nitems(nxt_http_informational) - 1) 902 903static const nxt_str_t nxt_http_informational[] = { 904 nxt_string("HTTP/1.1 100 Continue\r\n"), 905 nxt_string("HTTP/1.1 101 Switching Protocols\r\n"), 906}; 907 908 |
|
808#define NXT_HTTP_LAST_SUCCESS \ 809 (NXT_HTTP_OK + nxt_nitems(nxt_http_success) - 1) 810 811static const nxt_str_t nxt_http_success[] = { 812 nxt_string("HTTP/1.1 200 OK\r\n"), 813 nxt_string("HTTP/1.1 201 Created\r\n"), 814 nxt_string("HTTP/1.1 202 Accepted\r\n"), 815 nxt_string("HTTP/1.1 203 Non-Authoritative Information\r\n"), --- 40 unchanged lines hidden (view full) --- 856 nxt_string("HTTP/1.1 418\r\n"), 857 nxt_string("HTTP/1.1 419\r\n"), 858 nxt_string("HTTP/1.1 420\r\n"), 859 nxt_string("HTTP/1.1 421\r\n"), 860 nxt_string("HTTP/1.1 422\r\n"), 861 nxt_string("HTTP/1.1 423\r\n"), 862 nxt_string("HTTP/1.1 424\r\n"), 863 nxt_string("HTTP/1.1 425\r\n"), | 909#define NXT_HTTP_LAST_SUCCESS \ 910 (NXT_HTTP_OK + nxt_nitems(nxt_http_success) - 1) 911 912static const nxt_str_t nxt_http_success[] = { 913 nxt_string("HTTP/1.1 200 OK\r\n"), 914 nxt_string("HTTP/1.1 201 Created\r\n"), 915 nxt_string("HTTP/1.1 202 Accepted\r\n"), 916 nxt_string("HTTP/1.1 203 Non-Authoritative Information\r\n"), --- 40 unchanged lines hidden (view full) --- 957 nxt_string("HTTP/1.1 418\r\n"), 958 nxt_string("HTTP/1.1 419\r\n"), 959 nxt_string("HTTP/1.1 420\r\n"), 960 nxt_string("HTTP/1.1 421\r\n"), 961 nxt_string("HTTP/1.1 422\r\n"), 962 nxt_string("HTTP/1.1 423\r\n"), 963 nxt_string("HTTP/1.1 424\r\n"), 964 nxt_string("HTTP/1.1 425\r\n"), |
864 nxt_string("HTTP/1.1 426\r\n"), | 965 nxt_string("HTTP/1.1 426 Upgrade Required\r\n"), |
865 nxt_string("HTTP/1.1 427\r\n"), 866 nxt_string("HTTP/1.1 428\r\n"), 867 nxt_string("HTTP/1.1 429\r\n"), 868 nxt_string("HTTP/1.1 430\r\n"), 869 nxt_string("HTTP/1.1 431 Request Header Fields Too Large\r\n"), 870}; 871 872 --- 33 unchanged lines hidden (view full) --- 906 nxt_bool_t http11; 907 nxt_conn_t *c; 908 nxt_h1proto_t *h1p; 909 const nxt_str_t *status; 910 nxt_http_field_t *field; 911 u_char buf[UNKNOWN_STATUS_LENGTH]; 912 913 static const char chunked[] = "Transfer-Encoding: chunked\r\n"; | 966 nxt_string("HTTP/1.1 427\r\n"), 967 nxt_string("HTTP/1.1 428\r\n"), 968 nxt_string("HTTP/1.1 429\r\n"), 969 nxt_string("HTTP/1.1 430\r\n"), 970 nxt_string("HTTP/1.1 431 Request Header Fields Too Large\r\n"), 971}; 972 973 --- 33 unchanged lines hidden (view full) --- 1007 nxt_bool_t http11; 1008 nxt_conn_t *c; 1009 nxt_h1proto_t *h1p; 1010 const nxt_str_t *status; 1011 nxt_http_field_t *field; 1012 u_char buf[UNKNOWN_STATUS_LENGTH]; 1013 1014 static const char chunked[] = "Transfer-Encoding: chunked\r\n"; |
1015 static const char websocket_version[] = "Sec-WebSocket-Version: 13\r\n"; |
|
914 | 1016 |
915 static const nxt_str_t connection[2] = { | 1017 static const nxt_str_t connection[3] = { |
916 nxt_string("Connection: close\r\n"), 917 nxt_string("Connection: keep-alive\r\n"), | 1018 nxt_string("Connection: close\r\n"), 1019 nxt_string("Connection: keep-alive\r\n"), |
1020 nxt_string("Upgrade: websocket\r\n" 1021 "Connection: Upgrade\r\n" 1022 "Sec-WebSocket-Accept: "), |
|
918 }; 919 920 nxt_debug(task, "h1p request header send"); 921 922 r->header_sent = 1; 923 h1p = r->proto.h1; 924 n = r->status; 925 | 1023 }; 1024 1025 nxt_debug(task, "h1p request header send"); 1026 1027 r->header_sent = 1; 1028 h1p = r->proto.h1; 1029 n = r->status; 1030 |
926 if (n >= NXT_HTTP_OK && n <= NXT_HTTP_LAST_SUCCESS) { | 1031 if (n >= NXT_HTTP_CONTINUE && n <= NXT_HTTP_LAST_INFORMATIONAL) { 1032 status = &nxt_http_informational[n - NXT_HTTP_CONTINUE]; 1033 1034 } else if (n >= NXT_HTTP_OK && n <= NXT_HTTP_LAST_SUCCESS) { |
927 status = &nxt_http_success[n - NXT_HTTP_OK]; 928 929 } else if (n >= NXT_HTTP_MULTIPLE_CHOICES 930 && n <= NXT_HTTP_LAST_REDIRECTION) 931 { 932 status = &nxt_http_redirection[n - NXT_HTTP_MULTIPLE_CHOICES]; 933 934 } else if (n >= NXT_HTTP_BAD_REQUEST && n <= NXT_HTTP_LAST_CLIENT_ERROR) { --- 15 unchanged lines hidden (view full) --- 950 unknown_status.start = buf; 951 status = &unknown_status; 952 } 953 954 size = status->length; 955 /* Trailing CRLF at the end of header. */ 956 size += nxt_length("\r\n"); 957 | 1035 status = &nxt_http_success[n - NXT_HTTP_OK]; 1036 1037 } else if (n >= NXT_HTTP_MULTIPLE_CHOICES 1038 && n <= NXT_HTTP_LAST_REDIRECTION) 1039 { 1040 status = &nxt_http_redirection[n - NXT_HTTP_MULTIPLE_CHOICES]; 1041 1042 } else if (n >= NXT_HTTP_BAD_REQUEST && n <= NXT_HTTP_LAST_CLIENT_ERROR) { --- 15 unchanged lines hidden (view full) --- 1058 unknown_status.start = buf; 1059 status = &unknown_status; 1060 } 1061 1062 size = status->length; 1063 /* Trailing CRLF at the end of header. */ 1064 size += nxt_length("\r\n"); 1065 |
958 http11 = (h1p->parser.version.s.minor != '0'); | 1066 conn = -1; |
959 | 1067 |
960 if (r->resp.content_length == NULL || r->resp.content_length->skip) { | 1068 if (r->websocket_handshake && n == NXT_HTTP_SWITCHING_PROTOCOLS) { 1069 h1p->websocket = 1; 1070 h1p->keepalive = 0; 1071 conn = 2; 1072 size += NXT_WEBSOCKET_ACCEPT_SIZE + 2; |
961 | 1073 |
962 if (http11) { 963 if (n != NXT_HTTP_NOT_MODIFIED && n != NXT_HTTP_NO_CONTENT) { 964 h1p->chunked = 1; 965 size += nxt_length(chunked); 966 /* Trailing CRLF will be added by the first chunk header. */ 967 size -= nxt_length("\r\n"); | 1074 } else { 1075 http11 = (h1p->parser.version.s.minor != '0'); 1076 1077 if (r->resp.content_length == NULL || r->resp.content_length->skip) { 1078 1079 if (http11) { 1080 if (n != NXT_HTTP_NOT_MODIFIED 1081 && n != NXT_HTTP_NO_CONTENT 1082 && !h1p->websocket) 1083 { 1084 h1p->chunked = 1; 1085 size += nxt_length(chunked); 1086 /* Trailing CRLF will be added by the first chunk header. */ 1087 size -= nxt_length("\r\n"); 1088 } 1089 1090 } else { 1091 h1p->keepalive = 0; |
968 } | 1092 } |
1093 } |
|
969 | 1094 |
970 } else { 971 h1p->keepalive = 0; | 1095 if (http11 ^ h1p->keepalive) { 1096 conn = h1p->keepalive; |
972 } 973 } 974 | 1097 } 1098 } 1099 |
975 conn = -1; 976 977 if (http11 ^ h1p->keepalive) { 978 conn = h1p->keepalive; | 1100 if (conn >= 0) { |
979 size += connection[conn].length; 980 } 981 982 nxt_list_each(field, r->resp.fields) { 983 984 if (!field->skip) { 985 size += field->name_length + field->value_length; 986 size += nxt_length(": \r\n"); 987 } 988 989 } nxt_list_loop; 990 | 1101 size += connection[conn].length; 1102 } 1103 1104 nxt_list_each(field, r->resp.fields) { 1105 1106 if (!field->skip) { 1107 size += field->name_length + field->value_length; 1108 size += nxt_length(": \r\n"); 1109 } 1110 1111 } nxt_list_loop; 1112 |
1113 if (nxt_slow_path(n == NXT_HTTP_UPGRADE_REQUIRED)) { 1114 size += nxt_length(websocket_version); 1115 } 1116 |
|
991 header = nxt_http_buf_mem(task, r, size); 992 if (nxt_slow_path(header == NULL)) { 993 nxt_h1p_request_error(task, h1p, r); 994 return; 995 } 996 | 1117 header = nxt_http_buf_mem(task, r, size); 1118 if (nxt_slow_path(header == NULL)) { 1119 nxt_h1p_request_error(task, h1p, r); 1120 return; 1121 } 1122 |
997 p = header->mem.free; | 1123 p = nxt_cpymem(header->mem.free, status->start, status->length); |
998 | 1124 |
999 p = nxt_cpymem(p, status->start, status->length); 1000 | |
1001 nxt_list_each(field, r->resp.fields) { 1002 1003 if (!field->skip) { 1004 p = nxt_cpymem(p, field->name, field->name_length); 1005 *p++ = ':'; *p++ = ' '; 1006 p = nxt_cpymem(p, field->value, field->value_length); 1007 *p++ = '\r'; *p++ = '\n'; 1008 } 1009 1010 } nxt_list_loop; 1011 1012 if (conn >= 0) { 1013 p = nxt_cpymem(p, connection[conn].start, connection[conn].length); 1014 } 1015 | 1125 nxt_list_each(field, r->resp.fields) { 1126 1127 if (!field->skip) { 1128 p = nxt_cpymem(p, field->name, field->name_length); 1129 *p++ = ':'; *p++ = ' '; 1130 p = nxt_cpymem(p, field->value, field->value_length); 1131 *p++ = '\r'; *p++ = '\n'; 1132 } 1133 1134 } nxt_list_loop; 1135 1136 if (conn >= 0) { 1137 p = nxt_cpymem(p, connection[conn].start, connection[conn].length); 1138 } 1139 |
1140 if (h1p->websocket) { 1141 nxt_websocket_accept(p, h1p->websocket_key->value); 1142 p += NXT_WEBSOCKET_ACCEPT_SIZE; 1143 1144 *p++ = '\r'; *p++ = '\n'; 1145 } 1146 1147 if (nxt_slow_path(n == NXT_HTTP_UPGRADE_REQUIRED)) { 1148 p = nxt_cpymem(p, websocket_version, nxt_length(websocket_version)); 1149 } 1150 |
|
1016 if (h1p->chunked) { 1017 p = nxt_cpymem(p, chunked, nxt_length(chunked)); 1018 /* Trailing CRLF will be added by the first chunk header. */ 1019 1020 } else { 1021 *p++ = '\r'; *p++ = '\n'; 1022 } 1023 1024 header->mem.free = p; 1025 1026 h1p->header_size = nxt_buf_mem_used_size(&header->mem); 1027 1028 c = h1p->conn; 1029 1030 c->write = header; 1031 c->write_state = &nxt_h1p_request_send_state; 1032 1033 nxt_conn_write(task->thread->engine, c); | 1151 if (h1p->chunked) { 1152 p = nxt_cpymem(p, chunked, nxt_length(chunked)); 1153 /* Trailing CRLF will be added by the first chunk header. */ 1154 1155 } else { 1156 *p++ = '\r'; *p++ = '\n'; 1157 } 1158 1159 header->mem.free = p; 1160 1161 h1p->header_size = nxt_buf_mem_used_size(&header->mem); 1162 1163 c = h1p->conn; 1164 1165 c->write = header; 1166 c->write_state = &nxt_h1p_request_send_state; 1167 1168 nxt_conn_write(task->thread->engine, c); |
1169 1170 if (h1p->websocket) { 1171 nxt_h1p_websocket_first_frame_start(task, r, c->read); 1172 } |
|
1034} 1035 1036 | 1173} 1174 1175 |
1176void 1177nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p) 1178{ 1179 size_t size; 1180 nxt_buf_t *b, *in, *next; 1181 nxt_conn_t *c; 1182 1183 nxt_debug(task, "h1p complete buffers"); 1184 1185 b = h1p->buffers; 1186 c = h1p->conn; 1187 in = c->read; 1188 1189 if (b != NULL) { 1190 if (in == NULL) { 1191 /* A request with large body. */ 1192 in = b; 1193 c->read = in; 1194 1195 b = in->next; 1196 in->next = NULL; 1197 } 1198 1199 while (b != NULL) { 1200 next = b->next; 1201 1202 nxt_work_queue_add(&task->thread->engine->fast_work_queue, 1203 b->completion_handler, task, b, b->parent); 1204 1205 b = next; 1206 } 1207 1208 h1p->buffers = NULL; 1209 h1p->nbuffers = 0; 1210 } 1211 1212 if (in != NULL) { 1213 size = nxt_buf_mem_used_size(&in->mem); 1214 1215 if (size == 0) { 1216 nxt_mp_free(c->mem_pool, in); 1217 1218 c->read = NULL; 1219 } 1220 } 1221} 1222 1223 |
|
1037static const nxt_conn_state_t nxt_h1p_request_send_state 1038 nxt_aligned(64) = 1039{ 1040 .ready_handler = nxt_h1p_conn_sent, 1041 .error_handler = nxt_h1p_conn_request_error, 1042 1043 .timer_handler = nxt_h1p_conn_request_send_timeout, 1044 .timer_value = nxt_h1p_conn_request_timer_value, --- 131 unchanged lines hidden (view full) --- 1176 nxt_http_request_t *r; 1177 1178 h1p = data; 1179 1180 nxt_debug(task, "h1p conn request error"); 1181 1182 r = h1p->request; 1183 | 1224static const nxt_conn_state_t nxt_h1p_request_send_state 1225 nxt_aligned(64) = 1226{ 1227 .ready_handler = nxt_h1p_conn_sent, 1228 .error_handler = nxt_h1p_conn_request_error, 1229 1230 .timer_handler = nxt_h1p_conn_request_send_timeout, 1231 .timer_value = nxt_h1p_conn_request_timer_value, --- 131 unchanged lines hidden (view full) --- 1363 nxt_http_request_t *r; 1364 1365 h1p = data; 1366 1367 nxt_debug(task, "h1p conn request error"); 1368 1369 r = h1p->request; 1370 |
1371 if (nxt_slow_path(r == NULL)) { 1372 nxt_h1p_shutdown(task, h1p->conn); 1373 return; 1374 } 1375 |
|
1184 if (r->fields == NULL) { | 1376 if (r->fields == NULL) { |
1185 (void) nxt_h1p_header_process(h1p, r); | 1377 (void) nxt_h1p_header_process(task, h1p, r); |
1186 } 1187 1188 if (r->status == 0) { 1189 r->status = NXT_HTTP_BAD_REQUEST; 1190 } 1191 1192 nxt_h1p_request_error(task, h1p, r); 1193} --- 19 unchanged lines hidden (view full) --- 1213 */ 1214 c->socket.timedout = 0; 1215 1216 h1p = c->socket.data; 1217 h1p->keepalive = 0; 1218 r = h1p->request; 1219 1220 if (r->fields == NULL) { | 1378 } 1379 1380 if (r->status == 0) { 1381 r->status = NXT_HTTP_BAD_REQUEST; 1382 } 1383 1384 nxt_h1p_request_error(task, h1p, r); 1385} --- 19 unchanged lines hidden (view full) --- 1405 */ 1406 c->socket.timedout = 0; 1407 1408 h1p = c->socket.data; 1409 h1p->keepalive = 0; 1410 r = h1p->request; 1411 1412 if (r->fields == NULL) { |
1221 (void) nxt_h1p_header_process(h1p, r); | 1413 (void) nxt_h1p_header_process(task, h1p, r); |
1222 } 1223 1224 nxt_http_request_error(task, r, NXT_HTTP_REQUEST_TIMEOUT); 1225} 1226 1227 1228static void 1229nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, void *data) --- 9 unchanged lines hidden (view full) --- 1239 c = nxt_write_timer_conn(timer); 1240 c->block_write = 1; 1241 h1p = c->socket.data; 1242 1243 nxt_h1p_request_error(task, h1p, h1p->request); 1244} 1245 1246 | 1414 } 1415 1416 nxt_http_request_error(task, r, NXT_HTTP_REQUEST_TIMEOUT); 1417} 1418 1419 1420static void 1421nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, void *data) --- 9 unchanged lines hidden (view full) --- 1431 c = nxt_write_timer_conn(timer); 1432 c->block_write = 1; 1433 h1p = c->socket.data; 1434 1435 nxt_h1p_request_error(task, h1p, h1p->request); 1436} 1437 1438 |
1247static nxt_msec_t | 1439nxt_msec_t |
1248nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data) 1249{ 1250 nxt_h1proto_t *h1p; 1251 1252 h1p = c->socket.data; 1253 1254 return nxt_value_at(nxt_msec_t, h1p->request->conf->socket_conf, data); 1255} --- 90 unchanged lines hidden (view full) --- 1346 return nxt_value_at(nxt_msec_t, joint->socket_conf, data); 1347} 1348 1349 1350static void 1351nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) 1352{ 1353 size_t size; | 1440nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data) 1441{ 1442 nxt_h1proto_t *h1p; 1443 1444 h1p = c->socket.data; 1445 1446 return nxt_value_at(nxt_msec_t, h1p->request->conf->socket_conf, data); 1447} --- 90 unchanged lines hidden (view full) --- 1538 return nxt_value_at(nxt_msec_t, joint->socket_conf, data); 1539} 1540 1541 1542static void 1543nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) 1544{ 1545 size_t size; |
1354 nxt_buf_t *in, *b, *next; | 1546 nxt_buf_t *in; |
1355 1356 nxt_debug(task, "h1p keepalive"); 1357 1358 if (!c->tcp_nodelay) { 1359 nxt_conn_tcp_nodelay_on(task, c); 1360 } 1361 | 1547 1548 nxt_debug(task, "h1p keepalive"); 1549 1550 if (!c->tcp_nodelay) { 1551 nxt_conn_tcp_nodelay_on(task, c); 1552 } 1553 |
1362 b = h1p->buffers; | 1554 nxt_h1p_complete_buffers(task, h1p); |
1363 | 1555 |
1556 in = c->read; 1557 |
|
1364 nxt_memzero(h1p, offsetof(nxt_h1proto_t, conn)); 1365 1366 c->sent = 0; 1367 | 1558 nxt_memzero(h1p, offsetof(nxt_h1proto_t, conn)); 1559 1560 c->sent = 0; 1561 |
1368 in = c->read; 1369 | |
1370 if (in == NULL) { | 1562 if (in == NULL) { |
1371 /* A request with large body. */ 1372 in = b; 1373 c->read = in; 1374 1375 b = in->next; 1376 in->next = NULL; 1377 } 1378 1379 while (b != NULL) { 1380 next = b->next; 1381 nxt_mp_free(c->mem_pool, b); 1382 b = next; 1383 } 1384 1385 size = nxt_buf_mem_used_size(&in->mem); 1386 1387 if (size == 0) { 1388 nxt_mp_free(c->mem_pool, in); 1389 1390 c->read = NULL; | |
1391 c->read_state = &nxt_h1p_keepalive_state; 1392 1393 nxt_conn_read(task->thread->engine, c); 1394 1395 } else { | 1563 c->read_state = &nxt_h1p_keepalive_state; 1564 1565 nxt_conn_read(task->thread->engine, c); 1566 1567 } else { |
1568 size = nxt_buf_mem_used_size(&in->mem); 1569 |
|
1396 nxt_debug(task, "h1p pipelining"); 1397 1398 nxt_memmove(in->mem.start, in->mem.pos, size); 1399 1400 in->mem.pos = in->mem.start; 1401 in->mem.free = in->mem.start + size; 1402 1403 nxt_h1p_conn_request_init(task, c, c->socket.data); --- 12 unchanged lines hidden (view full) --- 1416 1417 .timer_handler = nxt_h1p_idle_timeout, 1418 .timer_value = nxt_h1p_conn_timer_value, 1419 .timer_data = offsetof(nxt_socket_conf_t, idle_timeout), 1420 .timer_autoreset = 1, 1421}; 1422 1423 | 1570 nxt_debug(task, "h1p pipelining"); 1571 1572 nxt_memmove(in->mem.start, in->mem.pos, size); 1573 1574 in->mem.pos = in->mem.start; 1575 in->mem.free = in->mem.start + size; 1576 1577 nxt_h1p_conn_request_init(task, c, c->socket.data); --- 12 unchanged lines hidden (view full) --- 1590 1591 .timer_handler = nxt_h1p_idle_timeout, 1592 .timer_value = nxt_h1p_conn_timer_value, 1593 .timer_data = offsetof(nxt_socket_conf_t, idle_timeout), 1594 .timer_autoreset = 1, 1595}; 1596 1597 |
1424static const nxt_conn_state_t nxt_h1p_idle_close_state | 1598const nxt_conn_state_t nxt_h1p_idle_close_state |
1425 nxt_aligned(64) = 1426{ 1427 .close_handler = nxt_h1p_idle_close, 1428}; 1429 1430 1431static void 1432nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data) --- 126 unchanged lines hidden (view full) --- 1559{ 1560 return 10 * 1000; 1561} 1562 1563 1564static void 1565nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c) 1566{ | 1599 nxt_aligned(64) = 1600{ 1601 .close_handler = nxt_h1p_idle_close, 1602}; 1603 1604 1605static void 1606nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data) --- 126 unchanged lines hidden (view full) --- 1733{ 1734 return 10 * 1000; 1735} 1736 1737 1738static void 1739nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c) 1740{ |
1741 nxt_timer_t *timer; 1742 nxt_h1proto_t *h1p; 1743 |
|
1567 nxt_debug(task, "h1p shutdown"); 1568 | 1744 nxt_debug(task, "h1p shutdown"); 1745 |
1746 h1p = c->socket.data; 1747 1748 if (nxt_slow_path(h1p != NULL && h1p->websocket_timer != NULL)) { 1749 timer = &h1p->websocket_timer->timer; 1750 1751 if (timer->handler != nxt_h1p_conn_ws_shutdown) { 1752 timer->handler = nxt_h1p_conn_ws_shutdown; 1753 nxt_timer_add(task->thread->engine, timer, 0); 1754 1755 } else { 1756 nxt_debug(task, "h1p already scheduled ws shutdown"); 1757 } 1758 1759 } else { 1760 nxt_h1p_shutdown_(task, c); 1761 } 1762} 1763 1764 1765static void 1766nxt_h1p_shutdown_(nxt_task_t *task, nxt_conn_t *c) 1767{ |
|
1569 c->socket.data = NULL; 1570 1571#if (NXT_TLS) 1572 1573 if (c->u.tls != NULL) { 1574 c->write_state = &nxt_h1p_shutdown_state; 1575 1576 c->io->shutdown(task, c, NULL); --- 15 unchanged lines hidden (view full) --- 1592 .close_handler = nxt_h1p_conn_closing, 1593 .error_handler = nxt_h1p_conn_closing, 1594}; 1595 1596#endif 1597 1598 1599static void | 1768 c->socket.data = NULL; 1769 1770#if (NXT_TLS) 1771 1772 if (c->u.tls != NULL) { 1773 c->write_state = &nxt_h1p_shutdown_state; 1774 1775 c->io->shutdown(task, c, NULL); --- 15 unchanged lines hidden (view full) --- 1791 .close_handler = nxt_h1p_conn_closing, 1792 .error_handler = nxt_h1p_conn_closing, 1793}; 1794 1795#endif 1796 1797 1798static void |
1799nxt_h1p_conn_ws_shutdown(nxt_task_t *task, void *obj, void *data) 1800{ 1801 nxt_timer_t *timer; 1802 nxt_h1p_websocket_timer_t *ws_timer; 1803 1804 nxt_debug(task, "h1p conn ws shutdown"); 1805 1806 timer = obj; 1807 ws_timer = nxt_timer_data(timer, nxt_h1p_websocket_timer_t, timer); 1808 1809 nxt_h1p_shutdown_(task, ws_timer->h1p->conn); 1810} 1811 1812 1813static void |
|
1600nxt_h1p_conn_closing(nxt_task_t *task, void *obj, void *data) 1601{ 1602 nxt_conn_t *c; 1603 1604 c = obj; 1605 1606 nxt_debug(task, "h1p conn closing"); 1607 --- 36 unchanged lines hidden --- | 1814nxt_h1p_conn_closing(nxt_task_t *task, void *obj, void *data) 1815{ 1816 nxt_conn_t *c; 1817 1818 c = obj; 1819 1820 nxt_debug(task, "h1p conn closing"); 1821 --- 36 unchanged lines hidden --- |