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