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