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