1 #include "first.h" 2 3 #include "base.h" 4 #include "buffer.h" 5 #include "burl.h" /* HTTP_PARSEOPT_HEADER_STRICT */ 6 #include "chunk.h" 7 #include "log.h" 8 #include "connections.h" 9 #include "fdevent.h" 10 #include "h2.h" 11 #include "http_header.h" 12 13 #include "reqpool.h" 14 #include "request.h" 15 #include "response.h" 16 #include "network.h" 17 #include "stat_cache.h" 18 19 #include "plugin.h" 20 21 #include "inet_ntop_cache.h" 22 23 #include <sys/stat.h> 24 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <errno.h> 28 #include <string.h> 29 30 #ifdef HAVE_SYS_FILIO_H 31 # include <sys/filio.h> 32 #endif 33 34 #include "sys-socket.h" 35 36 #define HTTP_LINGER_TIMEOUT 5 37 38 #define connection_set_state(r, n) ((r)->state = (n)) 39 40 __attribute_cold__ 41 static void connection_set_state_error(request_st * const r, const request_state_t state) { 42 connection_set_state(r, state); 43 } 44 45 __attribute_cold__ 46 static connection *connection_init(server *srv); 47 48 static void connection_reset(connection *con); 49 50 51 static connection *connections_get_new_connection(server *srv) { 52 connections * const conns = &srv->conns; 53 size_t i; 54 55 if (conns->size == conns->used) { 56 conns->size += srv->max_conns >= 128 ? 128 : srv->max_conns > 16 ? 16 : srv->max_conns; 57 conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size); 58 force_assert(NULL != conns->ptr); 59 60 for (i = conns->used; i < conns->size; i++) { 61 conns->ptr[i] = connection_init(srv); 62 connection_reset(conns->ptr[i]); 63 } 64 } 65 66 conns->ptr[conns->used]->ndx = conns->used; 67 return conns->ptr[conns->used++]; 68 } 69 70 static void connection_del(server *srv, connection *con) { 71 connections * const conns = &srv->conns; 72 73 if (-1 == con->ndx) return; 74 uint32_t i = (uint32_t)con->ndx; 75 76 /* not last element */ 77 78 if (i != --conns->used) { 79 connection * const temp = conns->ptr[i]; 80 conns->ptr[i] = conns->ptr[conns->used]; 81 conns->ptr[conns->used] = temp; 82 83 conns->ptr[i]->ndx = i; 84 conns->ptr[conns->used]->ndx = -1; 85 } 86 87 con->ndx = -1; 88 #if 0 89 fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used); 90 for (i = 0; i < conns->used; i++) { 91 fprintf(stderr, "%d ", conns->ptr[i]->fd); 92 } 93 fprintf(stderr, "\n"); 94 #endif 95 } 96 97 static void connection_close(connection *con) { 98 if (con->fd < 0) con->fd = -con->fd; 99 100 plugins_call_handle_connection_close(con); 101 102 server * const srv = con->srv; 103 request_st * const r = &con->request; 104 request_reset_ex(r); /*(r->conf.* is still valid below)*/ 105 connection_set_state(r, CON_STATE_CONNECT); 106 107 chunkqueue_reset(con->read_queue); 108 con->request_count = 0; 109 con->is_ssl_sock = 0; 110 111 fdevent_fdnode_event_del(srv->ev, con->fdn); 112 fdevent_unregister(srv->ev, con->fd); 113 con->fdn = NULL; 114 #ifdef __WIN32 115 if (0 == closesocket(con->fd)) 116 #else 117 if (0 == close(con->fd)) 118 #endif 119 --srv->cur_fds; 120 else 121 log_perror(r->conf.errh, __FILE__, __LINE__, 122 "(warning) close: %d", con->fd); 123 124 if (r->conf.log_state_handling) { 125 log_error(r->conf.errh, __FILE__, __LINE__, 126 "connection closed for fd %d", con->fd); 127 } 128 con->fd = -1; 129 130 connection_del(srv, con); 131 } 132 133 static void connection_read_for_eos_plain(connection * const con) { 134 /* we have to do the linger_on_close stuff regardless 135 * of r->keep_alive; even non-keepalive sockets 136 * may still have unread data, and closing before reading 137 * it will make the client not see all our output. 138 */ 139 ssize_t len; 140 const int type = con->dst_addr.plain.sa_family; 141 char buf[16384]; 142 do { 143 len = fdevent_socket_read_discard(con->fd, buf, sizeof(buf), 144 type, SOCK_STREAM); 145 } while (len > 0 || (len < 0 && errno == EINTR)); 146 147 if (len < 0 && errno == EAGAIN) return; 148 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 149 if (len < 0 && errno == EWOULDBLOCK) return; 150 #endif 151 152 /* 0 == len || (len < 0 && (errno is a non-recoverable error)) */ 153 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 154 } 155 156 static void connection_read_for_eos_ssl(connection * const con) { 157 if (con->network_read(con, con->read_queue, MAX_READ_LIMIT) < 0) 158 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 159 chunkqueue_reset(con->read_queue); 160 } 161 162 static void connection_read_for_eos(connection * const con) { 163 !con->is_ssl_sock 164 ? connection_read_for_eos_plain(con) 165 : connection_read_for_eos_ssl(con); 166 } 167 168 static void connection_handle_close_state(connection *con) { 169 connection_read_for_eos(con); 170 171 if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) { 172 connection_close(con); 173 } 174 } 175 176 static void connection_handle_shutdown(connection *con) { 177 plugins_call_handle_connection_shut_wr(con); 178 179 connection_reset(con); 180 ++con->srv->con_closed; 181 182 /* close the connection */ 183 if (con->fd >= 0 184 && (con->is_ssl_sock || 0 == shutdown(con->fd, SHUT_WR))) { 185 con->close_timeout_ts = log_epoch_secs; 186 187 request_st * const r = &con->request; 188 connection_set_state(r, CON_STATE_CLOSE); 189 if (r->conf.log_state_handling) { 190 log_error(r->conf.errh, __FILE__, __LINE__, 191 "shutdown for fd %d", con->fd); 192 } 193 } else { 194 connection_close(con); 195 } 196 } 197 198 __attribute_cold__ 199 static void connection_fdwaitqueue_append(connection *con) { 200 connection_list_append(&con->srv->fdwaitqueue, con); 201 } 202 203 204 static void connection_handle_response_end_state(request_st * const r, connection * const con) { 205 if (r->http_version > HTTP_VERSION_1_1) { 206 h2_retire_con(r, con); 207 r->keep_alive = 0; 208 /* set a status so that mod_accesslog, mod_rrdtool hooks are called 209 * in plugins_call_handle_request_done() (XXX: or set to 0 to omit) */ 210 r->http_status = 100; /* XXX: what if con->state == CON_STATE_ERROR? */ 211 } 212 213 /* call request_done hook if http_status set (e.g. to log request) */ 214 /* (even if error, connection dropped, as long as http_status is set) */ 215 if (r->http_status) plugins_call_handle_request_done(r); 216 217 if (r->state != CON_STATE_ERROR) ++con->srv->con_written; 218 219 if (r->reqbody_length != r->reqbody_queue->bytes_in 220 || r->state == CON_STATE_ERROR) { 221 /* request body is present and has not been read completely */ 222 r->keep_alive = 0; 223 } 224 225 if (r->keep_alive) { 226 request_reset(r); 227 config_reset_config(r); 228 con->is_readable = 1; /* potentially trigger optimistic read */ 229 /*(accounting used by mod_accesslog for HTTP/1.0 and HTTP/1.1)*/ 230 r->bytes_read_ckpt = con->bytes_read; 231 r->bytes_written_ckpt = con->bytes_written; 232 #if 0 233 r->start_ts = con->read_idle_ts = log_epoch_secs; 234 #endif 235 connection_set_state(r, CON_STATE_REQUEST_START); 236 } else { 237 connection_handle_shutdown(con); 238 } 239 } 240 241 static off_t 242 connection_write_throttle (connection * const con, off_t max_bytes) 243 { 244 request_st * const r = &con->request; 245 if (r->conf.global_bytes_per_second) { 246 off_t limit = (off_t)r->conf.global_bytes_per_second 247 - *(r->conf.global_bytes_per_second_cnt_ptr); 248 if (limit <= 0) { 249 /* we reached the global traffic limit */ 250 con->traffic_limit_reached = 1; 251 return 0; 252 } 253 else if (max_bytes > limit) 254 max_bytes = limit; 255 } 256 257 if (r->conf.bytes_per_second) { 258 off_t limit = (off_t)r->conf.bytes_per_second 259 - con->bytes_written_cur_second; 260 if (limit <= 0) { 261 /* we reached the traffic limit */ 262 con->traffic_limit_reached = 1; 263 return 0; 264 } 265 else if (max_bytes > limit) 266 max_bytes = limit; 267 } 268 269 return max_bytes; 270 } 271 272 273 static int 274 connection_write_chunkqueue (connection * const con, chunkqueue * const cq, off_t max_bytes) 275 { 276 con->write_request_ts = log_epoch_secs; 277 278 max_bytes = connection_write_throttle(con, max_bytes); 279 if (0 == max_bytes) return 1; 280 281 off_t written = cq->bytes_out; 282 int ret; 283 284 #ifdef TCP_CORK 285 /* Linux: put a cork into socket as we want to combine write() calls 286 * but only if we really have multiple chunks including non-MEM_CHUNK, 287 * and only if TCP socket 288 */ 289 int corked = 0; 290 if (cq->first && cq->first->next) { 291 const int sa_family = sock_addr_get_family(&con->srv_socket->addr); 292 if (sa_family == AF_INET || sa_family == AF_INET6) { 293 chunk *c = cq->first; 294 while (c->type == MEM_CHUNK && NULL != (c = c->next)) ; 295 if (NULL != c) { 296 corked = 1; 297 (void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, 298 &corked, sizeof(corked)); 299 } 300 } 301 } 302 #endif 303 304 ret = con->network_write(con, cq, max_bytes); 305 if (ret >= 0) { 306 ret = chunkqueue_is_empty(cq) ? 0 : 1; 307 } 308 309 #ifdef TCP_CORK 310 if (corked) { 311 corked = 0; 312 (void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, 313 &corked, sizeof(corked)); 314 } 315 #endif 316 317 written = cq->bytes_out - written; 318 con->bytes_written += written; 319 con->bytes_written_cur_second += written; 320 request_st * const r = &con->request; 321 if (r->conf.global_bytes_per_second_cnt_ptr) 322 *(r->conf.global_bytes_per_second_cnt_ptr) += written; 323 324 return ret; 325 } 326 327 328 static int 329 connection_write_100_continue (request_st * const r, connection * const con) 330 { 331 /* Make best effort to send all or none of "HTTP/1.1 100 Continue" */ 332 /* (Note: also choosing not to update con->write_request_ts 333 * which differs from connection_write_chunkqueue()) */ 334 static const char http_100_continue[] = "HTTP/1.1 100 Continue\r\n\r\n"; 335 336 if (con->traffic_limit_reached) 337 return 1; /* success; skip sending if throttled */ 338 339 chunkqueue * const cq = r->write_queue; 340 off_t written = cq->bytes_out; 341 342 chunkqueue_append_mem(cq,http_100_continue,sizeof(http_100_continue)-1); 343 int rc = con->network_write(con, cq, sizeof(http_100_continue)-1); 344 345 written = cq->bytes_out - written; 346 con->bytes_written += written; 347 con->bytes_written_cur_second += written; 348 if (r->conf.global_bytes_per_second_cnt_ptr) 349 *(r->conf.global_bytes_per_second_cnt_ptr) += written; 350 351 if (rc < 0) { 352 connection_set_state_error(r, CON_STATE_ERROR); 353 return 0; /* error */ 354 } 355 356 if (0 == written) { 357 /* skip sending 100 Continue if send would block */ 358 chunkqueue_mark_written(cq, sizeof(http_100_continue)-1); 359 con->is_writable = 0; 360 } 361 /* else partial write (unlikely), which can cause corrupt 362 * response if response is later cleared, e.g. sending errdoc. 363 * However, situation of partial write can occur here only on 364 * keep-alive request where client has sent pipelined request, 365 * and more than 0 chars were written, but fewer than 25 chars */ 366 367 return 1; /* success; sent all or none of "HTTP/1.1 100 Continue" */ 368 } 369 370 371 static void connection_handle_write(request_st * const r, connection * const con) { 372 int rc = connection_write_chunkqueue(con, con->write_queue, MAX_WRITE_LIMIT); 373 switch (rc) { 374 case 0: 375 if (r->resp_body_finished) { 376 connection_set_state(r, CON_STATE_RESPONSE_END); 377 } 378 break; 379 case -1: /* error on our side */ 380 log_error(r->conf.errh, __FILE__, __LINE__, 381 "connection closed: write failed on fd %d", con->fd); 382 connection_set_state_error(r, CON_STATE_ERROR); 383 break; 384 case -2: /* remote close */ 385 connection_set_state_error(r, CON_STATE_ERROR); 386 break; 387 case 1: 388 /* do not spin trying to send HTTP/2 server Connection Preface 389 * while waiting for TLS negotiation to complete */ 390 if (con->write_queue->bytes_out) 391 con->is_writable = 0; 392 393 /* not finished yet -> WRITE */ 394 break; 395 } 396 } 397 398 static void connection_handle_write_state(request_st * const r, connection * const con) { 399 do { 400 /* only try to write if we have something in the queue */ 401 if (!chunkqueue_is_empty(r->write_queue)) { 402 if (r->http_version <= HTTP_VERSION_1_1 && con->is_writable) { 403 /*(r->write_queue == con->write_queue)*//*(not HTTP/2 stream)*/ 404 connection_handle_write(r, con); 405 if (r->state != CON_STATE_WRITE) break; 406 } 407 } else if (r->resp_body_finished) { 408 connection_set_state(r, CON_STATE_RESPONSE_END); 409 break; 410 } 411 412 if (r->handler_module && !r->resp_body_finished) { 413 const plugin * const p = r->handler_module; 414 int rc = p->handle_subrequest(r, p->data); 415 switch(rc) { 416 case HANDLER_WAIT_FOR_EVENT: 417 case HANDLER_FINISHED: 418 case HANDLER_GO_ON: 419 break; 420 case HANDLER_WAIT_FOR_FD: 421 /* (In addition to waiting for dispatch from fdwaitqueue, 422 * HTTP/2 connections may retry more frequently after any 423 * activity occurs on connection or on other streams) */ 424 connection_fdwaitqueue_append(con); 425 break; 426 case HANDLER_COMEBACK: 427 default: 428 log_error(r->conf.errh, __FILE__, __LINE__, 429 "unexpected subrequest handler ret-value: %d %d", 430 con->fd, rc); 431 /* fall through */ 432 case HANDLER_ERROR: 433 connection_set_state_error(r, CON_STATE_ERROR); 434 break; 435 } 436 } 437 } while (r->state == CON_STATE_WRITE 438 && r->http_version <= HTTP_VERSION_1_1 439 && (!chunkqueue_is_empty(r->write_queue) 440 ? con->is_writable 441 : r->resp_body_finished)); 442 } 443 444 445 __attribute_cold__ 446 static connection *connection_init(server *srv) { 447 connection * const con = calloc(1, sizeof(*con)); 448 force_assert(NULL != con); 449 450 con->fd = 0; 451 con->ndx = -1; 452 con->bytes_written = 0; 453 con->bytes_read = 0; 454 455 con->dst_addr_buf = buffer_init(); 456 con->srv = srv; 457 con->plugin_slots = srv->plugin_slots; 458 con->config_data_base = srv->config_data_base; 459 460 request_st * const r = &con->request; 461 request_init_data(r, con, srv); 462 config_reset_config(r); 463 con->write_queue = r->write_queue; 464 con->read_queue = r->read_queue; 465 466 /* init plugin-specific per-connection structures */ 467 con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *)); 468 force_assert(NULL != con->plugin_ctx); 469 470 return con; 471 } 472 473 474 void connections_free(server *srv) { 475 connections * const conns = &srv->conns; 476 for (uint32_t i = 0; i < conns->size; ++i) { 477 connection *con = conns->ptr[i]; 478 request_st * const r = &con->request; 479 480 connection_reset(con); 481 if (con->write_queue != r->write_queue) 482 chunkqueue_free(con->write_queue); 483 if (con->read_queue != r->read_queue) 484 chunkqueue_free(con->read_queue); 485 request_free_data(r); 486 487 free(con->plugin_ctx); 488 buffer_free(con->dst_addr_buf); 489 490 free(con); 491 } 492 493 free(conns->ptr); 494 conns->ptr = NULL; 495 } 496 497 498 static void connection_reset(connection *con) { 499 request_st * const r = &con->request; 500 request_reset(r); 501 config_reset_config(r); 502 r->bytes_read_ckpt = 0; 503 r->bytes_written_ckpt = 0; 504 con->is_readable = 1; 505 506 con->bytes_written = 0; 507 con->bytes_written_cur_second = 0; 508 con->bytes_read = 0; 509 } 510 511 512 __attribute_cold__ 513 static chunk * 514 connection_discard_blank_line (chunkqueue * const cq, uint32_t header_len) 515 { 516 /*(separate func only to be able to mark with compiler hint as cold)*/ 517 chunkqueue_mark_written(cq, header_len); 518 return cq->first; /* refresh c after chunkqueue_mark_written() */ 519 } 520 521 522 static chunk * connection_read_header_more(connection *con, chunkqueue *cq, chunk *c, const size_t olen) { 523 /*(should not be reached by HTTP/2 streams)*/ 524 /*if (r->http_version == HTTP_VERSION_2) return NULL;*/ 525 /*(However, new connections over TLS may become HTTP/2 connections via ALPN 526 * and return from this routine with r->http_version == HTTP_VERSION_2) */ 527 528 if ((NULL == c || NULL == c->next) && con->is_readable) { 529 con->read_idle_ts = log_epoch_secs; 530 if (0 != con->network_read(con, cq, MAX_READ_LIMIT)) { 531 request_st * const r = &con->request; 532 connection_set_state_error(r, CON_STATE_ERROR); 533 } 534 /* check if switched to HTTP/2 (ALPN "h2" during TLS negotiation) */ 535 request_st * const r = &con->request; 536 if (r->http_version == HTTP_VERSION_2) return NULL; 537 } 538 539 if (cq->first != cq->last && 0 != olen) { 540 const size_t clen = chunkqueue_length(cq); 541 size_t block = (olen + (16384-1)) & (16384-1); 542 block += (block - olen > 1024 ? 0 : 16384); 543 chunkqueue_compact_mem(cq, block > clen ? clen : block); 544 } 545 546 /* detect if data is added to chunk */ 547 c = cq->first; 548 return (c && (size_t)c->offset + olen < buffer_string_length(c->mem)) 549 ? c 550 : NULL; 551 } 552 553 554 static void 555 connection_transition_h2 (request_st * const h2r, connection * const con) 556 { 557 buffer_copy_string_len(&h2r->target, CONST_STR_LEN("*")); 558 buffer_copy_string_len(&h2r->target_orig, CONST_STR_LEN("*")); 559 buffer_copy_string_len(&h2r->uri.path, CONST_STR_LEN("*")); 560 h2r->http_method = HTTP_METHOD_PRI; 561 h2r->reqbody_length = -1; /*(unnecessary for h2r?)*/ 562 h2r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN; 563 564 /* (h2r->state == CON_STATE_READ) for transition by ALPN 565 * or starting cleartext HTTP/2 with Prior Knowledge 566 * (e.g. via HTTP Alternative Services) 567 * (h2r->state == CON_STATE_RESPONSE_END) for Upgrade: h2c */ 568 569 if (h2r->state != CON_STATE_ERROR) 570 connection_set_state(h2r, CON_STATE_WRITE); 571 572 #if 0 /* ... if it turns out we need a separate fdevent handler for HTTP/2 */ 573 con->fdn->handler = connection_handle_fdevent_h2; 574 #endif 575 576 if (NULL == con->h2) /*(not yet transitioned to HTTP/2; not Upgrade: h2c)*/ 577 h2_init_con(h2r, con, NULL); 578 } 579 580 581 /** 582 * handle request header read 583 * 584 * we get called by the state-engine and by the fdevent-handler 585 */ 586 __attribute_noinline__ 587 static int connection_handle_read_state(connection * const con) { 588 /*(should not be reached by HTTP/2 streams)*/ 589 chunkqueue * const cq = con->read_queue; 590 chunk *c = cq->first; 591 uint32_t clen = 0; 592 uint32_t header_len = 0; 593 request_st * const r = &con->request; 594 uint8_t keepalive_request_start = 0; 595 uint8_t pipelined_request_start = 0; 596 uint8_t discard_blank = 0; 597 unsigned short hoff[8192]; /* max num header lines + 3; 16k on stack */ 598 599 if (con->request_count > 1) { 600 discard_blank = 1; 601 if (con->bytes_read == r->bytes_read_ckpt) { 602 keepalive_request_start = 1; 603 if (NULL != c) { /* !chunkqueue_is_empty(cq)) */ 604 pipelined_request_start = 1; 605 /* partial header of next request has already been read, 606 * so optimistically check for more data received on 607 * socket while processing the previous request */ 608 con->is_readable = 1; 609 /*(if partially read next request and unable to read any bytes, 610 * then will unnecessarily scan again before subsequent read)*/ 611 } 612 } 613 } 614 615 do { 616 if (NULL == c) continue; 617 clen = buffer_string_length(c->mem) - c->offset; 618 if (0 == clen) continue; 619 if (c->offset > USHRT_MAX) /*(highly unlikely)*/ 620 chunkqueue_compact_mem(cq, clen); 621 622 hoff[0] = 1; /* number of lines */ 623 hoff[1] = (unsigned short)c->offset; /* base offset for all lines */ 624 /*hoff[2] = ...;*/ /* offset from base for 2nd line */ 625 626 header_len = http_header_parse_hoff(c->mem->ptr + c->offset,clen,hoff); 627 628 /* casting to (unsigned short) might truncate, and the hoff[] 629 * addition might overflow, but max_request_field_size is USHRT_MAX, 630 * so failure will be detected below */ 631 const uint32_t max_request_field_size=r->conf.max_request_field_size; 632 if ((header_len ? header_len : clen) > max_request_field_size 633 || hoff[0] >= sizeof(hoff)/sizeof(hoff[0])-1) { 634 log_error(r->conf.errh, __FILE__, __LINE__, "%s", 635 "oversized request-header -> sending Status 431"); 636 r->http_status = 431; /* Request Header Fields Too Large */ 637 r->keep_alive = 0; 638 connection_set_state(r, CON_STATE_REQUEST_END); 639 return 1; 640 } 641 642 if (0 != header_len) { 643 if (hoff[0] > 1) break; /* common case; request headers complete */ 644 645 if (discard_blank) { /* skip one blank line e.g. following POST */ 646 if (header_len == clen) continue; 647 const int ch = c->mem->ptr[c->offset+header_len]; 648 if (ch != '\r' && ch != '\n') { 649 /* discard prior blank line if next line is not blank */ 650 discard_blank = 0; 651 clen = 0;/*(for connection_read_header_more() to return c)*/ 652 c = connection_discard_blank_line(cq, header_len);/*cold*/ 653 continue; 654 } /*(else fall through to error out in next block)*/ 655 } 656 } 657 658 if (((unsigned char *)c->mem->ptr)[c->offset] < 32) { 659 /* expecting ASCII method beginning with alpha char 660 * or HTTP/2 pseudo-header beginning with ':' */ 661 /*(TLS handshake begins with SYN 0x16 (decimal 22))*/ 662 log_error(r->conf.errh, __FILE__, __LINE__, "%s", 663 "invalid request-line -> sending Status 400"); 664 r->http_status = 400; /* Bad Request */ 665 r->keep_alive = 0; 666 connection_set_state(r, CON_STATE_REQUEST_END); 667 return 1; 668 } 669 } while ((c = connection_read_header_more(con, cq, c, clen))); 670 671 if (keepalive_request_start) { 672 if (con->bytes_read > r->bytes_read_ckpt) { 673 /* update r->start_ts timestamp when first byte of 674 * next request is received on a keep-alive connection */ 675 r->start_ts = log_epoch_secs; 676 if (r->conf.high_precision_timestamps) 677 log_clock_gettime_realtime(&r->start_hp); 678 } 679 if (pipelined_request_start && c) con->read_idle_ts = log_epoch_secs; 680 } 681 682 if (NULL == c) return 0; /* incomplete request headers */ 683 684 #ifdef __COVERITY__ 685 if (buffer_string_length(c->mem) < hoff[1]) { 686 return 1; 687 } 688 #endif 689 690 char * const hdrs = c->mem->ptr + hoff[1]; 691 692 if (con->request_count > 1) { 693 /* clear buffers which may have been kept for reporting on keep-alive, 694 * (e.g. mod_status) */ 695 request_reset_ex(r); 696 } 697 /* RFC7540 3.5 HTTP/2 Connection Preface 698 * "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 699 * (Connection Preface MUST be exact match) 700 * If ALT-SVC used to advertise HTTP/2, then client might start 701 * http connection (not TLS) sending HTTP/2 connection preface. 702 * (note: intentionally checking only on initial request) */ 703 else if (!con->is_ssl_sock && r->conf.h2proto 704 && hoff[0] == 2 && hoff[2] == 16 705 && hdrs[0]=='P' && hdrs[1]=='R' && hdrs[2]=='I' && hdrs[3]==' ') { 706 r->http_version = HTTP_VERSION_2; 707 return 0; 708 } 709 710 r->rqst_header_len = header_len; 711 if (r->conf.log_request_header) 712 log_error(r->conf.errh, __FILE__, __LINE__, 713 "fd: %d request-len: %d\n%.*s", con->fd, 714 (int)header_len, (int)header_len, hdrs); 715 http_request_headers_process(r, hdrs, hoff, con->proto_default_port); 716 chunkqueue_mark_written(cq, r->rqst_header_len); 717 connection_set_state(r, CON_STATE_REQUEST_END); 718 719 if (!con->is_ssl_sock && r->conf.h2proto && 0 == r->http_status 720 && h2_check_con_upgrade_h2c(r)) { 721 /*(Upgrade: h2c over cleartext does not have SNI; no COMP_HTTP_HOST)*/ 722 r->conditional_is_valid = (1 << COMP_SERVER_SOCKET) 723 | (1 << COMP_HTTP_REMOTE_IP); 724 /*connection_handle_write(r, con);*//* defer write to network */ 725 return 0; 726 } 727 728 return 1; 729 } 730 731 732 static void connection_state_machine_h2 (request_st *r, connection *con); 733 734 static handler_t connection_handle_fdevent(void *context, int revents) { 735 connection *con = context; 736 737 if (con->is_ssl_sock) { 738 /* ssl may read and write for both reads and writes */ 739 if (revents & (FDEVENT_IN | FDEVENT_OUT)) { 740 con->is_readable = 1; 741 con->is_writable = 1; 742 } 743 } else { 744 if (revents & FDEVENT_IN) { 745 con->is_readable = 1; 746 } 747 if (revents & FDEVENT_OUT) { 748 con->is_writable = 1; 749 /* we don't need the event twice */ 750 } 751 } 752 753 request_st * const r = &con->request; 754 755 if (r->http_version == HTTP_VERSION_2) { 756 connection_state_machine_h2(r, con); 757 if (-1 == con->fd) /*(con closed; CON_STATE_CONNECT)*/ 758 return HANDLER_FINISHED; 759 } 760 else { 761 joblist_append(con); 762 763 if (r->state == CON_STATE_READ) { 764 if (!connection_handle_read_state(con) 765 && r->http_version == HTTP_VERSION_2) 766 connection_transition_h2(r, con); 767 } 768 769 if (r->state == CON_STATE_WRITE && 770 !chunkqueue_is_empty(con->write_queue) && 771 con->is_writable) { 772 connection_handle_write(r, con); 773 } 774 } 775 776 if (r->state == CON_STATE_CLOSE) { 777 /* flush the read buffers */ 778 connection_read_for_eos(con); 779 } 780 781 782 /* attempt (above) to read data in kernel socket buffers 783 * prior to handling FDEVENT_HUP and FDEVENT_ERR */ 784 785 if ((revents & ~(FDEVENT_IN | FDEVENT_OUT)) && r->state != CON_STATE_ERROR) { 786 if (r->state == CON_STATE_CLOSE) { 787 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 788 } else if (revents & FDEVENT_HUP) { 789 connection_set_state_error(r, CON_STATE_ERROR); 790 } else if (revents & FDEVENT_RDHUP) { 791 int events = fdevent_fdnode_interest(con->fdn); 792 events &= ~(FDEVENT_IN|FDEVENT_RDHUP); 793 r->conf.stream_request_body &= ~(FDEVENT_STREAM_REQUEST_BUFMIN|FDEVENT_STREAM_REQUEST_POLLIN); 794 r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLRDHUP; 795 con->is_readable = 1; /*(can read 0 for end-of-stream)*/ 796 if (chunkqueue_is_empty(con->read_queue)) r->keep_alive = 0; 797 if (r->reqbody_length < -1) { /*(transparent proxy mode; no more data to read)*/ 798 r->reqbody_length = r->reqbody_queue->bytes_in; 799 } 800 if (sock_addr_get_family(&con->dst_addr) == AF_UNIX) { 801 /* future: will getpeername() on AF_UNIX properly check if still connected? */ 802 fdevent_fdnode_event_set(con->srv->ev, con->fdn, events); 803 } else if (fdevent_is_tcp_half_closed(con->fd)) { 804 /* Success of fdevent_is_tcp_half_closed() after FDEVENT_RDHUP indicates TCP FIN received, 805 * but does not distinguish between client shutdown(fd, SHUT_WR) and client close(fd). 806 * Remove FDEVENT_RDHUP so that we do not spin on the ready event. 807 * However, a later TCP RST will not be detected until next write to socket. 808 * future: might getpeername() to check for TCP RST on half-closed sockets 809 * (without FDEVENT_RDHUP interest) when checking for write timeouts 810 * once a second in server.c, though getpeername() on Windows might not indicate this */ 811 r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_TCP_FIN; 812 fdevent_fdnode_event_set(con->srv->ev, con->fdn, events); 813 } else { 814 /* Failure of fdevent_is_tcp_half_closed() indicates TCP RST 815 * (or unable to tell (unsupported OS), though should not 816 * be setting FDEVENT_RDHUP in that case) */ 817 connection_set_state_error(r, CON_STATE_ERROR); 818 } 819 } else if (revents & FDEVENT_ERR) { /* error, connection reset */ 820 connection_set_state_error(r, CON_STATE_ERROR); 821 } else { 822 log_error(r->conf.errh, __FILE__, __LINE__, 823 "connection closed: poll() -> ??? %d", revents); 824 } 825 } 826 827 return HANDLER_FINISHED; 828 } 829 830 831 connection *connection_accept(server *srv, server_socket *srv_socket) { 832 int cnt; 833 sock_addr cnt_addr; 834 size_t cnt_len = sizeof(cnt_addr); /*(size_t intentional; not socklen_t)*/ 835 836 /** 837 * check if we can still open a new connections 838 * 839 * see #1216 840 */ 841 842 if (srv->conns.used >= srv->max_conns) { 843 return NULL; 844 } 845 846 cnt = fdevent_accept_listenfd(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len); 847 if (-1 == cnt) { 848 switch (errno) { 849 case EAGAIN: 850 #if EWOULDBLOCK != EAGAIN 851 case EWOULDBLOCK: 852 #endif 853 case EINTR: 854 /* we were stopped _before_ we had a connection */ 855 case ECONNABORTED: /* this is a FreeBSD thingy */ 856 /* we were stopped _after_ we had a connection */ 857 break; 858 case EMFILE: 859 /* out of fds */ 860 break; 861 default: 862 log_perror(srv->errh, __FILE__, __LINE__, "accept failed"); 863 } 864 return NULL; 865 } else { 866 if (sock_addr_get_family(&cnt_addr) != AF_UNIX) { 867 network_accept_tcp_nagle_disable(cnt); 868 } 869 return connection_accepted(srv, srv_socket, &cnt_addr, cnt); 870 } 871 } 872 873 874 __attribute_cold__ 875 static int connection_read_cq_err(connection *con) { 876 request_st * const r = &con->request; 877 #if defined(__WIN32) 878 int lastError = WSAGetLastError(); 879 switch (lastError) { 880 case EAGAIN: 881 return 0; 882 case EINTR: 883 /* we have been interrupted before we could read */ 884 con->is_readable = 1; 885 return 0; 886 case ECONNRESET: 887 /* suppress logging for this error, expected for keep-alive */ 888 break; 889 default: 890 log_error(r->conf.errh, __FILE__, __LINE__, 891 "connection closed - recv failed: %d", lastError); 892 break; 893 } 894 #else /* __WIN32 */ 895 switch (errno) { 896 case EAGAIN: 897 return 0; 898 case EINTR: 899 /* we have been interrupted before we could read */ 900 con->is_readable = 1; 901 return 0; 902 case ECONNRESET: 903 /* suppress logging for this error, expected for keep-alive */ 904 break; 905 default: 906 log_perror(r->conf.errh, __FILE__, __LINE__, 907 "connection closed - read failed"); 908 break; 909 } 910 #endif /* __WIN32 */ 911 912 connection_set_state_error(r, CON_STATE_ERROR); 913 return -1; 914 } 915 916 917 /* 0: everything ok, -1: error, -2: con closed */ 918 static int connection_read_cq(connection *con, chunkqueue *cq, off_t max_bytes) { 919 ssize_t len; 920 size_t mem_len = 0; 921 922 do { 923 /* obtain chunk memory into which to read 924 * fill previous chunk if it has a reasonable amount of space available 925 * (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz) 926 */ 927 chunk *ckpt = cq->last; 928 char * const mem = chunkqueue_get_memory(cq, &mem_len); 929 if (mem_len > (size_t)max_bytes) mem_len = (size_t)max_bytes; 930 931 #if defined(__WIN32) 932 len = recv(con->fd, mem, mem_len, 0); 933 #else 934 len = read(con->fd, mem, mem_len); 935 #endif 936 937 chunkqueue_use_memory(cq, ckpt, len > 0 ? len : 0); 938 939 if (len != (ssize_t)mem_len) { 940 /* we got less then expected, wait for the next fd-event */ 941 con->is_readable = 0; 942 943 if (len > 0) { 944 con->bytes_read += len; 945 return 0; 946 } 947 else if (0 == len) /* other end close connection -> KEEP-ALIVE */ 948 return -2; /* (pipelining) */ 949 else 950 return connection_read_cq_err(con); 951 } 952 953 con->bytes_read += len; 954 max_bytes -= len; 955 956 int frd; 957 mem_len = (0 == fdevent_ioctl_fionread(con->fd, S_IFSOCK, &frd)) 958 ? (frd < max_bytes) ? (size_t)frd : (size_t)max_bytes 959 : 0; 960 } while (max_bytes); 961 return 0; 962 } 963 964 965 static int connection_write_cq(connection *con, chunkqueue *cq, off_t max_bytes) { 966 request_st * const r = &con->request; 967 return con->srv->network_backend_write(con->fd,cq,max_bytes,r->conf.errh); 968 } 969 970 971 static handler_t connection_handle_read_post_state(request_st * const r); 972 973 connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) { 974 connection *con; 975 976 srv->cur_fds++; 977 978 /* ok, we have the connection, register it */ 979 #if 0 980 log_error(srv->errh, __FILE__, __LINE__, "accepted() %d", cnt); 981 #endif 982 srv->con_opened++; 983 984 con = connections_get_new_connection(srv); 985 986 con->fd = cnt; 987 con->fdn = fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con); 988 con->network_read = connection_read_cq; 989 con->network_write = connection_write_cq; 990 con->reqbody_read = connection_handle_read_post_state; 991 992 request_st * const r = &con->request; 993 connection_set_state(r, CON_STATE_REQUEST_START); 994 995 con->connection_start = log_epoch_secs; 996 con->dst_addr = *cnt_addr; 997 buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); 998 con->srv_socket = srv_socket; 999 con->is_ssl_sock = srv_socket->is_ssl; 1000 con->proto_default_port = 80; /* "http" */ 1001 1002 config_cond_cache_reset(r); 1003 r->conditional_is_valid = (1 << COMP_SERVER_SOCKET) 1004 | (1 << COMP_HTTP_REMOTE_IP); 1005 1006 if (HANDLER_GO_ON != plugins_call_handle_connection_accept(con)) { 1007 connection_reset(con); 1008 connection_close(con); 1009 return NULL; 1010 } 1011 if (r->http_status < 0) connection_set_state(r, CON_STATE_WRITE); 1012 return con; 1013 } 1014 1015 1016 __attribute_cold__ 1017 __attribute_noinline__ 1018 static const char * 1019 connection_get_state (request_state_t state) 1020 { 1021 switch (state) { 1022 case CON_STATE_CONNECT: return "connect"; 1023 case CON_STATE_READ: return "read"; 1024 case CON_STATE_READ_POST: return "readpost"; 1025 case CON_STATE_WRITE: return "write"; 1026 case CON_STATE_CLOSE: return "close"; 1027 case CON_STATE_ERROR: return "error"; 1028 case CON_STATE_HANDLE_REQUEST: return "handle-req"; 1029 case CON_STATE_REQUEST_START: return "req-start"; 1030 case CON_STATE_REQUEST_END: return "req-end"; 1031 case CON_STATE_RESPONSE_START: return "resp-start"; 1032 case CON_STATE_RESPONSE_END: return "resp-end"; 1033 default: return "(unknown)"; 1034 } 1035 } 1036 1037 1038 static void 1039 connection_state_machine_loop (request_st * const r, connection * const con) 1040 { 1041 request_state_t ostate; 1042 do { 1043 if (r->conf.log_state_handling) { 1044 log_error(r->conf.errh, __FILE__, __LINE__, 1045 "state for fd %d %s", con->fd, connection_get_state(r->state)); 1046 } 1047 1048 switch ((ostate = r->state)) { 1049 case CON_STATE_REQUEST_START: /* transient */ 1050 /*(should not be reached by HTTP/2 streams)*/ 1051 r->start_ts = con->read_idle_ts = log_epoch_secs; 1052 if (r->conf.high_precision_timestamps) 1053 log_clock_gettime_realtime(&r->start_hp); 1054 1055 con->request_count++; 1056 r->loops_per_request = 0; 1057 1058 connection_set_state(r, CON_STATE_READ); 1059 /* fall through */ 1060 case CON_STATE_READ: 1061 /*(should not be reached by HTTP/2 streams)*/ 1062 if (!connection_handle_read_state(con)) { 1063 if (r->http_version == HTTP_VERSION_2) { 1064 connection_transition_h2(r, con); 1065 connection_state_machine_h2(r, con); 1066 return; 1067 } 1068 break; 1069 } 1070 /*if (r->state != CON_STATE_REQUEST_END) break;*/ 1071 /* fall through */ 1072 case CON_STATE_REQUEST_END: /* transient */ 1073 ostate = (0 == r->reqbody_length) 1074 ? CON_STATE_HANDLE_REQUEST 1075 : CON_STATE_READ_POST; 1076 connection_set_state(r, ostate); 1077 /* fall through */ 1078 case CON_STATE_READ_POST: 1079 case CON_STATE_HANDLE_REQUEST: 1080 switch (http_response_handler(r)) { 1081 case HANDLER_GO_ON:/*CON_STATE_RESPONSE_START occurred;transient*/ 1082 case HANDLER_FINISHED: 1083 break; 1084 case HANDLER_WAIT_FOR_EVENT: 1085 return; 1086 case HANDLER_COMEBACK: 1087 /* redo loop; will not match r->state */ 1088 ostate = CON_STATE_CONNECT; 1089 continue; 1090 case HANDLER_WAIT_FOR_FD: 1091 connection_fdwaitqueue_append(con); 1092 return; 1093 /*case HANDLER_ERROR:*/ 1094 default: 1095 connection_set_state_error(r, CON_STATE_ERROR); 1096 continue; 1097 } 1098 /* fall through */ 1099 /*case CON_STATE_RESPONSE_START:*//*occurred;transient*/ 1100 if (r->http_version > HTTP_VERSION_1_1) 1101 h2_send_headers(r, con); 1102 else 1103 http_response_write_header(r); 1104 connection_set_state(r, CON_STATE_WRITE); 1105 /* fall through */ 1106 case CON_STATE_WRITE: 1107 connection_handle_write_state(r, con); 1108 if (r->state != CON_STATE_RESPONSE_END) break; 1109 /* fall through */ 1110 case CON_STATE_RESPONSE_END: /* transient */ 1111 case CON_STATE_ERROR: /* transient */ 1112 if (r->http_version > HTTP_VERSION_1_1 && r != &con->request) 1113 return; 1114 connection_handle_response_end_state(r, con); 1115 break; 1116 case CON_STATE_CLOSE: 1117 /*(should not be reached by HTTP/2 streams)*/ 1118 connection_handle_close_state(con); 1119 break; 1120 case CON_STATE_CONNECT: 1121 break; 1122 default: 1123 log_error(r->conf.errh, __FILE__, __LINE__, 1124 "unknown state: %d %d", con->fd, r->state); 1125 break; 1126 } 1127 } while (ostate != (request_state_t)r->state); 1128 } 1129 1130 1131 static void 1132 connection_set_fdevent_interest (request_st * const r, connection * const con) 1133 { 1134 if (con->fd < 0) return; 1135 1136 int n = 0; 1137 switch(r->state) { 1138 case CON_STATE_READ: 1139 n = FDEVENT_IN | FDEVENT_RDHUP; 1140 break; 1141 case CON_STATE_WRITE: 1142 if (!chunkqueue_is_empty(con->write_queue) 1143 && 0 == con->is_writable && 0 == con->traffic_limit_reached) 1144 n |= FDEVENT_OUT; 1145 __attribute_fallthrough__ 1146 case CON_STATE_READ_POST: 1147 if (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLIN) 1148 n |= FDEVENT_IN; 1149 if (!(r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLRDHUP)) 1150 n |= FDEVENT_RDHUP; 1151 break; 1152 case CON_STATE_CLOSE: 1153 n = FDEVENT_IN; 1154 break; 1155 case CON_STATE_CONNECT: 1156 return; 1157 default: 1158 break; 1159 } 1160 1161 const int events = fdevent_fdnode_interest(con->fdn); 1162 if (con->is_readable < 0) { 1163 con->is_readable = 0; 1164 n |= FDEVENT_IN; 1165 } 1166 if (con->is_writable < 0) { 1167 con->is_writable = 0; 1168 n |= FDEVENT_OUT; 1169 } 1170 if (events & FDEVENT_RDHUP) 1171 n |= FDEVENT_RDHUP; 1172 1173 if (n == events) return; 1174 1175 /* update timestamps when enabling interest in events */ 1176 if ((n & FDEVENT_IN) && !(events & FDEVENT_IN)) 1177 con->read_idle_ts = log_epoch_secs; 1178 if ((n & FDEVENT_OUT) && !(events & FDEVENT_OUT)) 1179 con->write_request_ts = log_epoch_secs; 1180 fdevent_fdnode_event_set(con->srv->ev, con->fdn, n); 1181 } 1182 1183 1184 static void 1185 connection_state_machine_h2 (request_st * const h2r, connection * const con) 1186 { 1187 h2con * const h2c = con->h2; 1188 1189 if (h2c->sent_goaway <= 0 1190 && (chunkqueue_is_empty(con->read_queue) || h2_parse_frames(con)) 1191 && con->is_readable) { 1192 chunkqueue * const cq = con->read_queue; 1193 const off_t mark = cq->bytes_in; 1194 if (0 == con->network_read(con, cq, MAX_READ_LIMIT)) { 1195 if (mark < cq->bytes_in) 1196 h2_parse_frames(con); 1197 } 1198 else { 1199 /* network error; do not send GOAWAY, but pretend that we did */ 1200 h2c->sent_goaway = H2_E_CONNECT_ERROR; /*any error (not NO_ERROR)*/ 1201 connection_set_state_error(h2r, CON_STATE_ERROR); 1202 } 1203 } 1204 1205 /* process requests on HTTP/2 streams */ 1206 int resched = 0; 1207 if (h2c->sent_goaway <= 0 && h2c->rused) { 1208 /* coarse check for write throttling 1209 * (connection.kbytes-per-second, server.kbytes-per-second) 1210 * obtain an approximate limit, not refreshed per request_st, 1211 * even though we are not calculating response HEADERS frames 1212 * or frame overhead here */ 1213 off_t max_bytes = con->is_writable 1214 ? connection_write_throttle(con, MAX_WRITE_LIMIT) 1215 : 0; 1216 const off_t fsize = (off_t)h2c->s_max_frame_size; 1217 1218 /* XXX: to avoid buffer bloat due to staging too much data in 1219 * con->write_queue, consider setting limit on how much is staged 1220 * for sending on con->write_queue: adjusting max_bytes down */ 1221 1222 /* XXX: TODO: process requests in stream priority order */ 1223 for (uint32_t i = 0; i < h2c->rused; ++i) { 1224 request_st * const r = h2c->r[i]; 1225 /* future: might track read/write interest per request 1226 * to avoid iterating through all active requests */ 1227 1228 /* XXX: h2.c manages r->h2state, but does not modify r->state 1229 * (might revisit later and allow h2.c to modify both) */ 1230 if (r->state < CON_STATE_REQUEST_END 1231 && (r->h2state == H2_STATE_OPEN 1232 || r->h2state == H2_STATE_HALF_CLOSED_REMOTE)) 1233 connection_set_state(r, CON_STATE_REQUEST_END); 1234 else if (r->h2state == H2_STATE_CLOSED 1235 && r->state != CON_STATE_ERROR) 1236 connection_set_state(r, CON_STATE_ERROR); 1237 1238 #if 0 /*(done in connection_state_machine(), but w/o stream id)*/ 1239 const int log_state_handling = r->conf.log_state_handling; 1240 if (log_state_handling) 1241 log_error(r->conf.errh, __FILE__, __LINE__, 1242 "state at enter %d %d %s", con->fd, r->h2id, 1243 connection_get_state(r->state)); 1244 #endif 1245 1246 connection_state_machine_loop(r, con); 1247 1248 if (r->resp_header_len && !chunkqueue_is_empty(r->write_queue) 1249 && (r->resp_body_finished || r->conf.stream_response_body)) { 1250 1251 chunkqueue * const cq = r->write_queue; 1252 off_t avail = cq->bytes_in - cq->bytes_out; 1253 if (avail > max_bytes) avail = max_bytes; 1254 if (avail > fsize) avail = fsize; 1255 if (avail > r->h2_swin) avail = r->h2_swin; 1256 if (avail > h2r->h2_swin) avail = h2r->h2_swin; 1257 1258 if (avail > 0) { 1259 max_bytes -= avail; 1260 h2_send_cqdata(r, con, cq, (uint32_t)avail); 1261 } 1262 1263 if (r->resp_body_finished && chunkqueue_is_empty(cq)) { 1264 connection_set_state(r, CON_STATE_RESPONSE_END); 1265 if (r->conf.log_state_handling) 1266 connection_state_machine_loop(r, con); 1267 } 1268 else if (avail) /*(do not spin if swin empty window)*/ 1269 resched |= (!chunkqueue_is_empty(cq)); 1270 } 1271 1272 #if 0 /*(done in connection_state_machine(), but w/o stream id)*/ 1273 /* XXX: TODO: r is invalid if retired; not properly handled here */ 1274 if (log_state_handling) 1275 log_error(r->conf.errh, __FILE__, __LINE__, 1276 "state at exit %d %d %s", con->fd, r->h2id, 1277 connection_get_state(r->state)); 1278 #endif 1279 1280 if (r->state==CON_STATE_RESPONSE_END || r->state==CON_STATE_ERROR) { 1281 /*(trigger reschedule of con if frames pending)*/ 1282 if (h2c->rused == sizeof(h2c->r)/sizeof(*h2c->r) 1283 && !chunkqueue_is_empty(con->read_queue)) 1284 resched |= 1; 1285 h2_send_end_stream(r, con); 1286 h2_retire_stream(r, con);/*r invalidated;removed from h2c->r[]*/ 1287 --i;/* adjust loop i; h2c->rused was modified to retire r */ 1288 } 1289 } 1290 } 1291 1292 if (h2c->sent_goaway > 0 && h2c->rused) { 1293 /* retire streams if an error has occurred 1294 * note: this is not done to other streams in the loop above 1295 * (besides the current stream in the loop) due to the specific 1296 * implementation above, where doing so would mess up the iterator */ 1297 for (uint32_t i = 0; i < h2c->rused; ++i) { 1298 request_st * const r = h2c->r[i]; 1299 /*assert(r->h2state == H2_STATE_CLOSED);*/ 1300 h2_retire_stream(r, con);/*r invalidated;removed from h2c->r[]*/ 1301 --i;/* adjust loop i; h2c->rused was modified to retire r */ 1302 } 1303 /* XXX: ? should we discard con->write_queue 1304 * and change h2r->state to CON_STATE_RESPONSE_END ? */ 1305 } 1306 1307 if (h2r->state == CON_STATE_WRITE) { 1308 /* write HTTP/2 frames to socket */ 1309 if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) 1310 connection_handle_write(h2r, con); 1311 1312 if (chunkqueue_is_empty(con->write_queue) 1313 && 0 == h2c->rused && h2c->sent_goaway) 1314 connection_set_state(h2r, CON_STATE_RESPONSE_END); 1315 } 1316 1317 if (h2r->state == CON_STATE_WRITE) { 1318 if (resched && !con->traffic_limit_reached) 1319 joblist_append(con); 1320 1321 if (h2_want_read(con)) 1322 h2r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN; 1323 else 1324 h2r->conf.stream_request_body &= ~FDEVENT_STREAM_REQUEST_POLLIN; 1325 } 1326 else /* e.g. CON_STATE_RESPONSE_END or CON_STATE_ERROR */ 1327 connection_state_machine_loop(h2r, con); 1328 1329 connection_set_fdevent_interest(h2r, con); 1330 } 1331 1332 1333 static void 1334 connection_state_machine_h1 (request_st * const r, connection * const con) 1335 { 1336 const int log_state_handling = r->conf.log_state_handling; 1337 if (log_state_handling) { 1338 log_error(r->conf.errh, __FILE__, __LINE__, 1339 "state at enter %d %s", con->fd, connection_get_state(r->state)); 1340 } 1341 1342 connection_state_machine_loop(r, con); 1343 1344 if (log_state_handling) { 1345 log_error(r->conf.errh, __FILE__, __LINE__, 1346 "state at exit: %d %s", con->fd, connection_get_state(r->state)); 1347 } 1348 1349 connection_set_fdevent_interest(r, con); 1350 } 1351 1352 1353 void 1354 connection_state_machine (connection * const con) 1355 { 1356 request_st * const r = &con->request; 1357 if (r->http_version == HTTP_VERSION_2) 1358 connection_state_machine_h2(r, con); 1359 else /* if (r->http_version <= HTTP_VERSION_1_1) */ 1360 connection_state_machine_h1(r, con); 1361 } 1362 1363 1364 static void connection_check_timeout (connection * const con, const time_t cur_ts) { 1365 const int waitevents = fdevent_fdnode_interest(con->fdn); 1366 int changed = 0; 1367 int t_diff; 1368 1369 request_st * const r = &con->request; 1370 if (r->state == CON_STATE_CLOSE) { 1371 if (cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) { 1372 changed = 1; 1373 } 1374 } 1375 else if (con->h2 && r->state == CON_STATE_WRITE) { 1376 h2con * const h2c = con->h2; 1377 if (h2c->rused) { 1378 for (uint32_t i = 0; i < h2c->rused; ++i) { 1379 request_st * const rr = h2c->r[i]; 1380 if (rr->state == CON_STATE_ERROR) { /*(should not happen)*/ 1381 changed = 1; 1382 continue; 1383 } 1384 if (rr->reqbody_length != rr->reqbody_queue->bytes_in) { 1385 /* XXX: should timeout apply if not trying to read on h2con? 1386 * (still applying timeout to catch stuck connections) */ 1387 /* XXX: con->read_idle_ts is not per-request, so timeout 1388 * will not occur if other read activity occurs on h2con 1389 * (future: might keep separate timestamp per-request) */ 1390 if (cur_ts - con->read_idle_ts > rr->conf.max_read_idle) { 1391 /* time - out */ 1392 if (rr->conf.log_request_handling) { 1393 log_error(rr->conf.errh, __FILE__, __LINE__, 1394 "request aborted - read timeout: %d", con->fd); 1395 } 1396 connection_set_state_error(r, CON_STATE_ERROR); 1397 changed = 1; 1398 } 1399 } 1400 1401 if (rr->state != CON_STATE_READ_POST 1402 && con->write_request_ts != 0) { 1403 /* XXX: con->write_request_ts is not per-request, so timeout 1404 * will not occur if other write activity occurs on h2con 1405 * (future: might keep separate timestamp per-request) */ 1406 if (cur_ts - con->write_request_ts 1407 > r->conf.max_write_idle) { 1408 /*(see comment further down about max_write_idle)*/ 1409 /* time - out */ 1410 if (r->conf.log_timeouts) { 1411 log_error(r->conf.errh, __FILE__, __LINE__, 1412 "NOTE: a request from %.*s for %.*s timed out " 1413 "after writing %lld bytes. We waited %d seconds. " 1414 "If this is a problem, increase " 1415 "server.max-write-idle", 1416 BUFFER_INTLEN_PTR(con->dst_addr_buf), 1417 BUFFER_INTLEN_PTR(&r->target), 1418 (long long)r->write_queue->bytes_out, 1419 (int)r->conf.max_write_idle); 1420 } 1421 connection_set_state_error(r, CON_STATE_ERROR); 1422 changed = 1; 1423 } 1424 } 1425 } 1426 } 1427 else { 1428 if (cur_ts - con->read_idle_ts > con->keep_alive_idle) { 1429 /* time - out */ 1430 if (r->conf.log_request_handling) { 1431 log_error(r->conf.errh, __FILE__, __LINE__, 1432 "connection closed - keep-alive timeout: %d", 1433 con->fd); 1434 } 1435 connection_set_state(r, CON_STATE_RESPONSE_END); 1436 changed = 1; 1437 } 1438 } 1439 } 1440 else if (waitevents & FDEVENT_IN) { 1441 if (con->request_count == 1 || r->state != CON_STATE_READ) { 1442 /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */ 1443 if (cur_ts - con->read_idle_ts > r->conf.max_read_idle) { 1444 /* time - out */ 1445 if (r->conf.log_request_handling) { 1446 log_error(r->conf.errh, __FILE__, __LINE__, 1447 "connection closed - read timeout: %d", con->fd); 1448 } 1449 1450 connection_set_state_error(r, CON_STATE_ERROR); 1451 changed = 1; 1452 } 1453 } else { 1454 if (cur_ts - con->read_idle_ts > con->keep_alive_idle) { 1455 /* time - out */ 1456 if (r->conf.log_request_handling) { 1457 log_error(r->conf.errh, __FILE__, __LINE__, 1458 "connection closed - keep-alive timeout: %d", 1459 con->fd); 1460 } 1461 1462 connection_set_state_error(r, CON_STATE_ERROR); 1463 changed = 1; 1464 } 1465 } 1466 } 1467 1468 /* max_write_idle timeout currently functions as backend timeout, 1469 * too, after response has been started. 1470 * future: have separate backend timeout, and then change this 1471 * to check for write interest before checking for timeout */ 1472 /*if (waitevents & FDEVENT_OUT)*/ 1473 if (r->http_version <= HTTP_VERSION_1_1 1474 && r->state == CON_STATE_WRITE && con->write_request_ts != 0) { 1475 #if 0 1476 if (cur_ts - con->write_request_ts > 60) { 1477 log_error(r->conf.errh, __FILE__, __LINE__, 1478 "connection closed - pre-write-request-timeout: %d %d", 1479 con->fd, cur_ts - con->write_request_ts); 1480 } 1481 #endif 1482 1483 if (cur_ts - con->write_request_ts > r->conf.max_write_idle) { 1484 /* time - out */ 1485 if (r->conf.log_timeouts) { 1486 log_error(r->conf.errh, __FILE__, __LINE__, 1487 "NOTE: a request from %.*s for %.*s timed out after writing " 1488 "%lld bytes. We waited %d seconds. If this is a problem, " 1489 "increase server.max-write-idle", 1490 BUFFER_INTLEN_PTR(con->dst_addr_buf), 1491 BUFFER_INTLEN_PTR(&r->target), 1492 (long long)con->bytes_written, (int)r->conf.max_write_idle); 1493 } 1494 connection_set_state_error(r, CON_STATE_ERROR); 1495 changed = 1; 1496 } 1497 } 1498 1499 /* lighttpd HTTP/2 limitation: rate limit config r->conf.bytes_per_second 1500 * (currently) taken only from top-level config (socket), with host if SNI 1501 * used, but not any other config conditions, e.g. not per-file-type */ 1502 1503 if (0 == (t_diff = cur_ts - con->connection_start)) t_diff = 1; 1504 1505 if (con->traffic_limit_reached && 1506 (r->conf.bytes_per_second == 0 || 1507 con->bytes_written < (off_t)r->conf.bytes_per_second * t_diff)) { 1508 /* enable connection again */ 1509 con->traffic_limit_reached = 0; 1510 1511 changed = 1; 1512 } 1513 1514 con->bytes_written_cur_second = 0; 1515 1516 if (changed) { 1517 connection_state_machine(con); 1518 } 1519 } 1520 1521 void connection_periodic_maint (server * const srv, const time_t cur_ts) { 1522 /* check all connections for timeouts */ 1523 connections * const conns = &srv->conns; 1524 for (size_t ndx = 0; ndx < conns->used; ++ndx) { 1525 connection_check_timeout(conns->ptr[ndx], cur_ts); 1526 } 1527 } 1528 1529 void connection_graceful_shutdown_maint (server *srv) { 1530 connections * const conns = &srv->conns; 1531 for (size_t ndx = 0; ndx < conns->used; ++ndx) { 1532 connection * const con = conns->ptr[ndx]; 1533 int changed = 0; 1534 1535 request_st * const r = &con->request; 1536 if (r->state == CON_STATE_CLOSE) { 1537 /* reduce remaining linger timeout to be 1538 * (from zero) *up to* one more second, but no more */ 1539 if (HTTP_LINGER_TIMEOUT > 1) 1540 con->close_timeout_ts -= (HTTP_LINGER_TIMEOUT - 1); 1541 if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) 1542 changed = 1; 1543 } 1544 else if (con->h2 && r->state == CON_STATE_WRITE) { 1545 h2_send_goaway(con, H2_E_NO_ERROR); 1546 if (0 == con->h2->rused && chunkqueue_is_empty(con->write_queue)) { 1547 connection_set_state(r, CON_STATE_RESPONSE_END); 1548 changed = 1; 1549 } 1550 } 1551 else if (r->state == CON_STATE_READ && con->request_count > 1 1552 && chunkqueue_is_empty(con->read_queue)) { 1553 /* close connections in keep-alive waiting for next request */ 1554 connection_set_state_error(r, CON_STATE_ERROR); 1555 changed = 1; 1556 } 1557 1558 r->keep_alive = 0; /* disable keep-alive */ 1559 1560 r->conf.bytes_per_second = 0; /* disable rate limit */ 1561 r->conf.global_bytes_per_second = 0; /* disable rate limit */ 1562 if (con->traffic_limit_reached) { 1563 con->traffic_limit_reached = 0; 1564 changed = 1; 1565 } 1566 1567 if (changed) { 1568 connection_state_machine(con); 1569 } 1570 } 1571 } 1572 1573 1574 static int 1575 connection_handle_read_post_cq_compact (chunkqueue * const cq) 1576 { 1577 /* combine first mem chunk with next non-empty mem chunk 1578 * (loop if next chunk is empty) */ 1579 chunk *c; 1580 while (NULL != (c = cq->first) && NULL != c->next) { 1581 buffer *mem = c->next->mem; 1582 off_t offset = c->next->offset; 1583 size_t blen = buffer_string_length(mem) - (size_t)offset; 1584 force_assert(c->type == MEM_CHUNK); 1585 force_assert(c->next->type == MEM_CHUNK); 1586 buffer_append_string_len(c->mem, mem->ptr+offset, blen); 1587 c->next->offset = c->offset; 1588 c->next->mem = c->mem; 1589 c->mem = mem; 1590 c->offset = offset + (off_t)blen; 1591 chunkqueue_remove_finished_chunks(cq); 1592 if (0 != blen) return 1; 1593 } 1594 return 0; 1595 } 1596 1597 1598 static int 1599 connection_handle_read_post_chunked_crlf (chunkqueue * const cq) 1600 { 1601 /* caller might check chunkqueue_length(cq) >= 2 before calling here 1602 * to limit return value to either 1 for good or -1 for error */ 1603 chunk *c; 1604 buffer *b; 1605 char *p; 1606 size_t len; 1607 1608 /* caller must have called chunkqueue_remove_finished_chunks(cq), so if 1609 * chunkqueue is not empty, it contains chunk with at least one char */ 1610 if (chunkqueue_is_empty(cq)) return 0; 1611 1612 c = cq->first; 1613 b = c->mem; 1614 p = b->ptr+c->offset; 1615 if (p[0] != '\r') return -1; /* error */ 1616 if (p[1] == '\n') return 1; 1617 len = buffer_string_length(b) - (size_t)c->offset; 1618 if (1 != len) return -1; /* error */ 1619 1620 while (NULL != (c = c->next)) { 1621 b = c->mem; 1622 len = buffer_string_length(b) - (size_t)c->offset; 1623 if (0 == len) continue; 1624 p = b->ptr+c->offset; 1625 return (p[0] == '\n') ? 1 : -1; /* error if not '\n' */ 1626 } 1627 return 0; 1628 } 1629 1630 1631 static handler_t 1632 connection_handle_read_post_chunked (request_st * const r, chunkqueue * const cq, chunkqueue * const dst_cq) 1633 { 1634 /* r->conf.max_request_size is in kBytes */ 1635 const off_t max_request_size = (off_t)r->conf.max_request_size << 10; 1636 off_t te_chunked = r->te_chunked; 1637 do { 1638 off_t len = cq->bytes_in - cq->bytes_out; 1639 1640 while (0 == te_chunked) { 1641 char *p; 1642 chunk *c = cq->first; 1643 if (NULL == c) break; 1644 force_assert(c->type == MEM_CHUNK); 1645 p = strchr(c->mem->ptr+c->offset, '\n'); 1646 if (NULL != p) { /* found HTTP chunked header line */ 1647 off_t hsz = p + 1 - (c->mem->ptr+c->offset); 1648 unsigned char *s = (unsigned char *)c->mem->ptr+c->offset; 1649 for (unsigned char u;(u=(unsigned char)hex2int(*s))!=0xFF;++s) { 1650 if (te_chunked > (off_t)(1uLL<<(8*sizeof(off_t)-5))-1) { 1651 log_error(r->conf.errh, __FILE__, __LINE__, 1652 "chunked data size too large -> 400"); 1653 /* 400 Bad Request */ 1654 return http_response_reqbody_read_error(r, 400); 1655 } 1656 te_chunked <<= 4; 1657 te_chunked |= u; 1658 } 1659 if (s == (unsigned char *)c->mem->ptr+c->offset) { /*(no hex)*/ 1660 log_error(r->conf.errh, __FILE__, __LINE__, 1661 "chunked header invalid chars -> 400"); 1662 /* 400 Bad Request */ 1663 return http_response_reqbody_read_error(r, 400); 1664 } 1665 while (*s == ' ' || *s == '\t') ++s; 1666 if (*s != '\r' && *s != ';') { 1667 log_error(r->conf.errh, __FILE__, __LINE__, 1668 "chunked header invalid chars -> 400"); 1669 /* 400 Bad Request */ 1670 return http_response_reqbody_read_error(r, 400); 1671 } 1672 1673 if (hsz >= 1024) { 1674 /* prevent theoretical integer overflow 1675 * casting to (size_t) and adding 2 (for "\r\n") */ 1676 log_error(r->conf.errh, __FILE__, __LINE__, 1677 "chunked header line too long -> 400"); 1678 /* 400 Bad Request */ 1679 return http_response_reqbody_read_error(r, 400); 1680 } 1681 1682 if (0 == te_chunked) { 1683 /* do not consume final chunked header until 1684 * (optional) trailers received along with 1685 * request-ending blank line "\r\n" */ 1686 if (p[0] == '\r' && p[1] == '\n') { 1687 /*(common case with no trailers; final \r\n received)*/ 1688 hsz += 2; 1689 } 1690 else { 1691 /* trailers or final CRLF crosses into next cq chunk */ 1692 hsz -= 2; 1693 do { 1694 c = cq->first; 1695 p = strstr(c->mem->ptr+c->offset+hsz, "\r\n\r\n"); 1696 } while (NULL == p 1697 && connection_handle_read_post_cq_compact(cq)); 1698 if (NULL == p) { 1699 /*(effectively doubles max request field size 1700 * potentially received by backend, if in the future 1701 * these trailers are added to request headers)*/ 1702 if ((off_t)buffer_string_length(c->mem) - c->offset 1703 < (off_t)r->conf.max_request_field_size) { 1704 break; 1705 } 1706 else { 1707 /* ignore excessively long trailers; 1708 * disable keep-alive on connection */ 1709 r->keep_alive = 0; 1710 p = c->mem->ptr + buffer_string_length(c->mem) 1711 - 4; 1712 } 1713 } 1714 hsz = p + 4 - (c->mem->ptr+c->offset); 1715 /* trailers currently ignored, but could be processed 1716 * here if 0 == r->conf.stream_request_body, taking 1717 * care to reject any fields forbidden in trailers, 1718 * making trailers available to CGI and other backends*/ 1719 } 1720 chunkqueue_mark_written(cq, (size_t)hsz); 1721 r->reqbody_length = dst_cq->bytes_in; 1722 break; /* done reading HTTP chunked request body */ 1723 } 1724 1725 /* consume HTTP chunked header */ 1726 chunkqueue_mark_written(cq, (size_t)hsz); 1727 len = cq->bytes_in - cq->bytes_out; 1728 1729 if (0 !=max_request_size 1730 && (max_request_size < te_chunked 1731 || max_request_size - te_chunked < dst_cq->bytes_in)) { 1732 log_error(r->conf.errh, __FILE__, __LINE__, 1733 "request-size too long: %lld -> 413", 1734 (long long)(dst_cq->bytes_in + te_chunked)); 1735 /* 413 Payload Too Large */ 1736 return http_response_reqbody_read_error(r, 413); 1737 } 1738 1739 te_chunked += 2; /*(for trailing "\r\n" after chunked data)*/ 1740 1741 break; /* read HTTP chunked header */ 1742 } 1743 1744 /*(likely better ways to handle chunked header crossing chunkqueue 1745 * chunks, but this situation is not expected to occur frequently)*/ 1746 if ((off_t)buffer_string_length(c->mem) - c->offset >= 1024) { 1747 log_error(r->conf.errh, __FILE__, __LINE__, 1748 "chunked header line too long -> 400"); 1749 /* 400 Bad Request */ 1750 return http_response_reqbody_read_error(r, 400); 1751 } 1752 else if (!connection_handle_read_post_cq_compact(cq)) { 1753 break; 1754 } 1755 } 1756 if (0 == te_chunked) break; 1757 1758 if (te_chunked > 2) { 1759 if (len > te_chunked-2) len = te_chunked-2; 1760 if (dst_cq->bytes_in + te_chunked <= 64*1024) { 1761 /* avoid buffering request bodies <= 64k on disk */ 1762 chunkqueue_steal(dst_cq, cq, len); 1763 } 1764 else if (0 != chunkqueue_steal_with_tempfiles(dst_cq, cq, len, 1765 r->conf.errh)) { 1766 /* 500 Internal Server Error */ 1767 return http_response_reqbody_read_error(r, 500); 1768 } 1769 te_chunked -= len; 1770 len = cq->bytes_in - cq->bytes_out; 1771 } 1772 1773 if (len < te_chunked) break; 1774 1775 if (2 == te_chunked) { 1776 if (-1 == connection_handle_read_post_chunked_crlf(cq)) { 1777 log_error(r->conf.errh, __FILE__, __LINE__, 1778 "chunked data missing end CRLF -> 400"); 1779 /* 400 Bad Request */ 1780 return http_response_reqbody_read_error(r, 400); 1781 } 1782 chunkqueue_mark_written(cq, 2);/*consume \r\n at end of chunk data*/ 1783 te_chunked -= 2; 1784 } 1785 1786 } while (!chunkqueue_is_empty(cq)); 1787 1788 r->te_chunked = te_chunked; 1789 return HANDLER_GO_ON; 1790 } 1791 1792 1793 static handler_t 1794 connection_handle_read_body_unknown (request_st * const r, chunkqueue * const cq, chunkqueue * const dst_cq) 1795 { 1796 /* r->conf.max_request_size is in kBytes */ 1797 const off_t max_request_size = (off_t)r->conf.max_request_size << 10; 1798 chunkqueue_append_chunkqueue(dst_cq, cq); 1799 if (0 != max_request_size && dst_cq->bytes_in > max_request_size) { 1800 log_error(r->conf.errh, __FILE__, __LINE__, 1801 "request-size too long: %lld -> 413", (long long)dst_cq->bytes_in); 1802 /* 413 Payload Too Large */ 1803 return http_response_reqbody_read_error(r, 413); 1804 } 1805 return HANDLER_GO_ON; 1806 } 1807 1808 1809 static handler_t 1810 connection_handle_read_post_state (request_st * const r) 1811 { 1812 connection * const con = r->con; 1813 chunkqueue * const cq = r->read_queue; 1814 chunkqueue * const dst_cq = r->reqbody_queue; 1815 1816 int is_closed = 0; 1817 1818 if (r->http_version > HTTP_VERSION_1_1) { 1819 /*(H2_STATE_HALF_CLOSED_REMOTE or H2_STATE_CLOSED)*/ 1820 if (r->h2state >= H2_STATE_HALF_CLOSED_REMOTE) 1821 is_closed = 1; 1822 } 1823 else if (con->is_readable) { 1824 con->read_idle_ts = log_epoch_secs; 1825 1826 switch(con->network_read(con, cq, MAX_READ_LIMIT)) { 1827 case -1: 1828 connection_set_state_error(r, CON_STATE_ERROR); 1829 return HANDLER_ERROR; 1830 case -2: 1831 is_closed = 1; 1832 break; 1833 default: 1834 break; 1835 } 1836 } 1837 1838 chunkqueue_remove_finished_chunks(cq); 1839 1840 /* Check for Expect: 100-continue in request headers 1841 * if no request body received yet */ 1842 if (chunkqueue_is_empty(cq) && 0 == dst_cq->bytes_in 1843 && r->http_version != HTTP_VERSION_1_0 1844 && chunkqueue_is_empty(r->write_queue) && con->is_writable) { 1845 const buffer *vb = 1846 http_header_request_get(r, HTTP_HEADER_EXPECT, 1847 CONST_STR_LEN("Expect")); 1848 if (NULL != vb 1849 && buffer_eq_icase_slen(vb, CONST_STR_LEN("100-continue"))) { 1850 http_header_request_unset(r, HTTP_HEADER_EXPECT, 1851 CONST_STR_LEN("Expect")); 1852 if (r->http_version > HTTP_VERSION_1_1) 1853 h2_send_100_continue(r, con); 1854 else if (!connection_write_100_continue(r, con)) 1855 return HANDLER_ERROR; 1856 } 1857 } 1858 1859 if (r->http_version > HTTP_VERSION_1_1) { 1860 /* h2_recv_data() places frame payload directly into r->reqbody_queue */ 1861 } 1862 else if (r->reqbody_length < 0) { 1863 /*(-1: Transfer-Encoding: chunked, -2: unspecified length)*/ 1864 handler_t rc = (-1 == r->reqbody_length) 1865 ? connection_handle_read_post_chunked(r, cq, dst_cq) 1866 : connection_handle_read_body_unknown(r, cq, dst_cq); 1867 if (HANDLER_GO_ON != rc) return rc; 1868 } 1869 else { 1870 off_t len = (off_t)r->reqbody_length - dst_cq->bytes_in; 1871 if (r->reqbody_length <= 64*1024) { 1872 /* don't buffer request bodies <= 64k on disk */ 1873 chunkqueue_steal(dst_cq, cq, len); 1874 } 1875 else if (0 != 1876 chunkqueue_steal_with_tempfiles(dst_cq,cq,len,r->conf.errh)) { 1877 /* writing to temp file failed */ /* Internal Server Error */ 1878 return http_response_reqbody_read_error(r, 500); 1879 } 1880 } 1881 1882 chunkqueue_remove_finished_chunks(cq); 1883 1884 if (dst_cq->bytes_in == (off_t)r->reqbody_length) { 1885 /* Content is ready */ 1886 r->conf.stream_request_body &= ~FDEVENT_STREAM_REQUEST_POLLIN; 1887 if (r->state == CON_STATE_READ_POST) { 1888 connection_set_state(r, CON_STATE_HANDLE_REQUEST); 1889 } 1890 return HANDLER_GO_ON; 1891 } 1892 else if (is_closed) { 1893 #if 0 1894 return http_response_reqbody_read_error(r, 400); /* Bad Request */ 1895 #endif 1896 return HANDLER_ERROR; 1897 } 1898 else { 1899 r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN; 1900 return (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST) 1901 ? HANDLER_GO_ON 1902 : HANDLER_WAIT_FOR_EVENT; 1903 } 1904 } 1905