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 #if 0 /* DEBUG_DEV */ 98 __attribute_cold__ 99 static void connection_plugin_ctx_check(server * const srv, request_st * const r) { 100 /* plugins should have cleaned themselves up */ 101 for (uint32_t i = 0; i < srv->plugins.used; ++i) { 102 plugin *p = ((plugin **)(srv->plugins.ptr))[i]; 103 plugin_data_base *pd = p->data; 104 if (!pd) continue; 105 if (NULL == r->plugin_ctx[pd->id] 106 && NULL == r->con->plugin_ctx[pd->id]) continue; 107 log_error(r->conf.errh, __FILE__, __LINE__, 108 "missing cleanup in %s", p->name); 109 r->plugin_ctx[pd->id] = NULL; 110 r->con->plugin_ctx[pd->id] = NULL; 111 } 112 } 113 #endif 114 115 static void connection_close(connection *con) { 116 if (con->fd < 0) con->fd = -con->fd; 117 118 plugins_call_handle_connection_close(con); 119 120 server * const srv = con->srv; 121 request_st * const r = &con->request; 122 123 #if 0 /* DEBUG_DEV */ 124 /* plugins should have cleaned themselves up (id range: [1,used]) */ 125 for (uint32_t i = 1; i <= srv->plugins.used; ++i) { 126 if (NULL != r->plugin_ctx[i] || NULL != con->plugin_ctx[i]) { 127 connection_plugin_ctx_check(srv, r); 128 break; 129 } 130 } 131 #endif 132 133 connection_set_state(r, CON_STATE_CONNECT); 134 buffer_clear(&r->uri.authority); 135 buffer_reset(&r->uri.path); 136 buffer_reset(&r->uri.query); 137 buffer_reset(&r->target_orig); 138 buffer_reset(&r->target); /*(see comments in request_reset())*/ 139 buffer_reset(&r->pathinfo); /*(see comments in request_reset())*/ 140 141 chunkqueue_reset(con->read_queue); 142 con->request_count = 0; 143 con->is_ssl_sock = 0; 144 145 fdevent_fdnode_event_del(srv->ev, con->fdn); 146 fdevent_unregister(srv->ev, con->fd); 147 con->fdn = NULL; 148 #ifdef __WIN32 149 if (0 == closesocket(con->fd)) 150 #else 151 if (0 == close(con->fd)) 152 #endif 153 --srv->cur_fds; 154 else 155 log_perror(r->conf.errh, __FILE__, __LINE__, 156 "(warning) close: %d", con->fd); 157 158 if (r->conf.log_state_handling) { 159 log_error(r->conf.errh, __FILE__, __LINE__, 160 "connection closed for fd %d", con->fd); 161 } 162 con->fd = -1; 163 164 connection_del(srv, con); 165 } 166 167 static void connection_read_for_eos_plain(connection * const con) { 168 /* we have to do the linger_on_close stuff regardless 169 * of r->keep_alive; even non-keepalive sockets 170 * may still have unread data, and closing before reading 171 * it will make the client not see all our output. 172 */ 173 ssize_t len; 174 const int type = con->dst_addr.plain.sa_family; 175 char buf[16384]; 176 do { 177 len = fdevent_socket_read_discard(con->fd, buf, sizeof(buf), 178 type, SOCK_STREAM); 179 } while (len > 0 || (len < 0 && errno == EINTR)); 180 181 if (len < 0 && errno == EAGAIN) return; 182 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 183 if (len < 0 && errno == EWOULDBLOCK) return; 184 #endif 185 186 /* 0 == len || (len < 0 && (errno is a non-recoverable error)) */ 187 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 188 } 189 190 static void connection_read_for_eos_ssl(connection * const con) { 191 if (con->network_read(con, con->read_queue, MAX_READ_LIMIT) < 0) 192 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 193 chunkqueue_reset(con->read_queue); 194 } 195 196 static void connection_read_for_eos(connection * const con) { 197 !con->is_ssl_sock 198 ? connection_read_for_eos_plain(con) 199 : connection_read_for_eos_ssl(con); 200 } 201 202 static void connection_handle_close_state(connection *con) { 203 connection_read_for_eos(con); 204 205 if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) { 206 connection_close(con); 207 } 208 } 209 210 static void connection_handle_shutdown(connection *con) { 211 plugins_call_handle_connection_shut_wr(con); 212 213 connection_reset(con); 214 ++con->srv->con_closed; 215 216 /* close the connection */ 217 if (con->fd >= 0 218 && (con->is_ssl_sock || 0 == shutdown(con->fd, SHUT_WR))) { 219 con->close_timeout_ts = log_epoch_secs; 220 221 request_st * const r = &con->request; 222 connection_set_state(r, CON_STATE_CLOSE); 223 if (r->conf.log_state_handling) { 224 log_error(r->conf.errh, __FILE__, __LINE__, 225 "shutdown for fd %d", con->fd); 226 } 227 } else { 228 connection_close(con); 229 } 230 } 231 232 __attribute_cold__ 233 static void connection_fdwaitqueue_append(connection *con) { 234 connection_list_append(&con->srv->fdwaitqueue, con); 235 } 236 237 238 static void connection_handle_response_end_state(request_st * const r, connection * const con) { 239 if (r->http_version > HTTP_VERSION_1_1) { 240 h2_retire_con(r, con); 241 r->keep_alive = 0; 242 /* set a status so that mod_accesslog, mod_rrdtool hooks are called 243 * in plugins_call_handle_request_done() (XXX: or set to 0 to omit) */ 244 r->http_status = 100; /* XXX: what if con->state == CON_STATE_ERROR? */ 245 } 246 247 /* call request_done hook if http_status set (e.g. to log request) */ 248 /* (even if error, connection dropped, as long as http_status is set) */ 249 if (r->http_status) plugins_call_handle_request_done(r); 250 251 if (r->state != CON_STATE_ERROR) ++con->srv->con_written; 252 253 if (r->reqbody_length != r->reqbody_queue->bytes_in 254 || r->state == CON_STATE_ERROR) { 255 /* request body is present and has not been read completely */ 256 r->keep_alive = 0; 257 } 258 259 if (r->keep_alive) { 260 request_reset(r); 261 config_reset_config(r); 262 con->is_readable = 1; /* potentially trigger optimistic read */ 263 /*(accounting used by mod_accesslog for HTTP/1.0 and HTTP/1.1)*/ 264 r->bytes_read_ckpt = con->bytes_read; 265 r->bytes_written_ckpt = con->bytes_written; 266 #if 0 267 r->start_ts = con->read_idle_ts = log_epoch_secs; 268 #endif 269 connection_set_state(r, CON_STATE_REQUEST_START); 270 } else { 271 connection_handle_shutdown(con); 272 } 273 } 274 275 static off_t 276 connection_write_throttle (connection * const con, off_t max_bytes) 277 { 278 request_st * const r = &con->request; 279 if (r->conf.global_bytes_per_second) { 280 off_t limit = (off_t)r->conf.global_bytes_per_second 281 - *(r->conf.global_bytes_per_second_cnt_ptr); 282 if (limit <= 0) { 283 /* we reached the global traffic limit */ 284 con->traffic_limit_reached = 1; 285 return 0; 286 } 287 else if (max_bytes > limit) 288 max_bytes = limit; 289 } 290 291 if (r->conf.bytes_per_second) { 292 off_t limit = (off_t)r->conf.bytes_per_second 293 - con->bytes_written_cur_second; 294 if (limit <= 0) { 295 /* we reached the traffic limit */ 296 con->traffic_limit_reached = 1; 297 return 0; 298 } 299 else if (max_bytes > limit) 300 max_bytes = limit; 301 } 302 303 return max_bytes; 304 } 305 306 307 static int 308 connection_write_chunkqueue (connection * const con, chunkqueue * const cq, off_t max_bytes) 309 { 310 con->write_request_ts = log_epoch_secs; 311 312 max_bytes = connection_write_throttle(con, max_bytes); 313 if (0 == max_bytes) return 1; 314 315 off_t written = cq->bytes_out; 316 int ret; 317 318 #ifdef TCP_CORK 319 /* Linux: put a cork into socket as we want to combine write() calls 320 * but only if we really have multiple chunks including non-MEM_CHUNK, 321 * and only if TCP socket 322 */ 323 int corked = 0; 324 if (cq->first && cq->first->next) { 325 const int sa_family = sock_addr_get_family(&con->srv_socket->addr); 326 if (sa_family == AF_INET || sa_family == AF_INET6) { 327 chunk *c = cq->first; 328 while (c->type == MEM_CHUNK && NULL != (c = c->next)) ; 329 if (NULL != c) { 330 corked = 1; 331 (void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, 332 &corked, sizeof(corked)); 333 } 334 } 335 } 336 #endif 337 338 ret = con->network_write(con, cq, max_bytes); 339 if (ret >= 0) { 340 ret = chunkqueue_is_empty(cq) ? 0 : 1; 341 } 342 343 #ifdef TCP_CORK 344 if (corked) { 345 corked = 0; 346 (void)setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, 347 &corked, sizeof(corked)); 348 } 349 #endif 350 351 written = cq->bytes_out - written; 352 con->bytes_written += written; 353 con->bytes_written_cur_second += written; 354 request_st * const r = &con->request; 355 if (r->conf.global_bytes_per_second_cnt_ptr) 356 *(r->conf.global_bytes_per_second_cnt_ptr) += written; 357 358 return ret; 359 } 360 361 362 static int 363 connection_write_100_continue (request_st * const r, connection * const con) 364 { 365 /* Make best effort to send all or none of "HTTP/1.1 100 Continue" */ 366 /* (Note: also choosing not to update con->write_request_ts 367 * which differs from connection_write_chunkqueue()) */ 368 static const char http_100_continue[] = "HTTP/1.1 100 Continue\r\n\r\n"; 369 370 if (con->traffic_limit_reached) 371 return 1; /* success; skip sending if throttled */ 372 373 chunkqueue * const cq = r->write_queue; 374 off_t written = cq->bytes_out; 375 376 chunkqueue_append_mem(cq,http_100_continue,sizeof(http_100_continue)-1); 377 int rc = con->network_write(con, cq, sizeof(http_100_continue)-1); 378 379 written = cq->bytes_out - written; 380 con->bytes_written += written; 381 con->bytes_written_cur_second += written; 382 if (r->conf.global_bytes_per_second_cnt_ptr) 383 *(r->conf.global_bytes_per_second_cnt_ptr) += written; 384 385 if (rc < 0) { 386 connection_set_state_error(r, CON_STATE_ERROR); 387 return 0; /* error */ 388 } 389 390 if (0 == written) { 391 /* skip sending 100 Continue if send would block */ 392 chunkqueue_mark_written(cq, sizeof(http_100_continue)-1); 393 con->is_writable = 0; 394 } 395 /* else partial write (unlikely), which can cause corrupt 396 * response if response is later cleared, e.g. sending errdoc. 397 * However, situation of partial write can occur here only on 398 * keep-alive request where client has sent pipelined request, 399 * and more than 0 chars were written, but fewer than 25 chars */ 400 401 return 1; /* success; sent all or none of "HTTP/1.1 100 Continue" */ 402 } 403 404 405 static void connection_handle_write(request_st * const r, connection * const con) { 406 int rc = connection_write_chunkqueue(con, con->write_queue, MAX_WRITE_LIMIT); 407 switch (rc) { 408 case 0: 409 if (r->resp_body_finished) { 410 connection_set_state(r, CON_STATE_RESPONSE_END); 411 } 412 break; 413 case -1: /* error on our side */ 414 log_error(r->conf.errh, __FILE__, __LINE__, 415 "connection closed: write failed on fd %d", con->fd); 416 connection_set_state_error(r, CON_STATE_ERROR); 417 break; 418 case -2: /* remote close */ 419 connection_set_state_error(r, CON_STATE_ERROR); 420 break; 421 case 1: 422 /* do not spin trying to send HTTP/2 server Connection Preface 423 * while waiting for TLS negotiation to complete */ 424 if (con->write_queue->bytes_out) 425 con->is_writable = 0; 426 427 /* not finished yet -> WRITE */ 428 break; 429 } 430 } 431 432 static void connection_handle_write_state(request_st * const r, connection * const con) { 433 do { 434 /* only try to write if we have something in the queue */ 435 if (!chunkqueue_is_empty(r->write_queue)) { 436 if (r->http_version <= HTTP_VERSION_1_1 && con->is_writable) { 437 /*(r->write_queue == con->write_queue)*//*(not HTTP/2 stream)*/ 438 connection_handle_write(r, con); 439 if (r->state != CON_STATE_WRITE) break; 440 } 441 } else if (r->resp_body_finished) { 442 connection_set_state(r, CON_STATE_RESPONSE_END); 443 break; 444 } 445 446 if (r->handler_module && !r->resp_body_finished) { 447 const plugin * const p = r->handler_module; 448 int rc = p->handle_subrequest(r, p->data); 449 switch(rc) { 450 case HANDLER_WAIT_FOR_EVENT: 451 case HANDLER_FINISHED: 452 case HANDLER_GO_ON: 453 break; 454 case HANDLER_WAIT_FOR_FD: 455 /* (In addition to waiting for dispatch from fdwaitqueue, 456 * HTTP/2 connections may retry more frequently after any 457 * activity occurs on connection or on other streams) */ 458 connection_fdwaitqueue_append(con); 459 break; 460 case HANDLER_COMEBACK: 461 default: 462 log_error(r->conf.errh, __FILE__, __LINE__, 463 "unexpected subrequest handler ret-value: %d %d", 464 con->fd, rc); 465 /* fall through */ 466 case HANDLER_ERROR: 467 connection_set_state_error(r, CON_STATE_ERROR); 468 break; 469 } 470 } 471 } while (r->state == CON_STATE_WRITE 472 && r->http_version <= HTTP_VERSION_1_1 473 && (!chunkqueue_is_empty(r->write_queue) 474 ? con->is_writable 475 : r->resp_body_finished)); 476 } 477 478 479 __attribute_cold__ 480 static connection *connection_init(server *srv) { 481 connection * const con = calloc(1, sizeof(*con)); 482 force_assert(NULL != con); 483 484 con->fd = 0; 485 con->ndx = -1; 486 con->bytes_written = 0; 487 con->bytes_read = 0; 488 489 con->dst_addr_buf = buffer_init(); 490 con->srv = srv; 491 con->plugin_slots = srv->plugin_slots; 492 con->config_data_base = srv->config_data_base; 493 494 request_st * const r = &con->request; 495 request_init(r, con, srv); 496 config_reset_config(r); 497 con->write_queue = r->write_queue; 498 con->read_queue = r->read_queue; 499 500 /* init plugin-specific per-connection structures */ 501 con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *)); 502 force_assert(NULL != con->plugin_ctx); 503 504 return con; 505 } 506 507 508 void connections_free(server *srv) { 509 connections * const conns = &srv->conns; 510 for (uint32_t i = 0; i < conns->size; ++i) { 511 connection *con = conns->ptr[i]; 512 request_st * const r = &con->request; 513 514 connection_reset(con); 515 if (con->write_queue != r->write_queue) 516 chunkqueue_free(con->write_queue); 517 if (con->read_queue != r->read_queue) 518 chunkqueue_free(con->read_queue); 519 request_free(r); 520 521 free(con->plugin_ctx); 522 buffer_free(con->dst_addr_buf); 523 524 free(con); 525 } 526 527 free(conns->ptr); 528 conns->ptr = NULL; 529 } 530 531 532 static void connection_reset(connection *con) { 533 request_st * const r = &con->request; 534 request_reset(r); 535 config_reset_config(r); 536 r->bytes_read_ckpt = 0; 537 r->bytes_written_ckpt = 0; 538 con->is_readable = 1; 539 540 con->bytes_written = 0; 541 con->bytes_written_cur_second = 0; 542 con->bytes_read = 0; 543 } 544 545 546 __attribute_noinline__ 547 static void connection_discard_blank_line(request_st * const r, const char * const s, unsigned short * const hoff) { 548 if ((s[0] == '\r' && s[1] == '\n') 549 || (s[0] == '\n' 550 && !(r->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT))) { 551 hoff[2] += hoff[1]; 552 memmove(hoff+1, hoff+2, (--hoff[0] - 1) * sizeof(unsigned short)); 553 } 554 } 555 556 static chunk * connection_read_header_more(connection *con, chunkqueue *cq, chunk *c, const size_t olen) { 557 /*(should not be reached by HTTP/2 streams)*/ 558 /*if (r->http_version == HTTP_VERSION_2) return NULL;*/ 559 /*(However, new connections over TLS may become HTTP/2 connections via ALPN 560 * and return from this routine with r->http_version == HTTP_VERSION_2) */ 561 562 if ((NULL == c || NULL == c->next) && con->is_readable) { 563 con->read_idle_ts = log_epoch_secs; 564 if (0 != con->network_read(con, cq, MAX_READ_LIMIT)) { 565 request_st * const r = &con->request; 566 connection_set_state_error(r, CON_STATE_ERROR); 567 } 568 /* check if switched to HTTP/2 (ALPN "h2" during TLS negotiation) */ 569 request_st * const r = &con->request; 570 if (r->http_version == HTTP_VERSION_2) return NULL; 571 } 572 573 if (cq->first != cq->last && 0 != olen) { 574 const size_t clen = chunkqueue_length(cq); 575 size_t block = (olen + (16384-1)) & (16384-1); 576 block += (block - olen > 1024 ? 0 : 16384); 577 chunkqueue_compact_mem(cq, block > clen ? clen : block); 578 } 579 580 /* detect if data is added to chunk */ 581 c = cq->first; 582 return (c && (size_t)c->offset + olen < buffer_string_length(c->mem)) 583 ? c 584 : NULL; 585 } 586 587 588 static void 589 connection_transition_h2 (request_st * const h2r, connection * const con) 590 { 591 buffer_copy_string_len(&h2r->target, CONST_STR_LEN("*")); 592 buffer_copy_string_len(&h2r->target_orig, CONST_STR_LEN("*")); 593 buffer_copy_string_len(&h2r->uri.path, CONST_STR_LEN("*")); 594 h2r->http_method = HTTP_METHOD_PRI; 595 h2r->reqbody_length = -1; /*(unnecessary for h2r?)*/ 596 h2r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN; 597 598 /* (h2r->state == CON_STATE_READ) for transition by ALPN 599 * or starting cleartext HTTP/2 with Prior Knowledge 600 * (e.g. via HTTP Alternative Services) 601 * (h2r->state == CON_STATE_RESPONSE_END) for Upgrade: h2c */ 602 603 if (h2r->state != CON_STATE_ERROR) 604 connection_set_state(h2r, CON_STATE_WRITE); 605 606 #if 0 /* ... if it turns out we need a separate fdevent handler for HTTP/2 */ 607 con->fdn->handler = connection_handle_fdevent_h2; 608 #endif 609 610 if (NULL == con->h2) /*(not yet transitioned to HTTP/2; not Upgrade: h2c)*/ 611 h2_init_con(h2r, con, NULL); 612 } 613 614 615 /** 616 * handle request header read 617 * 618 * we get called by the state-engine and by the fdevent-handler 619 */ 620 __attribute_noinline__ 621 static int connection_handle_read_state(connection * const con) { 622 /*(should not be reached by HTTP/2 streams)*/ 623 chunkqueue * const cq = con->read_queue; 624 chunk *c = cq->first; 625 uint32_t clen = 0; 626 uint32_t header_len = 0; 627 request_st * const r = &con->request; 628 int keepalive_request_start = 0; 629 int pipelined_request_start = 0; 630 unsigned short hoff[8192]; /* max num header lines + 3; 16k on stack */ 631 632 if (con->request_count > 1 && con->bytes_read == r->bytes_read_ckpt) { 633 keepalive_request_start = 1; 634 if (NULL != c) { /* !chunkqueue_is_empty(cq)) */ 635 pipelined_request_start = 1; 636 /* partial header of next request has already been read, 637 * so optimistically check for more data received on 638 * socket while processing the previous request */ 639 con->is_readable = 1; 640 /*(if partially read next request and unable to read() any bytes, 641 * then will unnecessarily scan again before subsequent read())*/ 642 } 643 } 644 645 do { 646 if (NULL == c) continue; 647 clen = buffer_string_length(c->mem) - c->offset; 648 if (0 == clen) continue; 649 if (c->offset > USHRT_MAX) /*(highly unlikely)*/ 650 chunkqueue_compact_mem(cq, clen); 651 652 hoff[0] = 1; /* number of lines */ 653 hoff[1] = (unsigned short)c->offset; /* base offset for all lines */ 654 /*hoff[2] = ...;*/ /* offset from base for 2nd line */ 655 656 header_len = http_header_parse_hoff(c->mem->ptr + c->offset,clen,hoff); 657 658 /* casting to (unsigned short) might truncate, and the hoff[] 659 * addition might overflow, but max_request_field_size is USHRT_MAX, 660 * so failure will be detected below */ 661 const uint32_t max_request_field_size=r->conf.max_request_field_size; 662 if ((header_len ? header_len : clen) > max_request_field_size 663 || hoff[0] >= sizeof(hoff)/sizeof(hoff[0])-1) { 664 log_error(r->conf.errh, __FILE__, __LINE__, "%s", 665 "oversized request-header -> sending Status 431"); 666 r->http_status = 431; /* Request Header Fields Too Large */ 667 r->keep_alive = 0; 668 connection_set_state(r, CON_STATE_REQUEST_END); 669 return 1; 670 } 671 672 if (0 != header_len) break; 673 if (((unsigned char *)c->mem->ptr)[c->offset] < 32) { 674 /* expecting ASCII method beginning with alpha char 675 * or HTTP/2 pseudo-header beginning with ':' */ 676 /*(TLS handshake begins with SYN 0x16 (decimal 22))*/ 677 log_error(r->conf.errh, __FILE__, __LINE__, "%s", 678 "invalid request-line -> sending Status 400"); 679 r->http_status = 400; /* Bad Request */ 680 r->keep_alive = 0; 681 connection_set_state(r, CON_STATE_REQUEST_END); 682 return 1; 683 } 684 } while ((c = connection_read_header_more(con, cq, c, clen))); 685 686 if (keepalive_request_start) { 687 if (con->bytes_read > r->bytes_read_ckpt) { 688 /* update r->start_ts timestamp when first byte of 689 * next request is received on a keep-alive connection */ 690 r->start_ts = log_epoch_secs; 691 if (r->conf.high_precision_timestamps) 692 log_clock_gettime_realtime(&r->start_hp); 693 } 694 if (pipelined_request_start && c) con->read_idle_ts = log_epoch_secs; 695 } 696 697 if (NULL == c) return 0; /* incomplete request headers */ 698 699 #ifdef __COVERITY__ 700 if (buffer_string_length(c->mem) < hoff[1]) { 701 return 1; 702 } 703 #endif 704 705 char * const hdrs = c->mem->ptr + hoff[1]; 706 707 if (con->request_count > 1) { 708 /* skip past \r\n or \n after previous POST request when keep-alive */ 709 if (hoff[2] - hoff[1] <= 2) 710 connection_discard_blank_line(r, hdrs, hoff); 711 712 /* clear buffers which may have been kept for reporting on keep-alive, 713 * (e.g. mod_status) */ 714 buffer_clear(&r->uri.authority); 715 buffer_reset(&r->uri.path); 716 buffer_reset(&r->uri.query); 717 buffer_reset(&r->target_orig); 718 } 719 /* RFC7540 3.5 HTTP/2 Connection Preface 720 * "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 721 * (Connection Preface MUST be exact match) 722 * If ALT-SVC used to advertise HTTP/2, then client might start 723 * http connection (not TLS) sending HTTP/2 connection preface. 724 * (note: intentionally checking only on initial request) */ 725 else if (!con->is_ssl_sock && r->conf.h2proto 726 && hoff[0] == 2 && hoff[2] == 16 727 && hdrs[0]=='P' && hdrs[1]=='R' && hdrs[2]=='I' && hdrs[3]==' ') { 728 r->http_version = HTTP_VERSION_2; 729 return 0; 730 } 731 732 r->rqst_header_len = header_len; 733 if (r->conf.log_request_header) 734 log_error(r->conf.errh, __FILE__, __LINE__, 735 "fd: %d request-len: %d\n%.*s", con->fd, 736 (int)header_len, (int)header_len, hdrs); 737 http_request_headers_process(r, hdrs, hoff, con->proto_default_port); 738 chunkqueue_mark_written(cq, r->rqst_header_len); 739 connection_set_state(r, CON_STATE_REQUEST_END); 740 741 if (!con->is_ssl_sock && r->conf.h2proto && 0 == r->http_status 742 && h2_check_con_upgrade_h2c(r)) { 743 /*(Upgrade: h2c over cleartext does not have SNI; no COMP_HTTP_HOST)*/ 744 r->conditional_is_valid = (1 << COMP_SERVER_SOCKET) 745 | (1 << COMP_HTTP_REMOTE_IP); 746 /*connection_handle_write(r, con);*//* defer write to network */ 747 return 0; 748 } 749 750 return 1; 751 } 752 753 754 static void connection_state_machine_h2 (request_st *r, connection *con); 755 756 static handler_t connection_handle_fdevent(void *context, int revents) { 757 connection *con = context; 758 759 if (con->is_ssl_sock) { 760 /* ssl may read and write for both reads and writes */ 761 if (revents & (FDEVENT_IN | FDEVENT_OUT)) { 762 con->is_readable = 1; 763 con->is_writable = 1; 764 } 765 } else { 766 if (revents & FDEVENT_IN) { 767 con->is_readable = 1; 768 } 769 if (revents & FDEVENT_OUT) { 770 con->is_writable = 1; 771 /* we don't need the event twice */ 772 } 773 } 774 775 request_st * const r = &con->request; 776 777 if (r->http_version == HTTP_VERSION_2) { 778 connection_state_machine_h2(r, con); 779 if (-1 == con->fd) /*(con closed; CON_STATE_CONNECT)*/ 780 return HANDLER_FINISHED; 781 } 782 else { 783 joblist_append(con); 784 785 if (r->state == CON_STATE_READ) { 786 if (!connection_handle_read_state(con) 787 && r->http_version == HTTP_VERSION_2) 788 connection_transition_h2(r, con); 789 } 790 791 if (r->state == CON_STATE_WRITE && 792 !chunkqueue_is_empty(con->write_queue) && 793 con->is_writable) { 794 connection_handle_write(r, con); 795 } 796 } 797 798 if (r->state == CON_STATE_CLOSE) { 799 /* flush the read buffers */ 800 connection_read_for_eos(con); 801 } 802 803 804 /* attempt (above) to read data in kernel socket buffers 805 * prior to handling FDEVENT_HUP and FDEVENT_ERR */ 806 807 if ((revents & ~(FDEVENT_IN | FDEVENT_OUT)) && r->state != CON_STATE_ERROR) { 808 if (r->state == CON_STATE_CLOSE) { 809 con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1); 810 } else if (revents & FDEVENT_HUP) { 811 connection_set_state_error(r, CON_STATE_ERROR); 812 } else if (revents & FDEVENT_RDHUP) { 813 int events = fdevent_fdnode_interest(con->fdn); 814 events &= ~(FDEVENT_IN|FDEVENT_RDHUP); 815 r->conf.stream_request_body &= ~(FDEVENT_STREAM_REQUEST_BUFMIN|FDEVENT_STREAM_REQUEST_POLLIN); 816 r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLRDHUP; 817 con->is_readable = 1; /*(can read 0 for end-of-stream)*/ 818 if (chunkqueue_is_empty(con->read_queue)) r->keep_alive = 0; 819 if (r->reqbody_length < -1) { /*(transparent proxy mode; no more data to read)*/ 820 r->reqbody_length = r->reqbody_queue->bytes_in; 821 } 822 if (sock_addr_get_family(&con->dst_addr) == AF_UNIX) { 823 /* future: will getpeername() on AF_UNIX properly check if still connected? */ 824 fdevent_fdnode_event_set(con->srv->ev, con->fdn, events); 825 } else if (fdevent_is_tcp_half_closed(con->fd)) { 826 /* Success of fdevent_is_tcp_half_closed() after FDEVENT_RDHUP indicates TCP FIN received, 827 * but does not distinguish between client shutdown(fd, SHUT_WR) and client close(fd). 828 * Remove FDEVENT_RDHUP so that we do not spin on the ready event. 829 * However, a later TCP RST will not be detected until next write to socket. 830 * future: might getpeername() to check for TCP RST on half-closed sockets 831 * (without FDEVENT_RDHUP interest) when checking for write timeouts 832 * once a second in server.c, though getpeername() on Windows might not indicate this */ 833 r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_TCP_FIN; 834 fdevent_fdnode_event_set(con->srv->ev, con->fdn, events); 835 } else { 836 /* Failure of fdevent_is_tcp_half_closed() indicates TCP RST 837 * (or unable to tell (unsupported OS), though should not 838 * be setting FDEVENT_RDHUP in that case) */ 839 connection_set_state_error(r, CON_STATE_ERROR); 840 } 841 } else if (revents & FDEVENT_ERR) { /* error, connection reset */ 842 connection_set_state_error(r, CON_STATE_ERROR); 843 } else { 844 log_error(r->conf.errh, __FILE__, __LINE__, 845 "connection closed: poll() -> ??? %d", revents); 846 } 847 } 848 849 return HANDLER_FINISHED; 850 } 851 852 853 connection *connection_accept(server *srv, server_socket *srv_socket) { 854 int cnt; 855 sock_addr cnt_addr; 856 size_t cnt_len = sizeof(cnt_addr); /*(size_t intentional; not socklen_t)*/ 857 858 /** 859 * check if we can still open a new connections 860 * 861 * see #1216 862 */ 863 864 if (srv->conns.used >= srv->max_conns) { 865 return NULL; 866 } 867 868 cnt = fdevent_accept_listenfd(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len); 869 if (-1 == cnt) { 870 switch (errno) { 871 case EAGAIN: 872 #if EWOULDBLOCK != EAGAIN 873 case EWOULDBLOCK: 874 #endif 875 case EINTR: 876 /* we were stopped _before_ we had a connection */ 877 case ECONNABORTED: /* this is a FreeBSD thingy */ 878 /* we were stopped _after_ we had a connection */ 879 break; 880 case EMFILE: 881 /* out of fds */ 882 break; 883 default: 884 log_perror(srv->errh, __FILE__, __LINE__, "accept failed"); 885 } 886 return NULL; 887 } else { 888 if (sock_addr_get_family(&cnt_addr) != AF_UNIX) { 889 network_accept_tcp_nagle_disable(cnt); 890 } 891 return connection_accepted(srv, srv_socket, &cnt_addr, cnt); 892 } 893 } 894 895 896 __attribute_cold__ 897 static int connection_read_cq_err(connection *con) { 898 request_st * const r = &con->request; 899 #if defined(__WIN32) 900 int lastError = WSAGetLastError(); 901 switch (lastError) { 902 case EAGAIN: 903 return 0; 904 case EINTR: 905 /* we have been interrupted before we could read */ 906 con->is_readable = 1; 907 return 0; 908 case ECONNRESET: 909 /* suppress logging for this error, expected for keep-alive */ 910 break; 911 default: 912 log_error(r->conf.errh, __FILE__, __LINE__, 913 "connection closed - recv failed: %d", lastError); 914 break; 915 } 916 #else /* __WIN32 */ 917 switch (errno) { 918 case EAGAIN: 919 return 0; 920 case EINTR: 921 /* we have been interrupted before we could read */ 922 con->is_readable = 1; 923 return 0; 924 case ECONNRESET: 925 /* suppress logging for this error, expected for keep-alive */ 926 break; 927 default: 928 log_perror(r->conf.errh, __FILE__, __LINE__, 929 "connection closed - read failed"); 930 break; 931 } 932 #endif /* __WIN32 */ 933 934 connection_set_state_error(r, CON_STATE_ERROR); 935 return -1; 936 } 937 938 939 /* 0: everything ok, -1: error, -2: con closed */ 940 static int connection_read_cq(connection *con, chunkqueue *cq, off_t max_bytes) { 941 ssize_t len; 942 size_t mem_len = 0; 943 944 do { 945 /* obtain chunk memory into which to read 946 * fill previous chunk if it has a reasonable amount of space available 947 * (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz) 948 */ 949 chunk *ckpt = cq->last; 950 char * const mem = chunkqueue_get_memory(cq, &mem_len); 951 if (mem_len > (size_t)max_bytes) mem_len = (size_t)max_bytes; 952 953 #if defined(__WIN32) 954 len = recv(con->fd, mem, mem_len, 0); 955 #else 956 len = read(con->fd, mem, mem_len); 957 #endif 958 959 chunkqueue_use_memory(cq, ckpt, len > 0 ? len : 0); 960 961 if (len != (ssize_t)mem_len) { 962 /* we got less then expected, wait for the next fd-event */ 963 con->is_readable = 0; 964 965 if (len > 0) { 966 con->bytes_read += len; 967 return 0; 968 } 969 else if (0 == len) /* other end close connection -> KEEP-ALIVE */ 970 return -2; /* (pipelining) */ 971 else 972 return connection_read_cq_err(con); 973 } 974 975 con->bytes_read += len; 976 max_bytes -= len; 977 978 int frd; 979 mem_len = (0 == fdevent_ioctl_fionread(con->fd, S_IFSOCK, &frd)) 980 ? (frd < max_bytes) ? (size_t)frd : (size_t)max_bytes 981 : 0; 982 } while (max_bytes); 983 return 0; 984 } 985 986 987 static int connection_write_cq(connection *con, chunkqueue *cq, off_t max_bytes) { 988 request_st * const r = &con->request; 989 return con->srv->network_backend_write(con->fd,cq,max_bytes,r->conf.errh); 990 } 991 992 993 static handler_t connection_handle_read_post_state(request_st * const r); 994 995 connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) { 996 connection *con; 997 998 srv->cur_fds++; 999 1000 /* ok, we have the connection, register it */ 1001 #if 0 1002 log_error(srv->errh, __FILE__, __LINE__, "accepted() %d", cnt); 1003 #endif 1004 srv->con_opened++; 1005 1006 con = connections_get_new_connection(srv); 1007 1008 con->fd = cnt; 1009 con->fdn = fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con); 1010 con->network_read = connection_read_cq; 1011 con->network_write = connection_write_cq; 1012 con->reqbody_read = connection_handle_read_post_state; 1013 1014 request_st * const r = &con->request; 1015 connection_set_state(r, CON_STATE_REQUEST_START); 1016 1017 con->connection_start = log_epoch_secs; 1018 con->dst_addr = *cnt_addr; 1019 buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); 1020 con->srv_socket = srv_socket; 1021 con->is_ssl_sock = srv_socket->is_ssl; 1022 con->proto_default_port = 80; /* "http" */ 1023 1024 config_cond_cache_reset(r); 1025 r->conditional_is_valid = (1 << COMP_SERVER_SOCKET) 1026 | (1 << COMP_HTTP_REMOTE_IP); 1027 1028 if (HANDLER_GO_ON != plugins_call_handle_connection_accept(con)) { 1029 connection_reset(con); 1030 connection_close(con); 1031 return NULL; 1032 } 1033 if (r->http_status < 0) connection_set_state(r, CON_STATE_WRITE); 1034 return con; 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