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> 12 13 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) 21 static ssize_t nxt_http_idle_io_read_handler(nxt_conn_t *c); 22 static void nxt_http_conn_test(nxt_task_t *task, void *obj, void *data); 23 #endif 24 static ssize_t nxt_h1p_idle_io_read_handler(nxt_conn_t *c); 25 static void nxt_h1p_conn_proto_init(nxt_task_t *task, void *obj, void *data); 26 static void nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data); 27 static void nxt_h1p_conn_request_header_parse(nxt_task_t *task, void *obj, 28 void *data); 29 static nxt_int_t nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p, 30 nxt_http_request_t *r); 31 static 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); 33 static nxt_int_t nxt_h1p_connection(void *ctx, nxt_http_field_t *field, 34 uintptr_t data); 35 static nxt_int_t nxt_h1p_upgrade(void *ctx, nxt_http_field_t *field, 36 uintptr_t data); 37 static nxt_int_t nxt_h1p_websocket_key(void *ctx, nxt_http_field_t *field, 38 uintptr_t data); 39 static nxt_int_t nxt_h1p_websocket_version(void *ctx, nxt_http_field_t *field, 40 uintptr_t data); 41 static nxt_int_t nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, 42 uintptr_t data); 43 static void nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r); 44 static void nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, 45 void *data); 46 static void nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r); 47 static void nxt_h1p_request_header_send(nxt_task_t *task, 48 nxt_http_request_t *r); 49 static void nxt_h1p_request_send(nxt_task_t *task, nxt_http_request_t *r, 50 nxt_buf_t *out); 51 static nxt_buf_t *nxt_h1p_chunk_create(nxt_task_t *task, nxt_http_request_t *r, 52 nxt_buf_t *out); 53 static nxt_off_t nxt_h1p_request_body_bytes_sent(nxt_task_t *task, 54 nxt_http_proto_t proto); 55 static void nxt_h1p_request_discard(nxt_task_t *task, nxt_http_request_t *r, 56 nxt_buf_t *last); 57 static void nxt_h1p_conn_request_error(nxt_task_t *task, void *obj, void *data); 58 static void nxt_h1p_conn_request_timeout(nxt_task_t *task, void *obj, 59 void *data); 60 static void nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, 61 void *data); 62 nxt_inline void nxt_h1p_request_error(nxt_task_t *task, nxt_h1proto_t *h1p, 63 nxt_http_request_t *r); 64 static void nxt_h1p_request_close(nxt_task_t *task, nxt_http_proto_t proto, 65 nxt_socket_conf_joint_t *joint); 66 static void nxt_h1p_conn_sent(nxt_task_t *task, void *obj, void *data); 67 static void nxt_h1p_conn_close(nxt_task_t *task, void *obj, void *data); 68 static void nxt_h1p_conn_error(nxt_task_t *task, void *obj, void *data); 69 static nxt_msec_t nxt_h1p_conn_timer_value(nxt_conn_t *c, uintptr_t data); 70 static void nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, 71 nxt_conn_t *c); 72 static void nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data); 73 static void nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data); 74 static void nxt_h1p_idle_response(nxt_task_t *task, nxt_conn_t *c); 75 static void nxt_h1p_idle_response_sent(nxt_task_t *task, void *obj, void *data); 76 static void nxt_h1p_idle_response_timeout(nxt_task_t *task, void *obj, 77 void *data); 78 static nxt_msec_t nxt_h1p_idle_response_timer_value(nxt_conn_t *c, 79 uintptr_t data); 80 static void nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c); 81 static void nxt_h1p_shutdown_(nxt_task_t *task, nxt_conn_t *c); 82 static void nxt_h1p_conn_ws_shutdown(nxt_task_t *task, void *obj, void *data); 83 static void nxt_h1p_conn_closing(nxt_task_t *task, void *obj, void *data); 84 static void nxt_h1p_conn_free(nxt_task_t *task, void *obj, void *data); 85 86 #if (NXT_TLS) 87 static const nxt_conn_state_t nxt_http_idle_state; 88 static const nxt_conn_state_t nxt_h1p_shutdown_state; 89 #endif 90 static const nxt_conn_state_t nxt_h1p_idle_state; 91 static const nxt_conn_state_t nxt_h1p_header_parse_state; 92 static const nxt_conn_state_t nxt_h1p_read_body_state; 93 static const nxt_conn_state_t nxt_h1p_request_send_state; 94 static const nxt_conn_state_t nxt_h1p_timeout_response_state; 95 static const nxt_conn_state_t nxt_h1p_keepalive_state; 96 static const nxt_conn_state_t nxt_h1p_close_state; 97 98 99 const 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, 110 }, 111 /* NXT_HTTP_PROTO_H2 */ 112 /* NXT_HTTP_PROTO_DEVNULL */ 113 }; 114 115 116 static nxt_lvlhsh_t nxt_h1p_fields_hash; 117 118 static 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 }, 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, 132 offsetof(nxt_http_request_t, user_agent) }, 133 { nxt_string("Content-Type"), &nxt_http_request_field, 134 offsetof(nxt_http_request_t, content_type) }, 135 { nxt_string("Content-Length"), &nxt_http_request_content_length, 0 }, 136 }; 137 138 139 nxt_int_t 140 nxt_h1p_init(nxt_task_t *task, nxt_runtime_t *rt) 141 { 142 return nxt_http_fields_hash(&nxt_h1p_fields_hash, rt->mem_pool, 143 nxt_h1p_fields, nxt_nitems(nxt_h1p_fields)); 144 } 145 146 147 void 148 nxt_http_conn_init(nxt_task_t *task, void *obj, void *data) 149 { 150 nxt_conn_t *c; 151 nxt_socket_conf_t *skcf; 152 nxt_event_engine_t *engine; 153 nxt_listen_event_t *lev; 154 nxt_socket_conf_joint_t *joint; 155 156 c = obj; 157 lev = data; 158 159 nxt_debug(task, "http conn init"); 160 161 joint = lev->socket.data; 162 skcf = joint->socket_conf; 163 c->local = skcf->sockaddr; 164 165 engine = task->thread->engine; 166 c->read_work_queue = &engine->fast_work_queue; 167 c->write_work_queue = &engine->fast_work_queue; 168 169 c->read_state = &nxt_h1p_idle_state; 170 171 #if (NXT_TLS) 172 if (skcf->tls != NULL) { 173 c->read_state = &nxt_http_idle_state; 174 } 175 #endif 176 177 nxt_conn_read(engine, c); 178 } 179 180 181 #if (NXT_TLS) 182 183 static const nxt_conn_state_t nxt_http_idle_state 184 nxt_aligned(64) = 185 { 186 .ready_handler = nxt_http_conn_test, 187 .close_handler = nxt_h1p_conn_close, 188 .error_handler = nxt_h1p_conn_error, 189 190 .io_read_handler = nxt_http_idle_io_read_handler, 191 192 .timer_handler = nxt_h1p_idle_timeout, 193 .timer_value = nxt_h1p_conn_timer_value, 194 .timer_data = offsetof(nxt_socket_conf_t, idle_timeout), 195 }; 196 197 198 static ssize_t 199 nxt_http_idle_io_read_handler(nxt_conn_t *c) 200 { 201 size_t size; 202 ssize_t n; 203 nxt_buf_t *b; 204 nxt_socket_conf_joint_t *joint; 205 206 joint = c->listen->socket.data; 207 208 if (nxt_slow_path(joint == NULL)) { 209 /* 210 * Listening socket had been closed while 211 * connection was in keep-alive state. 212 */ 213 c->read_state = &nxt_h1p_idle_close_state; 214 return 0; 215 } 216 217 size = joint->socket_conf->header_buffer_size; 218 219 b = nxt_buf_mem_alloc(c->mem_pool, size, 0); 220 if (nxt_slow_path(b == NULL)) { 221 c->socket.error = NXT_ENOMEM; 222 return NXT_ERROR; 223 } 224 225 /* 226 * 1 byte is enough to distinguish between SSLv3/TLS and plain HTTP. 227 * 11 bytes are enough to log supported SSLv3/TLS version. 228 * 16 bytes are just for more optimized kernel copy-out operation. 229 */ 230 n = c->io->recv(c, b->mem.pos, 16, MSG_PEEK); 231 232 if (n > 0) { 233 c->read = b; 234 235 } else { 236 c->read = NULL; 237 nxt_mp_free(c->mem_pool, b); 238 } 239 240 return n; 241 } 242 243 244 static void 245 nxt_http_conn_test(nxt_task_t *task, void *obj, void *data) 246 { 247 u_char *p; 248 nxt_buf_t *b; 249 nxt_conn_t *c; 250 nxt_tls_conf_t *tls; 251 nxt_socket_conf_joint_t *joint; 252 253 c = obj; 254 255 nxt_debug(task, "h1p conn https test"); 256 257 b = c->read; 258 p = b->mem.pos; 259 260 c->read_state = &nxt_h1p_idle_state; 261 262 if (p[0] != 0x16) { 263 b->mem.free = b->mem.pos; 264 265 nxt_conn_read(task->thread->engine, c); 266 return; 267 } 268 269 /* SSLv3/TLS ClientHello message. */ 270 271 #if (NXT_DEBUG) 272 if (nxt_buf_mem_used_size(&b->mem) >= 11) { 273 u_char major, minor; 274 const char *protocol; 275 276 major = p[9]; 277 minor = p[10]; 278 279 if (major == 3) { 280 if (minor == 0) { 281 protocol = "SSLv"; 282 283 } else { 284 protocol = "TLSv"; 285 major -= 2; 286 minor -= 1; 287 } 288 289 nxt_debug(task, "SSL/TLS: %s%ud.%ud", protocol, major, minor); 290 } 291 } 292 #endif 293 294 c->read = NULL; 295 nxt_mp_free(c->mem_pool, b); 296 297 joint = c->listen->socket.data; 298 299 if (nxt_slow_path(joint == NULL)) { 300 /* 301 * Listening socket had been closed while 302 * connection was in keep-alive state. 303 */ 304 nxt_h1p_shutdown(task, c); 305 return; 306 } 307 308 tls = joint->socket_conf->tls; 309 310 tls->conn_init(task, tls, c); 311 } 312 313 #endif 314 315 316 static const nxt_conn_state_t nxt_h1p_idle_state 317 nxt_aligned(64) = 318 { 319 .ready_handler = nxt_h1p_conn_proto_init, 320 .close_handler = nxt_h1p_conn_close, 321 .error_handler = nxt_h1p_conn_error, 322 323 .io_read_handler = nxt_h1p_idle_io_read_handler, 324 325 .timer_handler = nxt_h1p_idle_timeout, 326 .timer_value = nxt_h1p_conn_timer_value, 327 .timer_data = offsetof(nxt_socket_conf_t, idle_timeout), 328 .timer_autoreset = 1, 329 }; 330 331 332 static ssize_t 333 nxt_h1p_idle_io_read_handler(nxt_conn_t *c) 334 { 335 size_t size; 336 ssize_t n; 337 nxt_buf_t *b; 338 nxt_socket_conf_joint_t *joint; 339 340 joint = c->listen->socket.data; 341 342 if (nxt_slow_path(joint == NULL)) { 343 /* 344 * Listening socket had been closed while 345 * connection was in keep-alive state. 346 */ 347 c->read_state = &nxt_h1p_idle_close_state; 348 return 0; 349 } 350 351 b = c->read; 352 353 if (b == NULL) { 354 size = joint->socket_conf->header_buffer_size; 355 356 b = nxt_buf_mem_alloc(c->mem_pool, size, 0); 357 if (nxt_slow_path(b == NULL)) { 358 c->socket.error = NXT_ENOMEM; 359 return NXT_ERROR; 360 } 361 } 362 363 n = c->io->recvbuf(c, b); 364 365 if (n > 0) { 366 c->read = b; 367 368 } else { 369 c->read = NULL; 370 nxt_mp_free(c->mem_pool, b); 371 } 372 373 return n; 374 } 375 376 377 static void 378 nxt_h1p_conn_proto_init(nxt_task_t *task, void *obj, void *data) 379 { 380 nxt_conn_t *c; 381 nxt_h1proto_t *h1p; 382 383 c = obj; 384 385 nxt_debug(task, "h1p conn proto init"); 386 387 h1p = nxt_mp_zget(c->mem_pool, sizeof(nxt_h1proto_t)); 388 if (nxt_slow_path(h1p == NULL)) { 389 nxt_h1p_shutdown(task, c); 390 return; 391 } 392 393 c->socket.data = h1p; 394 h1p->conn = c; 395 396 nxt_h1p_conn_request_init(task, c, h1p); 397 } 398 399 400 static void 401 nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data) 402 { 403 nxt_int_t ret; 404 nxt_conn_t *c; 405 nxt_h1proto_t *h1p; 406 nxt_http_request_t *r; 407 nxt_socket_conf_joint_t *joint; 408 409 c = obj; 410 h1p = data; 411 412 nxt_debug(task, "h1p conn request init"); 413 414 r = nxt_http_request_create(task); 415 416 if (nxt_fast_path(r != NULL)) { 417 h1p->request = r; 418 r->proto.h1 = h1p; 419 420 /* r->protocol = NXT_HTTP_PROTO_H1 is done by zeroing. */ 421 r->remote = c->remote; 422 423 #if (NXT_TLS) 424 r->tls = c->u.tls; 425 #endif 426 427 ret = nxt_http_parse_request_init(&h1p->parser, r->mem_pool); 428 429 if (nxt_fast_path(ret == NXT_OK)) { 430 joint = c->listen->socket.data; 431 joint->count++; 432 433 r->conf = joint; 434 c->local = joint->socket_conf->sockaddr; 435 436 nxt_h1p_conn_request_header_parse(task, c, h1p); 437 return; 438 } 439 440 /* 441 * The request is very incomplete here, 442 * so "internal server error" useless here. 443 */ 444 nxt_mp_release(r->mem_pool); 445 } 446 447 nxt_h1p_shutdown(task, c); 448 } 449 450 451 static const nxt_conn_state_t nxt_h1p_header_parse_state 452 nxt_aligned(64) = 453 { 454 .ready_handler = nxt_h1p_conn_request_header_parse, 455 .close_handler = nxt_h1p_conn_request_error, 456 .error_handler = nxt_h1p_conn_request_error, 457 458 .timer_handler = nxt_h1p_conn_request_timeout, 459 .timer_value = nxt_h1p_conn_request_timer_value, 460 .timer_data = offsetof(nxt_socket_conf_t, header_read_timeout), 461 }; 462 463 464 static void 465 nxt_h1p_conn_request_header_parse(nxt_task_t *task, void *obj, void *data) 466 { 467 nxt_int_t ret; 468 nxt_conn_t *c; 469 nxt_h1proto_t *h1p; 470 nxt_http_status_t status; 471 nxt_http_request_t *r; 472 473 c = obj; 474 h1p = data; 475 476 nxt_debug(task, "h1p conn header parse"); 477 478 ret = nxt_http_parse_request(&h1p->parser, &c->read->mem); 479 480 ret = nxt_expect(NXT_DONE, ret); 481 482 if (ret != NXT_AGAIN) { 483 nxt_timer_disable(task->thread->engine, &c->read_timer); 484 } 485 486 r = h1p->request; 487 488 switch (ret) { 489 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 498 ret = nxt_h1p_header_process(task, h1p, r); 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 } 507 #endif 508 509 r->state->ready_handler(task, r, NULL); 510 return; 511 } 512 513 status = ret; 514 goto error; 515 516 case NXT_AGAIN: 517 status = nxt_h1p_header_buffer_test(task, h1p, c, r->conf->socket_conf); 518 519 if (nxt_fast_path(status == NXT_OK)) { 520 c->read_state = &nxt_h1p_header_parse_state; 521 522 nxt_conn_read(task->thread->engine, c); 523 return; 524 } 525 526 break; 527 528 case NXT_HTTP_PARSE_INVALID: 529 status = NXT_HTTP_BAD_REQUEST; 530 break; 531 532 case NXT_HTTP_PARSE_UNSUPPORTED_VERSION: 533 status = NXT_HTTP_VERSION_NOT_SUPPORTED; 534 break; 535 536 case NXT_HTTP_PARSE_TOO_LARGE_FIELD: 537 status = NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; 538 break; 539 540 default: 541 case NXT_ERROR: 542 status = NXT_HTTP_INTERNAL_SERVER_ERROR; 543 break; 544 } 545 546 (void) nxt_h1p_header_process(task, h1p, r); 547 548 error: 549 550 h1p->keepalive = 0; 551 552 nxt_http_request_error(task, r, status); 553 } 554 555 556 static nxt_int_t 557 nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p, 558 nxt_http_request_t *r) 559 { 560 u_char *m; 561 nxt_int_t ret; 562 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 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; 617 } 618 619 620 static nxt_int_t 621 nxt_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; 625 nxt_buf_t *in, *b; 626 627 in = c->read; 628 629 if (nxt_buf_mem_free_size(&in->mem) == 0) { 630 size = skcf->large_header_buffer_size; 631 used = nxt_buf_mem_used_size(&in->mem); 632 633 if (size <= used || h1p->nbuffers >= skcf->large_header_buffers) { 634 return NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; 635 } 636 637 b = nxt_buf_mem_alloc(c->mem_pool, size, 0); 638 if (nxt_slow_path(b == NULL)) { 639 return NXT_HTTP_INTERNAL_SERVER_ERROR; 640 } 641 642 b->mem.free = nxt_cpymem(b->mem.pos, in->mem.pos, used); 643 644 in->next = h1p->buffers; 645 h1p->buffers = in; 646 h1p->nbuffers++; 647 648 c->read = b; 649 } 650 651 return NXT_OK; 652 } 653 654 655 static nxt_int_t 656 nxt_h1p_connection(void *ctx, nxt_http_field_t *field, uintptr_t data) 657 { 658 nxt_http_request_t *r; 659 static const u_char *upgrade = (const u_char *) "upgrade"; 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; 670 } 671 672 return NXT_OK; 673 } 674 675 676 static nxt_int_t 677 nxt_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 694 static nxt_int_t 695 nxt_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 709 static nxt_int_t 710 nxt_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 726 static nxt_int_t 727 nxt_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 735 && nxt_memcmp(field->value, "chunked", 7) == 0) 736 { 737 te = NXT_HTTP_TE_CHUNKED; 738 739 } else { 740 te = NXT_HTTP_TE_UNSUPPORTED; 741 } 742 743 r->proto.h1->transfer_encoding = te; 744 745 return NXT_OK; 746 } 747 748 749 static void 750 nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) 751 { 752 size_t size, body_length; 753 nxt_buf_t *in, *b; 754 nxt_conn_t *c; 755 nxt_h1proto_t *h1p; 756 nxt_http_status_t status; 757 758 h1p = r->proto.h1; 759 760 nxt_debug(task, "h1p request body read %O te:%d", 761 r->content_length_n, h1p->transfer_encoding); 762 763 switch (h1p->transfer_encoding) { 764 765 case NXT_HTTP_TE_CHUNKED: 766 status = NXT_HTTP_LENGTH_REQUIRED; 767 goto error; 768 769 case NXT_HTTP_TE_UNSUPPORTED: 770 status = NXT_HTTP_NOT_IMPLEMENTED; 771 goto error; 772 773 default: 774 case NXT_HTTP_TE_NONE: 775 break; 776 } 777 778 if (r->content_length_n == -1 || r->content_length_n == 0) { 779 goto ready; 780 } 781 782 if (r->content_length_n > (nxt_off_t) r->conf->socket_conf->max_body_size) { 783 status = NXT_HTTP_PAYLOAD_TOO_LARGE; 784 goto error; 785 } 786 787 body_length = (size_t) r->content_length_n; 788 789 b = r->body; 790 791 if (b == NULL) { 792 b = nxt_buf_mem_alloc(r->mem_pool, body_length, 0); 793 if (nxt_slow_path(b == NULL)) { 794 status = NXT_HTTP_INTERNAL_SERVER_ERROR; 795 goto error; 796 } 797 798 r->body = b; 799 } 800 801 in = h1p->conn->read; 802 803 size = nxt_buf_mem_used_size(&in->mem); 804 805 if (size != 0) { 806 if (size > body_length) { 807 size = body_length; 808 } 809 810 b->mem.free = nxt_cpymem(b->mem.free, in->mem.pos, size); 811 in->mem.pos += size; 812 } 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++; 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 } 830 831 ready: 832 833 nxt_work_queue_add(&task->thread->engine->fast_work_queue, 834 r->state->ready_handler, task, r, NULL); 835 836 return; 837 838 error: 839 840 h1p->keepalive = 0; 841 842 nxt_http_request_error(task, r, status); 843 } 844 845 846 static const nxt_conn_state_t nxt_h1p_read_body_state 847 nxt_aligned(64) = 848 { 849 .ready_handler = nxt_h1p_conn_request_body_read, 850 .close_handler = nxt_h1p_conn_request_error, 851 .error_handler = nxt_h1p_conn_request_error, 852 853 .timer_handler = nxt_h1p_conn_request_timeout, 854 .timer_value = nxt_h1p_conn_request_timer_value, 855 .timer_data = offsetof(nxt_socket_conf_t, body_read_timeout), 856 .timer_autoreset = 1, 857 }; 858 859 860 static void 861 nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data) 862 { 863 size_t size; 864 nxt_conn_t *c; 865 nxt_h1proto_t *h1p; 866 nxt_http_request_t *r; 867 nxt_event_engine_t *engine; 868 869 c = obj; 870 h1p = data; 871 872 nxt_debug(task, "h1p conn request body read"); 873 874 size = nxt_buf_mem_free_size(&c->read->mem); 875 876 nxt_debug(task, "h1p body rest: %uz", size); 877 878 engine = task->thread->engine; 879 880 if (size != 0) { 881 nxt_conn_read(engine, c); 882 883 } else { 884 c->read = NULL; 885 r = h1p->request; 886 887 nxt_work_queue_add(&engine->fast_work_queue, r->state->ready_handler, 888 task, r, NULL); 889 } 890 } 891 892 893 static void 894 nxt_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 903 static 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 909 #define NXT_HTTP_LAST_SUCCESS \ 910 (NXT_HTTP_OK + nxt_nitems(nxt_http_success) - 1) 911 912 static 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"), 917 nxt_string("HTTP/1.1 204 No Content\r\n"), 918 nxt_string("HTTP/1.1 205 Reset Content\r\n"), 919 nxt_string("HTTP/1.1 206 Partial Content\r\n"), 920 }; 921 922 923 #define NXT_HTTP_LAST_REDIRECTION \ 924 (NXT_HTTP_MULTIPLE_CHOICES + nxt_nitems(nxt_http_redirection) - 1) 925 926 static const nxt_str_t nxt_http_redirection[] = { 927 nxt_string("HTTP/1.1 300 Multiple Choices\r\n"), 928 nxt_string("HTTP/1.1 301 Moved Permanently\r\n"), 929 nxt_string("HTTP/1.1 302 Found\r\n"), 930 nxt_string("HTTP/1.1 303 See Other\r\n"), 931 nxt_string("HTTP/1.1 304 Not Modified\r\n"), 932 }; 933 934 935 #define NXT_HTTP_LAST_CLIENT_ERROR \ 936 (NXT_HTTP_BAD_REQUEST + nxt_nitems(nxt_http_client_error) - 1) 937 938 static const nxt_str_t nxt_http_client_error[] = { 939 nxt_string("HTTP/1.1 400 Bad Request\r\n"), 940 nxt_string("HTTP/1.1 401 Unauthorized\r\n"), 941 nxt_string("HTTP/1.1 402 Payment Required\r\n"), 942 nxt_string("HTTP/1.1 403 Forbidden\r\n"), 943 nxt_string("HTTP/1.1 404 Not Found\r\n"), 944 nxt_string("HTTP/1.1 405 Method Not Allowed\r\n"), 945 nxt_string("HTTP/1.1 406 Not Acceptable\r\n"), 946 nxt_string("HTTP/1.1 407 Proxy Authentication Required\r\n"), 947 nxt_string("HTTP/1.1 408 Request Timeout\r\n"), 948 nxt_string("HTTP/1.1 409 Conflict\r\n"), 949 nxt_string("HTTP/1.1 410 Gone\r\n"), 950 nxt_string("HTTP/1.1 411 Length Required\r\n"), 951 nxt_string("HTTP/1.1 412 Precondition Failed\r\n"), 952 nxt_string("HTTP/1.1 413 Payload Too Large\r\n"), 953 nxt_string("HTTP/1.1 414 URI Too Long\r\n"), 954 nxt_string("HTTP/1.1 415 Unsupported Media Type\r\n"), 955 nxt_string("HTTP/1.1 416 Range Not Satisfiable\r\n"), 956 nxt_string("HTTP/1.1 417 Expectation Failed\r\n"), 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"), 965 nxt_string("HTTP/1.1 426 Upgrade Required\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 974 #define NXT_HTTP_LAST_NGINX_ERROR \ 975 (NXT_HTTP_TO_HTTPS + nxt_nitems(nxt_http_nginx_error) - 1) 976 977 static const nxt_str_t nxt_http_nginx_error[] = { 978 nxt_string("HTTP/1.1 400 " 979 "The plain HTTP request was sent to HTTPS port\r\n"), 980 }; 981 982 983 #define NXT_HTTP_LAST_SERVER_ERROR \ 984 (NXT_HTTP_INTERNAL_SERVER_ERROR + nxt_nitems(nxt_http_server_error) - 1) 985 986 static const nxt_str_t nxt_http_server_error[] = { 987 nxt_string("HTTP/1.1 500 Internal Server Error\r\n"), 988 nxt_string("HTTP/1.1 501 Not Implemented\r\n"), 989 nxt_string("HTTP/1.1 502 Bad Gateway\r\n"), 990 nxt_string("HTTP/1.1 503 Service Unavailable\r\n"), 991 nxt_string("HTTP/1.1 504 Gateway Timeout\r\n"), 992 nxt_string("HTTP/1.1 505 HTTP Version Not Supported\r\n"), 993 }; 994 995 996 #define UNKNOWN_STATUS_LENGTH nxt_length("HTTP/1.1 65536\r\n") 997 998 static void 999 nxt_h1p_request_header_send(nxt_task_t *task, nxt_http_request_t *r) 1000 { 1001 u_char *p; 1002 size_t size; 1003 nxt_buf_t *header; 1004 nxt_str_t unknown_status; 1005 nxt_int_t conn; 1006 nxt_uint_t n; 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"; 1016 1017 static const nxt_str_t connection[3] = { 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: "), 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 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) { 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) { 1043 status = &nxt_http_client_error[n - NXT_HTTP_BAD_REQUEST]; 1044 1045 } else if (n >= NXT_HTTP_TO_HTTPS && n <= NXT_HTTP_LAST_NGINX_ERROR) { 1046 status = &nxt_http_nginx_error[n - NXT_HTTP_TO_HTTPS]; 1047 1048 } else if (n >= NXT_HTTP_INTERNAL_SERVER_ERROR 1049 && n <= NXT_HTTP_LAST_SERVER_ERROR) 1050 { 1051 status = &nxt_http_server_error[n - NXT_HTTP_INTERNAL_SERVER_ERROR]; 1052 1053 } else { 1054 p = nxt_sprintf(buf, buf + UNKNOWN_STATUS_LENGTH, 1055 "HTTP/1.1 %03d\r\n", n); 1056 1057 unknown_status.length = p - buf; 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 1066 conn = -1; 1067 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; 1073 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; 1092 } 1093 } 1094 1095 if (http11 ^ h1p->keepalive) { 1096 conn = h1p->keepalive; 1097 } 1098 } 1099 1100 if (conn >= 0) { 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 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 1123 p = nxt_cpymem(header->mem.free, status->start, status->length); 1124 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 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 } 1173 } 1174 1175 1176 void 1177 nxt_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 1224 static 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, 1232 .timer_data = offsetof(nxt_socket_conf_t, send_timeout), 1233 .timer_autoreset = 1, 1234 }; 1235 1236 1237 static void 1238 nxt_h1p_request_send(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out) 1239 { 1240 nxt_conn_t *c; 1241 nxt_h1proto_t *h1p; 1242 1243 nxt_debug(task, "h1p request send"); 1244 1245 h1p = r->proto.h1; 1246 c = h1p->conn; 1247 1248 if (h1p->chunked) { 1249 out = nxt_h1p_chunk_create(task, r, out); 1250 if (nxt_slow_path(out == NULL)) { 1251 nxt_h1p_request_error(task, h1p, r); 1252 return; 1253 } 1254 } 1255 1256 if (c->write == NULL) { 1257 c->write = out; 1258 c->write_state = &nxt_h1p_request_send_state; 1259 1260 nxt_conn_write(task->thread->engine, c); 1261 1262 } else { 1263 nxt_buf_chain_add(&c->write, out); 1264 } 1265 } 1266 1267 1268 static nxt_buf_t * 1269 nxt_h1p_chunk_create(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out) 1270 { 1271 nxt_off_t size; 1272 nxt_buf_t *b, **prev, *header, *tail; 1273 1274 const size_t chunk_size = 2 * nxt_length("\r\n") + NXT_OFF_T_HEXLEN; 1275 static const char tail_chunk[] = "\r\n0\r\n\r\n"; 1276 1277 size = 0; 1278 prev = &out; 1279 1280 for (b = out; b != NULL; b = b->next) { 1281 1282 if (nxt_buf_is_last(b)) { 1283 tail = nxt_http_buf_mem(task, r, chunk_size); 1284 if (nxt_slow_path(tail == NULL)) { 1285 return NULL; 1286 } 1287 1288 *prev = tail; 1289 tail->next = b; 1290 /* 1291 * The tail_chunk size with trailing zero is 8 bytes, so 1292 * memcpy may be inlined with just single 8 byte move operation. 1293 */ 1294 nxt_memcpy(tail->mem.free, tail_chunk, sizeof(tail_chunk)); 1295 tail->mem.free += nxt_length(tail_chunk); 1296 1297 break; 1298 } 1299 1300 size += nxt_buf_used_size(b); 1301 prev = &b->next; 1302 } 1303 1304 if (size == 0) { 1305 return out; 1306 } 1307 1308 header = nxt_http_buf_mem(task, r, chunk_size); 1309 if (nxt_slow_path(header == NULL)) { 1310 return NULL; 1311 } 1312 1313 header->next = out; 1314 header->mem.free = nxt_sprintf(header->mem.free, header->mem.end, 1315 "\r\n%xO\r\n", size); 1316 return header; 1317 } 1318 1319 1320 static nxt_off_t 1321 nxt_h1p_request_body_bytes_sent(nxt_task_t *task, nxt_http_proto_t proto) 1322 { 1323 nxt_off_t sent; 1324 nxt_h1proto_t *h1p; 1325 1326 h1p = proto.h1; 1327 1328 sent = h1p->conn->sent - h1p->header_size; 1329 1330 return (sent > 0) ? sent : 0; 1331 } 1332 1333 1334 static void 1335 nxt_h1p_request_discard(nxt_task_t *task, nxt_http_request_t *r, 1336 nxt_buf_t *last) 1337 { 1338 nxt_buf_t *b; 1339 nxt_conn_t *c; 1340 nxt_h1proto_t *h1p; 1341 nxt_work_queue_t *wq; 1342 1343 nxt_debug(task, "h1p request discard"); 1344 1345 h1p = r->proto.h1; 1346 h1p->keepalive = 0; 1347 1348 c = h1p->conn; 1349 b = c->write; 1350 c->write = NULL; 1351 1352 wq = &task->thread->engine->fast_work_queue; 1353 1354 nxt_sendbuf_drain(task, wq, b); 1355 nxt_sendbuf_drain(task, wq, last); 1356 } 1357 1358 1359 static void 1360 nxt_h1p_conn_request_error(nxt_task_t *task, void *obj, void *data) 1361 { 1362 nxt_h1proto_t *h1p; 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 1376 if (r->fields == NULL) { 1377 (void) nxt_h1p_header_process(task, h1p, r); 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 } 1386 1387 1388 static void 1389 nxt_h1p_conn_request_timeout(nxt_task_t *task, void *obj, void *data) 1390 { 1391 nxt_conn_t *c; 1392 nxt_timer_t *timer; 1393 nxt_h1proto_t *h1p; 1394 nxt_http_request_t *r; 1395 1396 timer = obj; 1397 1398 nxt_debug(task, "h1p conn request timeout"); 1399 1400 c = nxt_read_timer_conn(timer); 1401 c->block_read = 1; 1402 /* 1403 * Disable SO_LINGER off during socket closing 1404 * to send "408 Request Timeout" error response. 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) { 1413 (void) nxt_h1p_header_process(task, h1p, r); 1414 } 1415 1416 nxt_http_request_error(task, r, NXT_HTTP_REQUEST_TIMEOUT); 1417 } 1418 1419 1420 static void 1421 nxt_h1p_conn_request_send_timeout(nxt_task_t *task, void *obj, void *data) 1422 { 1423 nxt_conn_t *c; 1424 nxt_timer_t *timer; 1425 nxt_h1proto_t *h1p; 1426 1427 timer = obj; 1428 1429 nxt_debug(task, "h1p conn request send timeout"); 1430 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 1439 nxt_msec_t 1440 nxt_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 } 1448 1449 1450 nxt_inline void 1451 nxt_h1p_request_error(nxt_task_t *task, nxt_h1proto_t *h1p, 1452 nxt_http_request_t *r) 1453 { 1454 h1p->keepalive = 0; 1455 1456 r->state->error_handler(task, r, h1p); 1457 } 1458 1459 1460 static void 1461 nxt_h1p_request_close(nxt_task_t *task, nxt_http_proto_t proto, 1462 nxt_socket_conf_joint_t *joint) 1463 { 1464 nxt_conn_t *c; 1465 nxt_h1proto_t *h1p; 1466 1467 nxt_debug(task, "h1p request close"); 1468 1469 h1p = proto.h1; 1470 h1p->request = NULL; 1471 1472 nxt_router_conf_release(task, joint); 1473 1474 c = h1p->conn; 1475 1476 if (h1p->keepalive) { 1477 nxt_h1p_keepalive(task, h1p, c); 1478 1479 } else { 1480 nxt_h1p_shutdown(task, c); 1481 } 1482 } 1483 1484 1485 static void 1486 nxt_h1p_conn_sent(nxt_task_t *task, void *obj, void *data) 1487 { 1488 nxt_conn_t *c; 1489 nxt_event_engine_t *engine; 1490 1491 c = obj; 1492 1493 nxt_debug(task, "h1p conn sent"); 1494 1495 engine = task->thread->engine; 1496 1497 c->write = nxt_sendbuf_completion(task, &engine->fast_work_queue, c->write); 1498 1499 if (c->write != NULL) { 1500 nxt_conn_write(engine, c); 1501 } 1502 } 1503 1504 1505 static void 1506 nxt_h1p_conn_close(nxt_task_t *task, void *obj, void *data) 1507 { 1508 nxt_conn_t *c; 1509 1510 c = obj; 1511 1512 nxt_debug(task, "h1p conn close"); 1513 1514 nxt_h1p_shutdown(task, c); 1515 } 1516 1517 1518 static void 1519 nxt_h1p_conn_error(nxt_task_t *task, void *obj, void *data) 1520 { 1521 nxt_conn_t *c; 1522 1523 c = obj; 1524 1525 nxt_debug(task, "h1p conn error"); 1526 1527 nxt_h1p_shutdown(task, c); 1528 } 1529 1530 1531 static nxt_msec_t 1532 nxt_h1p_conn_timer_value(nxt_conn_t *c, uintptr_t data) 1533 { 1534 nxt_socket_conf_joint_t *joint; 1535 1536 joint = c->listen->socket.data; 1537 1538 return nxt_value_at(nxt_msec_t, joint->socket_conf, data); 1539 } 1540 1541 1542 static void 1543 nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) 1544 { 1545 size_t size; 1546 nxt_buf_t *in; 1547 1548 nxt_debug(task, "h1p keepalive"); 1549 1550 if (!c->tcp_nodelay) { 1551 nxt_conn_tcp_nodelay_on(task, c); 1552 } 1553 1554 nxt_h1p_complete_buffers(task, h1p); 1555 1556 in = c->read; 1557 1558 nxt_memzero(h1p, offsetof(nxt_h1proto_t, conn)); 1559 1560 c->sent = 0; 1561 1562 if (in == NULL) { 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 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); 1578 } 1579 } 1580 1581 1582 static const nxt_conn_state_t nxt_h1p_keepalive_state 1583 nxt_aligned(64) = 1584 { 1585 .ready_handler = nxt_h1p_conn_request_init, 1586 .close_handler = nxt_h1p_conn_close, 1587 .error_handler = nxt_h1p_conn_error, 1588 1589 .io_read_handler = nxt_h1p_idle_io_read_handler, 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 1598 const nxt_conn_state_t nxt_h1p_idle_close_state 1599 nxt_aligned(64) = 1600 { 1601 .close_handler = nxt_h1p_idle_close, 1602 }; 1603 1604 1605 static void 1606 nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data) 1607 { 1608 nxt_conn_t *c; 1609 1610 c = obj; 1611 1612 nxt_debug(task, "h1p idle close"); 1613 1614 nxt_h1p_idle_response(task, c); 1615 } 1616 1617 1618 static void 1619 nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data) 1620 { 1621 nxt_conn_t *c; 1622 nxt_timer_t *timer; 1623 1624 timer = obj; 1625 1626 nxt_debug(task, "h1p idle timeout"); 1627 1628 c = nxt_read_timer_conn(timer); 1629 c->block_read = 1; 1630 1631 nxt_h1p_idle_response(task, c); 1632 } 1633 1634 1635 #define NXT_H1P_IDLE_TIMEOUT \ 1636 "HTTP/1.1 408 Request Timeout\r\n" \ 1637 "Server: " NXT_SERVER "\r\n" \ 1638 "Connection: close\r\n" \ 1639 "Content-Length: 0\r\n" \ 1640 "Date: " 1641 1642 1643 static void 1644 nxt_h1p_idle_response(nxt_task_t *task, nxt_conn_t *c) 1645 { 1646 u_char *p; 1647 size_t size; 1648 nxt_buf_t *out, *last; 1649 1650 size = nxt_length(NXT_H1P_IDLE_TIMEOUT) 1651 + nxt_http_date_cache.size 1652 + nxt_length("\r\n\r\n"); 1653 1654 out = nxt_buf_mem_alloc(c->mem_pool, size, 0); 1655 if (nxt_slow_path(out == NULL)) { 1656 goto fail; 1657 } 1658 1659 p = nxt_cpymem(out->mem.free, NXT_H1P_IDLE_TIMEOUT, 1660 nxt_length(NXT_H1P_IDLE_TIMEOUT)); 1661 1662 p = nxt_thread_time_string(task->thread, &nxt_http_date_cache, p); 1663 1664 out->mem.free = nxt_cpymem(p, "\r\n\r\n", 4); 1665 1666 last = nxt_mp_zget(c->mem_pool, NXT_BUF_SYNC_SIZE); 1667 if (nxt_slow_path(last == NULL)) { 1668 goto fail; 1669 } 1670 1671 out->next = last; 1672 nxt_buf_set_sync(last); 1673 nxt_buf_set_last(last); 1674 1675 last->completion_handler = nxt_h1p_idle_response_sent; 1676 last->parent = c; 1677 1678 c->write = out; 1679 c->write_state = &nxt_h1p_timeout_response_state; 1680 1681 nxt_conn_write(task->thread->engine, c); 1682 return; 1683 1684 fail: 1685 1686 nxt_h1p_shutdown(task, c); 1687 } 1688 1689 1690 static const nxt_conn_state_t nxt_h1p_timeout_response_state 1691 nxt_aligned(64) = 1692 { 1693 .ready_handler = nxt_h1p_conn_sent, 1694 .error_handler = nxt_h1p_conn_error, 1695 1696 .timer_handler = nxt_h1p_idle_response_timeout, 1697 .timer_value = nxt_h1p_idle_response_timer_value, 1698 }; 1699 1700 1701 static void 1702 nxt_h1p_idle_response_sent(nxt_task_t *task, void *obj, void *data) 1703 { 1704 nxt_conn_t *c; 1705 1706 c = data; 1707 1708 nxt_debug(task, "h1p idle timeout response sent"); 1709 1710 nxt_h1p_shutdown(task, c); 1711 } 1712 1713 1714 static void 1715 nxt_h1p_idle_response_timeout(nxt_task_t *task, void *obj, void *data) 1716 { 1717 nxt_conn_t *c; 1718 nxt_timer_t *timer; 1719 1720 timer = obj; 1721 1722 nxt_debug(task, "h1p idle timeout response timeout"); 1723 1724 c = nxt_read_timer_conn(timer); 1725 c->block_write = 1; 1726 1727 nxt_h1p_shutdown(task, c); 1728 } 1729 1730 1731 static nxt_msec_t 1732 nxt_h1p_idle_response_timer_value(nxt_conn_t *c, uintptr_t data) 1733 { 1734 return 10 * 1000; 1735 } 1736 1737 1738 static void 1739 nxt_h1p_shutdown(nxt_task_t *task, nxt_conn_t *c) 1740 { 1741 nxt_timer_t *timer; 1742 nxt_h1proto_t *h1p; 1743 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 1765 static void 1766 nxt_h1p_shutdown_(nxt_task_t *task, nxt_conn_t *c) 1767 { 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); 1776 return; 1777 } 1778 1779 #endif 1780 1781 nxt_h1p_conn_closing(task, c, NULL); 1782 } 1783 1784 1785 #if (NXT_TLS) 1786 1787 static const nxt_conn_state_t nxt_h1p_shutdown_state 1788 nxt_aligned(64) = 1789 { 1790 .ready_handler = nxt_h1p_conn_closing, 1791 .close_handler = nxt_h1p_conn_closing, 1792 .error_handler = nxt_h1p_conn_closing, 1793 }; 1794 1795 #endif 1796 1797 1798 static void 1799 nxt_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 1813 static void 1814 nxt_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 1822 c->write_state = &nxt_h1p_close_state; 1823 1824 nxt_conn_close(task->thread->engine, c); 1825 } 1826 1827 1828 static const nxt_conn_state_t nxt_h1p_close_state 1829 nxt_aligned(64) = 1830 { 1831 .ready_handler = nxt_h1p_conn_free, 1832 }; 1833 1834 1835 static void 1836 nxt_h1p_conn_free(nxt_task_t *task, void *obj, void *data) 1837 { 1838 nxt_conn_t *c; 1839 nxt_listen_event_t *lev; 1840 nxt_event_engine_t *engine; 1841 1842 c = obj; 1843 1844 nxt_debug(task, "h1p conn free"); 1845 1846 nxt_queue_remove(&c->link); 1847 1848 engine = task->thread->engine; 1849 1850 nxt_sockaddr_cache_free(engine, c); 1851 1852 lev = c->listen; 1853 1854 nxt_conn_free(task, c); 1855 1856 nxt_router_listen_event_release(&engine->task, lev, NULL); 1857 } 1858