113 | 113 |
u_char *pos, u_char *end);
|
114 | 114 |
static u_char *ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c,
|
115 | 115 |
u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
|
|
116 |
static u_char *ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c,
|
|
117 |
u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
|
116 | 118 |
static u_char *ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c,
|
117 | 119 |
ngx_uint_t err);
|
118 | 120 |
|
|
161 | 163 |
static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
|
162 | 164 |
static void ngx_http_v2_run_request(ngx_http_request_t *r);
|
163 | 165 |
static ngx_int_t ngx_http_v2_init_request_body(ngx_http_request_t *r);
|
|
166 |
static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r);
|
164 | 167 |
|
165 | 168 |
static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c,
|
166 | 169 |
ngx_http_v2_stream_t *stream, ngx_uint_t status);
|
|
429 | 432 |
"run http2 stream %ui", stream->node->id);
|
430 | 433 |
|
431 | 434 |
wev = stream->request->connection->write;
|
|
435 |
|
|
436 |
wev->active = 0;
|
|
437 |
wev->ready = 1;
|
|
438 |
|
432 | 439 |
wev->handler(wev);
|
433 | 440 |
}
|
434 | 441 |
|
|
882 | 889 |
ngx_buf_t *buf;
|
883 | 890 |
ngx_int_t rc;
|
884 | 891 |
ngx_temp_file_t *tf;
|
|
892 |
ngx_connection_t *fc;
|
885 | 893 |
ngx_http_request_t *r;
|
886 | 894 |
ngx_http_v2_stream_t *stream;
|
887 | 895 |
ngx_http_request_body_t *rb;
|
|
918 | 926 |
return ngx_http_v2_state_skip_padded(h2c, pos, end);
|
919 | 927 |
}
|
920 | 928 |
|
|
929 |
fc = r->connection;
|
921 | 930 |
rb = r->request_body;
|
922 | 931 |
tf = rb->temp_file;
|
923 | 932 |
buf = rb->buf;
|
|
928 | 937 |
if (r->headers_in.content_length_n != -1
|
929 | 938 |
&& r->headers_in.content_length_n < rb->rest)
|
930 | 939 |
{
|
931 | |
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
|
940 |
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
932 | 941 |
"client intended to send body data "
|
933 | 942 |
"larger than declared");
|
934 | 943 |
|
|
941 | 950 |
if (clcf->client_max_body_size
|
942 | 951 |
&& clcf->client_max_body_size < rb->rest)
|
943 | 952 |
{
|
944 | |
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
953 |
ngx_log_error(NGX_LOG_ERR, fc->log, 0,
|
945 | 954 |
"client intended to send "
|
946 | 955 |
"too large chunked body: %O bytes", rb->rest);
|
947 | 956 |
|
|
981 | 990 |
}
|
982 | 991 |
|
983 | 992 |
if (h2c->state.length) {
|
|
993 |
if (rb->post_handler) {
|
|
994 |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
995 |
ngx_add_timer(fc->read, clcf->client_body_timeout);
|
|
996 |
}
|
|
997 |
|
984 | 998 |
return ngx_http_v2_state_save(h2c, pos, end,
|
985 | 999 |
ngx_http_v2_state_read_data);
|
986 | 1000 |
}
|
|
992 | 1006 |
r->headers_in.content_length_n = rb->rest;
|
993 | 1007 |
|
994 | 1008 |
} else if (r->headers_in.content_length_n != rb->rest) {
|
995 | |
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
|
1009 |
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
996 | 1010 |
"client prematurely closed stream: "
|
997 | 1011 |
"only %O out of %O bytes of request body received",
|
998 | 1012 |
rb->rest, r->headers_in.content_length_n);
|
|
1012 | 1026 |
}
|
1013 | 1027 |
|
1014 | 1028 |
if (rb->post_handler) {
|
|
1029 |
if (fc->read->timer_set) {
|
|
1030 |
ngx_del_timer(fc->read);
|
|
1031 |
}
|
|
1032 |
|
1015 | 1033 |
r->read_event_handler = ngx_http_block_reading;
|
1016 | 1034 |
rb->post_handler(r);
|
1017 | 1035 |
}
|
|
1036 |
|
|
1037 |
} else if (rb->post_handler) {
|
|
1038 |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
1039 |
ngx_add_timer(fc->read, clcf->client_body_timeout);
|
1018 | 1040 |
}
|
1019 | 1041 |
|
1020 | 1042 |
if (h2c->state.padding) {
|
|
1026 | 1048 |
error:
|
1027 | 1049 |
|
1028 | 1050 |
if (rb->post_handler) {
|
|
1051 |
if (fc->read->timer_set) {
|
|
1052 |
ngx_del_timer(fc->read);
|
|
1053 |
}
|
1029 | 1054 |
|
1030 | 1055 |
if (stream->skip_data == NGX_HTTP_V2_DATA_ERROR) {
|
1031 | 1056 |
rc = (r->headers_in.content_length_n == -1)
|
|
1217 | 1242 |
ngx_uint_t indexed, size_update, prefix;
|
1218 | 1243 |
|
1219 | 1244 |
if (end - pos < 1) {
|
1220 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1221 | |
ngx_http_v2_state_header_block);
|
|
1245 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1246 |
ngx_http_v2_state_header_block);
|
1222 | 1247 |
}
|
1223 | 1248 |
|
1224 | 1249 |
if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
|
|
1261 | 1286 |
|
1262 | 1287 |
if (value < 0) {
|
1263 | 1288 |
if (value == NGX_AGAIN) {
|
1264 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1265 | |
ngx_http_v2_state_header_block);
|
|
1289 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1290 |
ngx_http_v2_state_header_block);
|
1266 | 1291 |
}
|
1267 | 1292 |
|
1268 | 1293 |
if (value == NGX_DECLINED) {
|
|
1332 | 1357 |
}
|
1333 | 1358 |
|
1334 | 1359 |
if (end - pos < 1) {
|
1335 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1336 | |
ngx_http_v2_state_field_len);
|
|
1360 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1361 |
ngx_http_v2_state_field_len);
|
1337 | 1362 |
}
|
1338 | 1363 |
|
1339 | 1364 |
huff = *pos >> 7;
|
|
1341 | 1366 |
|
1342 | 1367 |
if (len < 0) {
|
1343 | 1368 |
if (len == NGX_AGAIN) {
|
1344 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1345 | |
ngx_http_v2_state_field_len);
|
|
1369 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1370 |
ngx_http_v2_state_field_len);
|
1346 | 1371 |
}
|
1347 | 1372 |
|
1348 | 1373 |
if (len == NGX_DECLINED) {
|
|
1434 | 1459 |
}
|
1435 | 1460 |
|
1436 | 1461 |
if (h2c->state.length) {
|
1437 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1438 | |
ngx_http_v2_state_field_huff);
|
|
1462 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1463 |
ngx_http_v2_state_field_huff);
|
1439 | 1464 |
}
|
1440 | 1465 |
|
1441 | 1466 |
if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
|
|
1479 | 1504 |
}
|
1480 | 1505 |
|
1481 | 1506 |
if (h2c->state.length) {
|
1482 | |
return ngx_http_v2_state_save(h2c, pos, end,
|
1483 | |
ngx_http_v2_state_field_raw);
|
|
1507 |
return ngx_http_v2_state_headers_save(h2c, pos, end,
|
|
1508 |
ngx_http_v2_state_field_raw);
|
1484 | 1509 |
}
|
1485 | 1510 |
|
1486 | 1511 |
if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
|
|
1753 | 1778 |
}
|
1754 | 1779 |
|
1755 | 1780 |
if ((size_t) (end - pos) < len + NGX_HTTP_V2_FRAME_HEADER_SIZE) {
|
1756 | |
return ngx_http_v2_state_save(h2c, pos, end, handler);
|
|
1781 |
return ngx_http_v2_state_headers_save(h2c, pos, end, handler);
|
1757 | 1782 |
}
|
1758 | 1783 |
|
1759 | 1784 |
p = pos + len;
|
|
2228 | 2253 |
|
2229 | 2254 |
wev = stream->request->connection->write;
|
2230 | 2255 |
|
2231 | |
if (!wev->timer_set) {
|
2232 | |
wev->delayed = 0;
|
|
2256 |
wev->active = 0;
|
|
2257 |
wev->ready = 1;
|
|
2258 |
|
|
2259 |
if (!wev->delayed) {
|
2233 | 2260 |
wev->handler(wev);
|
2234 | 2261 |
}
|
2235 | 2262 |
}
|
|
2261 | 2288 |
|
2262 | 2289 |
wev = stream->request->connection->write;
|
2263 | 2290 |
|
2264 | |
if (!wev->timer_set) {
|
2265 | |
wev->delayed = 0;
|
|
2291 |
wev->active = 0;
|
|
2292 |
wev->ready = 1;
|
|
2293 |
|
|
2294 |
if (!wev->delayed) {
|
2266 | 2295 |
wev->handler(wev);
|
2267 | 2296 |
|
2268 | 2297 |
if (h2c->send_window == 0) {
|
|
2366 | 2395 |
h2c->state.incomplete = 1;
|
2367 | 2396 |
|
2368 | 2397 |
return end;
|
|
2398 |
}
|
|
2399 |
|
|
2400 |
|
|
2401 |
static u_char *
|
|
2402 |
ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|
2403 |
u_char *end, ngx_http_v2_handler_pt handler)
|
|
2404 |
{
|
|
2405 |
ngx_event_t *rev;
|
|
2406 |
ngx_http_request_t *r;
|
|
2407 |
ngx_http_core_srv_conf_t *cscf;
|
|
2408 |
|
|
2409 |
if (h2c->state.stream) {
|
|
2410 |
r = h2c->state.stream->request;
|
|
2411 |
rev = r->connection->read;
|
|
2412 |
|
|
2413 |
if (!rev->timer_set) {
|
|
2414 |
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
|
2415 |
ngx_add_timer(rev, cscf->client_header_timeout);
|
|
2416 |
}
|
|
2417 |
}
|
|
2418 |
|
|
2419 |
return ngx_http_v2_state_save(h2c, pos, end, handler);
|
2369 | 2420 |
}
|
2370 | 2421 |
|
2371 | 2422 |
|
|
2747 | 2798 |
ngx_memcpy(log, h2c->connection->log, sizeof(ngx_log_t));
|
2748 | 2799 |
|
2749 | 2800 |
log->data = ctx;
|
|
2801 |
log->action = "reading client request headers";
|
2750 | 2802 |
|
2751 | 2803 |
ngx_memzero(rev, sizeof(ngx_event_t));
|
2752 | 2804 |
|
|
3553 | 3605 |
ngx_http_v2_read_request_body(ngx_http_request_t *r,
|
3554 | 3606 |
ngx_http_client_body_handler_pt post_handler)
|
3555 | 3607 |
{
|
3556 | |
ngx_http_v2_stream_t *stream;
|
|
3608 |
ngx_http_v2_stream_t *stream;
|
|
3609 |
ngx_http_core_loc_conf_t *clcf;
|
3557 | 3610 |
|
3558 | 3611 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
3559 | 3612 |
"http2 read request body");
|
|
3589 | 3642 |
|
3590 | 3643 |
r->request_body->post_handler = post_handler;
|
3591 | 3644 |
|
3592 | |
r->read_event_handler = ngx_http_test_reading;
|
|
3645 |
r->read_event_handler = ngx_http_v2_read_client_request_body_handler;
|
3593 | 3646 |
r->write_event_handler = ngx_http_request_empty_handler;
|
3594 | 3647 |
|
|
3648 |
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
|
3649 |
ngx_add_timer(r->connection->read, clcf->client_body_timeout);
|
|
3650 |
|
3595 | 3651 |
return NGX_AGAIN;
|
|
3652 |
}
|
|
3653 |
|
|
3654 |
|
|
3655 |
static void
|
|
3656 |
ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r)
|
|
3657 |
{
|
|
3658 |
ngx_connection_t *fc;
|
|
3659 |
|
|
3660 |
fc = r->connection;
|
|
3661 |
|
|
3662 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
|
3663 |
"http2 read client request body handler");
|
|
3664 |
|
|
3665 |
if (fc->read->timedout) {
|
|
3666 |
ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");
|
|
3667 |
|
|
3668 |
fc->timedout = 1;
|
|
3669 |
r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD;
|
|
3670 |
|
|
3671 |
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
|
|
3672 |
return;
|
|
3673 |
}
|
|
3674 |
|
|
3675 |
if (fc->error) {
|
|
3676 |
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
|
|
3677 |
"client prematurely closed stream");
|
|
3678 |
|
|
3679 |
r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD;
|
|
3680 |
|
|
3681 |
ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
|
|
3682 |
return;
|
|
3683 |
}
|
3596 | 3684 |
}
|
3597 | 3685 |
|
3598 | 3686 |
|
|
3646 | 3734 |
|
3647 | 3735 |
if (!stream->out_closed) {
|
3648 | 3736 |
if (ngx_http_v2_send_rst_stream(h2c, node->id,
|
3649 | |
NGX_HTTP_V2_INTERNAL_ERROR)
|
|
3737 |
fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR
|
|
3738 |
: NGX_HTTP_V2_INTERNAL_ERROR)
|
3650 | 3739 |
!= NGX_OK)
|
3651 | 3740 |
{
|
3652 | 3741 |
h2c->connection->error = 1;
|
|
3683 | 3772 |
|
3684 | 3773 |
ev = fc->read;
|
3685 | 3774 |
|
3686 | |
if (ev->active || ev->disabled) {
|
3687 | |
ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
|
3688 | |
"fake read event was activated");
|
3689 | |
}
|
3690 | |
|
3691 | 3775 |
if (ev->timer_set) {
|
3692 | 3776 |
ngx_del_timer(ev);
|
3693 | 3777 |
}
|
|
3698 | 3782 |
|
3699 | 3783 |
ev = fc->write;
|
3700 | 3784 |
|
3701 | |
if (ev->active || ev->disabled) {
|
3702 | |
ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
|
3703 | |
"fake write event was activated");
|
3704 | |
}
|
3705 | |
|
3706 | 3785 |
if (ev->timer_set) {
|
3707 | 3786 |
ngx_del_timer(ev);
|
3708 | 3787 |
}
|
|
3736 | 3815 |
fc = ev->data;
|
3737 | 3816 |
r = fc->data;
|
3738 | 3817 |
|
3739 | |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
|
3818 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
3740 | 3819 |
"http2 close stream handler");
|
|
3820 |
|
|
3821 |
if (ev->timedout) {
|
|
3822 |
ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");
|
|
3823 |
|
|
3824 |
fc->timedout = 1;
|
|
3825 |
|
|
3826 |
ngx_http_v2_close_stream(r->stream, NGX_HTTP_REQUEST_TIME_OUT);
|
|
3827 |
return;
|
|
3828 |
}
|
3741 | 3829 |
|
3742 | 3830 |
ngx_http_v2_close_stream(r->stream, 0);
|
3743 | 3831 |
}
|
|
3746 | 3834 |
static void
|
3747 | 3835 |
ngx_http_v2_handle_connection_handler(ngx_event_t *rev)
|
3748 | 3836 |
{
|
3749 | |
ngx_connection_t *c;
|
|
3837 |
ngx_connection_t *c;
|
|
3838 |
ngx_http_v2_connection_t *h2c;
|
|
3839 |
|
|
3840 |
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
|
|
3841 |
"http2 handle connection handler");
|
3750 | 3842 |
|
3751 | 3843 |
rev->handler = ngx_http_v2_read_handler;
|
3752 | 3844 |
|
|
3756 | 3848 |
}
|
3757 | 3849 |
|
3758 | 3850 |
c = rev->data;
|
|
3851 |
h2c = c->data;
|
|
3852 |
|
|
3853 |
if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
|
|
3854 |
ngx_http_v2_finalize_connection(h2c, 0);
|
|
3855 |
return;
|
|
3856 |
}
|
3759 | 3857 |
|
3760 | 3858 |
ngx_http_v2_handle_connection(c->data);
|
3761 | 3859 |
}
|
|
3877 | 3975 |
|
3878 | 3976 |
if (stream->queued) {
|
3879 | 3977 |
stream->queued = 0;
|
3880 | |
|
3881 | 3978 |
ev = fc->write;
|
3882 | |
ev->delayed = 0;
|
3883 | 3979 |
|
3884 | 3980 |
} else {
|
3885 | 3981 |
ev = fc->read;
|
|
3948 | 4044 |
|
3949 | 4045 |
wev = stream->request->connection->write;
|
3950 | 4046 |
|
3951 | |
if (!wev->timer_set) {
|
3952 | |
wev->delayed = 0;
|
|
4047 |
wev->active = 0;
|
|
4048 |
wev->ready = 1;
|
|
4049 |
|
|
4050 |
if (!wev->delayed) {
|
3953 | 4051 |
wev->handler(wev);
|
3954 | 4052 |
}
|
3955 | 4053 |
}
|