xref: /lighttpd1.4/src/connections.c (revision 34709192)
1 #include "first.h"
2 
3 #include "base.h"
4 #include "buffer.h"
5 #include "burl.h"       /* HTTP_PARSEOPT_HEADER_STRICT */
6 #include "settings.h"   /* BUFFER_MAX_REUSE_SIZE MAX_READ_LIMIT MAX_WRITE_LIMIT */
7 #include "log.h"
8 #include "connections.h"
9 #include "fdevent.h"
10 #include "http_header.h"
11 
12 #include "request.h"
13 #include "response.h"
14 #include "network.h"
15 #include "http_chunk.h"
16 #include "stat_cache.h"
17 
18 #include "plugin.h"
19 
20 #include "inet_ntop_cache.h"
21 
22 #include <sys/stat.h>
23 
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <string.h>
28 
29 #ifdef HAVE_SYS_FILIO_H
30 # include <sys/filio.h>
31 #endif
32 
33 #include "sys-socket.h"
34 
35 #define HTTP_LINGER_TIMEOUT 5
36 
37 #define connection_set_state(r, n) ((r)->state = (n))
38 
39 __attribute_cold__
40 static connection *connection_init(server *srv);
41 
42 static void connection_reset(connection *con);
43 
44 
45 static connection *connections_get_new_connection(server *srv) {
46 	connections * const conns = &srv->conns;
47 	size_t i;
48 
49 	if (conns->size == conns->used) {
50 		conns->size += srv->max_conns >= 128 ? 128 : srv->max_conns > 16 ? 16 : srv->max_conns;
51 		conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
52 		force_assert(NULL != conns->ptr);
53 
54 		for (i = conns->used; i < conns->size; i++) {
55 			conns->ptr[i] = connection_init(srv);
56 			connection_reset(conns->ptr[i]);
57 		}
58 	}
59 
60 	conns->ptr[conns->used]->ndx = conns->used;
61 	return conns->ptr[conns->used++];
62 }
63 
64 static void connection_del(server *srv, connection *con) {
65 	connections * const conns = &srv->conns;
66 
67 	if (-1 == con->ndx) return;
68 	uint32_t i = (uint32_t)con->ndx;
69 
70 	/* not last element */
71 
72 	if (i != --conns->used) {
73 		connection * const temp = conns->ptr[i];
74 		conns->ptr[i] = conns->ptr[conns->used];
75 		conns->ptr[conns->used] = temp;
76 
77 		conns->ptr[i]->ndx = i;
78 		conns->ptr[conns->used]->ndx = -1;
79 	}
80 
81 	con->ndx = -1;
82 #if 0
83 	fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
84 	for (i = 0; i < conns->used; i++) {
85 		fprintf(stderr, "%d ", conns->ptr[i]->fd);
86 	}
87 	fprintf(stderr, "\n");
88 #endif
89 }
90 
91 #if 0 /* DEBUG_DEV */
92 __attribute_cold__
93 static void connection_plugin_ctx_check(server * const srv, request_st * const r) {
94 	/* plugins should have cleaned themselves up */
95 	for (uint32_t i = 0; i < srv->plugins.used; ++i) {
96 		plugin *p = ((plugin **)(srv->plugins.ptr))[i];
97 		plugin_data_base *pd = p->data;
98 		if (!pd) continue;
99 		if (NULL == r->plugin_ctx[pd->id]
100 		    && NULL == r->con->plugin_ctx[pd->id]) continue;
101 		log_error(r->conf.errh, __FILE__, __LINE__,
102 		  "missing cleanup in %s", p->name);
103 		r->plugin_ctx[pd->id] = NULL;
104 		r->con->plugin_ctx[pd->id] = NULL;
105 	}
106 }
107 #endif
108 
109 static void connection_close(connection *con) {
110 	if (con->fd < 0) con->fd = -con->fd;
111 
112 	plugins_call_handle_connection_close(con);
113 
114 	server * const srv = con->srv;
115 	request_st * const r = &con->request;
116 
117   #if 0 /* DEBUG_DEV */
118 	/* plugins should have cleaned themselves up */
119 	for (uint32_t i = 0; i < srv->plugins.used; ++i) {
120 		if (NULL != r->plugin_ctx[i] || NULL != con->plugin_ctx[i]) {
121 			connection_plugin_ctx_check(srv, r);
122 			break;
123 		}
124 	}
125   #endif
126 
127 	connection_set_state(r, CON_STATE_CONNECT);
128 	buffer_clear(&r->uri.authority);
129 	buffer_reset(&r->uri.path);
130 	buffer_reset(&r->uri.query);
131 	buffer_reset(&r->target_orig);
132 	buffer_reset(&r->target);       /*(see comments in connection_reset())*/
133 	buffer_reset(&r->pathinfo);     /*(see comments in connection_reset())*/
134 
135 	chunkqueue_reset(con->read_queue);
136 	con->request_count = 0;
137 	con->is_ssl_sock = 0;
138 
139 	fdevent_fdnode_event_del(srv->ev, con->fdn);
140 	fdevent_unregister(srv->ev, con->fd);
141 	con->fdn = NULL;
142 #ifdef __WIN32
143 	if (0 == closesocket(con->fd))
144 #else
145 	if (0 == close(con->fd))
146 #endif
147 		--srv->cur_fds;
148 	else
149 		log_perror(r->conf.errh, __FILE__, __LINE__,
150 		  "(warning) close: %d", con->fd);
151 
152 	if (r->conf.log_state_handling) {
153 		log_error(r->conf.errh, __FILE__, __LINE__,
154 		  "connection closed for fd %d", con->fd);
155 	}
156 	con->fd = -1;
157 
158 	connection_del(srv, con);
159 }
160 
161 static void connection_read_for_eos_plain(connection * const con) {
162 	/* we have to do the linger_on_close stuff regardless
163 	 * of r->keep_alive; even non-keepalive sockets
164 	 * may still have unread data, and closing before reading
165 	 * it will make the client not see all our output.
166 	 */
167 	ssize_t len;
168 	const int type = con->dst_addr.plain.sa_family;
169 	char buf[16384];
170 	do {
171 		len = fdevent_socket_read_discard(con->fd, buf, sizeof(buf),
172 						  type, SOCK_STREAM);
173 	} while (len > 0 || (len < 0 && errno == EINTR));
174 
175 	if (len < 0 && errno == EAGAIN) return;
176       #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
177 	if (len < 0 && errno == EWOULDBLOCK) return;
178       #endif
179 
180 	/* 0 == len || (len < 0 && (errno is a non-recoverable error)) */
181 		con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1);
182 }
183 
184 static void connection_read_for_eos_ssl(connection * const con) {
185 	if (con->network_read(con, con->read_queue, MAX_READ_LIMIT) < 0)
186 		con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1);
187 	chunkqueue_reset(con->read_queue);
188 }
189 
190 static void connection_read_for_eos(connection * const con) {
191 	!con->is_ssl_sock
192 	  ? connection_read_for_eos_plain(con)
193 	  : connection_read_for_eos_ssl(con);
194 }
195 
196 static void connection_handle_close_state(connection *con) {
197 	connection_read_for_eos(con);
198 
199 	if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
200 		connection_close(con);
201 	}
202 }
203 
204 static void connection_handle_shutdown(connection *con) {
205 	plugins_call_handle_connection_shut_wr(con);
206 
207 	connection_reset(con);
208 	++con->srv->con_closed;
209 
210 	/* close the connection */
211 	if (con->fd >= 0
212 	    && (con->is_ssl_sock || 0 == shutdown(con->fd, SHUT_WR))) {
213 		con->close_timeout_ts = log_epoch_secs;
214 
215 		request_st * const r = &con->request;
216 		connection_set_state(r, CON_STATE_CLOSE);
217 		if (r->conf.log_state_handling) {
218 			log_error(r->conf.errh, __FILE__, __LINE__,
219 			  "shutdown for fd %d", con->fd);
220 		}
221 	} else {
222 		connection_close(con);
223 	}
224 }
225 
226 __attribute_cold__
227 static void connection_fdwaitqueue_append(connection *con) {
228     connection_list_append(&con->srv->fdwaitqueue, con);
229 }
230 
231 static void connection_handle_response_end_state(request_st * const r, connection * const con) {
232 	/* call request_done hook if http_status set (e.g. to log request) */
233 	/* (even if error, connection dropped, as long as http_status is set) */
234 	if (r->http_status) plugins_call_handle_request_done(r);
235 
236 	if (r->state != CON_STATE_ERROR) ++con->srv->con_written;
237 
238 	if (r->reqbody_length != r->reqbody_queue->bytes_in
239 	    || r->state == CON_STATE_ERROR) {
240 		/* request body is present and has not been read completely */
241 		r->keep_alive = 0;
242 	}
243 
244         if (r->keep_alive) {
245 		connection_reset(con);
246 #if 0
247 		r->start_ts = con->read_idle_ts = log_epoch_secs;
248 #endif
249 		connection_set_state(r, CON_STATE_REQUEST_START);
250 	} else {
251 		connection_handle_shutdown(con);
252 	}
253 }
254 
255 __attribute_cold__
256 static void connection_handle_errdoc_init(request_st * const r) {
257 	/* modules that produce headers required with error response should
258 	 * typically also produce an error document.  Make an exception for
259 	 * mod_auth WWW-Authenticate response header. */
260 	buffer *www_auth = NULL;
261 	if (401 == r->http_status) {
262 		const buffer *vb = http_header_response_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"));
263 		if (NULL != vb) www_auth = buffer_init_buffer(vb);
264 	}
265 
266 	buffer_reset(&r->physical.path);
267 	r->resp_htags = 0;
268 	array_reset_data_strings(&r->resp_headers);
269 	http_response_body_clear(r, 0);
270 
271 	if (NULL != www_auth) {
272 		http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(www_auth));
273 		buffer_free(www_auth);
274 	}
275 }
276 
277 __attribute_cold__
278 static void connection_handle_errdoc(request_st * const r) {
279     if (NULL == r->handler_module
280         ? r->error_handler_saved_status >= 65535
281         : (!r->conf.error_intercept||r->error_handler_saved_status))
282         return;
283 
284     connection_handle_errdoc_init(r);
285     r->resp_body_finished = 1;
286 
287     /* try to send static errorfile */
288     if (!buffer_string_is_empty(r->conf.errorfile_prefix)) {
289         buffer_copy_buffer(&r->physical.path, r->conf.errorfile_prefix);
290         buffer_append_int(&r->physical.path, r->http_status);
291         buffer_append_string_len(&r->physical.path, CONST_STR_LEN(".html"));
292         if (0 == http_chunk_append_file(r, &r->physical.path)) {
293             stat_cache_entry *sce = stat_cache_get_entry(&r->physical.path);
294             const buffer *content_type = (NULL != sce)
295               ? stat_cache_content_type_get(sce, r)
296               : NULL;
297             if (content_type)
298                 http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
299                                          CONST_STR_LEN("Content-Type"),
300                                          CONST_BUF_LEN(content_type));
301             return;
302         }
303     }
304 
305     /* build default error-page */
306     buffer_reset(&r->physical.path);
307     buffer * const b = r->tmp_buf;
308     buffer_copy_string_len(b, CONST_STR_LEN(
309       "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
310       "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
311       "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
312       "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
313       " <head>\n"
314       "  <title>"));
315     http_status_append(b, r->http_status);
316     buffer_append_string_len(b, CONST_STR_LEN(
317       "</title>\n"
318       " </head>\n"
319       " <body>\n"
320       "  <h1>"));
321     http_status_append(b, r->http_status);
322     buffer_append_string_len(b, CONST_STR_LEN(
323       "</h1>\n"
324       " </body>\n"
325       "</html>\n"));
326     (void)http_chunk_append_mem(r, CONST_BUF_LEN(b));
327 
328     http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
329                              CONST_STR_LEN("Content-Type"),
330                              CONST_STR_LEN("text/html"));
331 }
332 
333 __attribute_cold__
334 static void
335 connection_merge_trailers (request_st * const r)
336 {
337     /* attempt to merge trailers into headers; header not yet sent by caller */
338     if (buffer_string_is_empty(&r->gw_dechunk->b)) return;
339     const int done = r->gw_dechunk->done;
340     if (!done) return; /* XXX: !done; could scan for '\n' and send only those */
341 
342     /* do not include trailers if success status (when response was read from
343      * backend) subsequently changed to error status.  http_chunk could add the
344      * trailers, but such actions are better on a different code layer than in
345      * http_chunk.c */
346     if (done < 400 && r->http_status >= 400) return;
347 
348     /* XXX: trailers passed through; no sanity check currently done
349      * https://tools.ietf.org/html/rfc7230#section-4.1.2
350      *
351      * Not checking for disallowed fields
352      * Not handling (deprecated) line wrapping
353      * Not strictly checking fields
354      */
355     const char *k = strchr(r->gw_dechunk->b.ptr, '\n'); /*(skip final chunk)*/
356     if (NULL == k) return; /*(should not happen)*/
357     ++k;
358     for (const char *v, *e; (e = strchr(k, '\n')); k = e+1) {
359         v = memchr(k, ':', (size_t)(e - k));
360         if (NULL == v || v == k || *k == ' ' || *k == '\t') continue;
361         uint32_t klen = (uint32_t)(v - k);
362         do { ++v; } while (*v == ' ' || *v == '\t');
363         if (*v == '\r' || *v == '\n') continue;
364         enum http_header_e id = http_header_hkey_get(k, klen);
365         http_header_response_insert(r, id, k, klen, v, (size_t)(e - v));
366     }
367     http_header_response_unset(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Trailer"));
368     buffer_clear(&r->gw_dechunk->b);
369 }
370 
371 static int connection_handle_write_prepare(request_st * const r) {
372 	if (NULL == r->handler_module) {
373 		/* static files */
374 		switch(r->http_method) {
375 		case HTTP_METHOD_GET:
376 		case HTTP_METHOD_POST:
377 		case HTTP_METHOD_HEAD:
378 			break;
379 		case HTTP_METHOD_OPTIONS:
380 			/*
381 			 * 400 is coming from the request-parser BEFORE uri.path is set
382 			 * 403 is from the response handler when no module handled request
383 			 *
384 			 * */
385 			if ((!r->http_status || r->http_status == 200)
386 			    && !buffer_string_is_empty(&r->uri.path)
387 			    && r->uri.path.ptr[0] != '*') {
388 				http_response_body_clear(r, 0);
389 				http_header_response_append(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
390 				r->http_status = 200;
391 				r->resp_body_finished = 1;
392 
393 			}
394 			break;
395 		default:
396 			if (0 == r->http_status) {
397 				r->http_status = 501;
398 			}
399 			break;
400 		}
401 	}
402 
403 	if (r->http_status == 0) {
404 		r->http_status = 403;
405 	}
406 
407 	switch(r->http_status) {
408 	case 204: /* class: header only */
409 	case 205:
410 	case 304:
411 		/* disable chunked encoding again as we have no body */
412 		http_response_body_clear(r, 1);
413 		r->resp_body_finished = 1;
414 		break;
415 	default: /* class: header + body */
416 		/* only custom body for 4xx and 5xx */
417 		if (r->http_status >= 400 && r->http_status < 600)
418 			connection_handle_errdoc(r);
419 		break;
420 	}
421 
422 	if (r->gw_dechunk)
423 		connection_merge_trailers(r);
424 
425 	/* Allow filter plugins to change response headers before they are written. */
426 	switch(plugins_call_handle_response_start(r)) {
427 	case HANDLER_GO_ON:
428 	case HANDLER_FINISHED:
429 		break;
430 	default:
431 		log_error(r->conf.errh, __FILE__, __LINE__,
432 		  "response_start plugin failed");
433 		return -1;
434 	}
435 
436 	if (r->resp_body_finished) {
437 		/* we have all the content and chunked encoding is not used, set a content-length */
438 
439 		if (!(r->resp_htags & (HTTP_HEADER_CONTENT_LENGTH|HTTP_HEADER_TRANSFER_ENCODING))) {
440 			off_t qlen = chunkqueue_length(r->write_queue);
441 
442 			/**
443 			 * The Content-Length header only can be sent if we have content:
444 			 * - HEAD doesn't have a content-body (but have a content-length)
445 			 * - 1xx, 204 and 304 don't have a content-body (RFC 2616 Section 4.3)
446 			 *
447 			 * Otherwise generate a Content-Length header as chunked encoding is not
448 			 * available
449 			 */
450 			if ((r->http_status >= 100 && r->http_status < 200) ||
451 			    r->http_status == 204 ||
452 			    r->http_status == 304) {
453 				/* no Content-Body, no Content-Length */
454 				http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"));
455 			} else if (qlen > 0) {
456 				buffer * const tb = r->tmp_buf;
457 				buffer_clear(tb);
458 				buffer_append_int(tb, qlen);
459 				http_header_response_set(r, HTTP_HEADER_CONTENT_LENGTH,
460 				                         CONST_STR_LEN("Content-Length"),
461 				                         CONST_BUF_LEN(tb));
462 			} else if (r->http_method != HTTP_METHOD_HEAD) {
463 				/* qlen = 0 is important for Redirects (301, ...) as they MAY have
464 				 * a content. Browsers are waiting for a Content otherwise
465 				 */
466 				http_header_response_set(r, HTTP_HEADER_CONTENT_LENGTH,
467 				                         CONST_STR_LEN("Content-Length"),
468 				                         CONST_STR_LEN("0"));
469 			}
470 		}
471 	} else {
472 		/**
473 		 * the file isn't finished yet, but we have all headers
474 		 *
475 		 * to get keep-alive we either need:
476 		 * - Content-Length: ... (HTTP/1.0 and HTTP/1.0) or
477 		 * - Transfer-Encoding: chunked (HTTP/1.1)
478 		 * - Upgrade: ... (lighttpd then acts as transparent proxy)
479 		 */
480 
481 		if (!(r->resp_htags & (HTTP_HEADER_CONTENT_LENGTH|HTTP_HEADER_TRANSFER_ENCODING|HTTP_HEADER_UPGRADE))) {
482 			if (r->http_method == HTTP_METHOD_CONNECT
483 			    && r->http_status == 200) {
484 				/*(no transfer-encoding if successful CONNECT)*/
485 			} else if (r->http_version == HTTP_VERSION_1_1) {
486 				off_t qlen = chunkqueue_length(r->write_queue);
487 				r->resp_send_chunked = 1;
488 				if (qlen) {
489 					/* create initial Transfer-Encoding: chunked segment */
490 					buffer * const b = chunkqueue_prepend_buffer_open(r->write_queue);
491 					buffer_append_uint_hex(b, (uintmax_t)qlen);
492 					buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
493 					chunkqueue_prepend_buffer_commit(r->write_queue);
494 					chunkqueue_append_mem(r->write_queue, CONST_STR_LEN("\r\n"));
495 				}
496 				http_header_response_append(r, HTTP_HEADER_TRANSFER_ENCODING, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN("chunked"));
497 			} else {
498 				r->keep_alive = 0;
499 			}
500 		}
501 	}
502 
503 	if (r->http_method == HTTP_METHOD_HEAD) {
504 		/**
505 		 * a HEAD request has the same as a GET
506 		 * without the content
507 		 */
508 		http_response_body_clear(r, 1);
509 		r->resp_body_finished = 1;
510 	}
511 
512 	http_response_write_header(r);
513 
514 	return 0;
515 }
516 
517 static void connection_handle_write(connection *con) {
518 	int rc = connection_write_chunkqueue(con, con->write_queue, MAX_WRITE_LIMIT);
519 	request_st * const r = &con->request;
520 	switch (rc) {
521 	case 0:
522 		if (r->resp_body_finished) {
523 			connection_set_state(r, CON_STATE_RESPONSE_END);
524 		}
525 		break;
526 	case -1: /* error on our side */
527 		log_error(r->conf.errh, __FILE__, __LINE__,
528 		  "connection closed: write failed on fd %d", con->fd);
529 		connection_set_state(r, CON_STATE_ERROR);
530 		break;
531 	case -2: /* remote close */
532 		connection_set_state(r, CON_STATE_ERROR);
533 		break;
534 	case 1:
535 		con->is_writable = 0;
536 
537 		/* not finished yet -> WRITE */
538 		break;
539 	}
540 }
541 
542 static void connection_handle_write_state(request_st * const r, connection * const con) {
543     do {
544         /* only try to write if we have something in the queue */
545         if (!chunkqueue_is_empty(con->write_queue)) {
546             if (con->is_writable) {
547                 connection_handle_write(con);
548                 if (r->state != CON_STATE_WRITE) break;
549             }
550         } else if (r->resp_body_finished) {
551             connection_set_state(r, CON_STATE_RESPONSE_END);
552             break;
553         }
554 
555         if (r->handler_module && !r->resp_body_finished) {
556             const plugin * const p = r->handler_module;
557             int rc = p->handle_subrequest(r, p->data);
558             switch(rc) {
559             case HANDLER_WAIT_FOR_EVENT:
560             case HANDLER_FINISHED:
561             case HANDLER_GO_ON:
562                 break;
563             case HANDLER_WAIT_FOR_FD:
564                 connection_fdwaitqueue_append(con);
565                 break;
566             case HANDLER_COMEBACK:
567             default:
568                 log_error(r->conf.errh, __FILE__, __LINE__,
569                   "unexpected subrequest handler ret-value: %d %d",
570                   con->fd, rc);
571                 /* fall through */
572             case HANDLER_ERROR:
573                 connection_set_state(r, CON_STATE_ERROR);
574                 break;
575             }
576         }
577     } while (r->state == CON_STATE_WRITE
578              && (!chunkqueue_is_empty(con->write_queue)
579                  ? con->is_writable
580                  : r->resp_body_finished));
581 }
582 
583 
584 __attribute_cold__
585 static void
586 request_init (request_st * const r, connection * const con, server * const srv)
587 {
588 	r->write_queue = chunkqueue_init();
589 	r->read_queue = chunkqueue_init();
590 	r->reqbody_queue = chunkqueue_init();
591 
592 	r->resp_header_len = 0;
593 	r->loops_per_request = 0;
594 	r->con = con;
595 	r->tmp_buf = srv->tmp_buf;
596 
597 	/* init plugin-specific per-request structures */
598 	r->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
599 	force_assert(NULL != r->plugin_ctx);
600 
601 	r->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
602 	force_assert(NULL != r->cond_cache);
603 
604       #ifdef HAVE_PCRE_H
605 	if (srv->config_context->used > 1) {/*(save 128b per con if no conditions)*/
606 		r->cond_match =
607 		  calloc(srv->config_context->used, sizeof(cond_match_t));
608 		force_assert(NULL != r->cond_match);
609 	}
610       #endif
611 
612 	config_reset_config(r);
613 }
614 
615 __attribute_cold__
616 static connection *connection_init(server *srv) {
617 	connection * const con = calloc(1, sizeof(*con));
618 	force_assert(NULL != con);
619 
620 	con->fd = 0;
621 	con->ndx = -1;
622 	con->bytes_written = 0;
623 	con->bytes_read = 0;
624 
625 	con->dst_addr_buf = buffer_init();
626 	con->srv  = srv;
627 	con->plugin_slots = srv->plugin_slots;
628 	con->config_data_base = srv->config_data_base;
629 
630 	request_st * const r = &con->request;
631 	request_init(r, con, srv);
632 	con->write_queue = r->write_queue;
633 	con->read_queue = r->read_queue;
634 
635 	/* init plugin-specific per-connection structures */
636 	con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
637 	force_assert(NULL != con->plugin_ctx);
638 
639 	return con;
640 }
641 
642 
643 static void
644 request_free (request_st * const r)
645 {
646 		chunkqueue_free(r->reqbody_queue);
647 		chunkqueue_free(r->write_queue);
648 		chunkqueue_free(r->read_queue);
649 		array_free_data(&r->rqst_headers);
650 		array_free_data(&r->resp_headers);
651 		array_free_data(&r->env);
652 
653 		free(r->target.ptr);
654 		free(r->target_orig.ptr);
655 
656 		free(r->uri.scheme.ptr);
657 		free(r->uri.authority.ptr);
658 		free(r->uri.path.ptr);
659 		free(r->uri.query.ptr);
660 
661 		free(r->physical.doc_root.ptr);
662 		free(r->physical.path.ptr);
663 		free(r->physical.basedir.ptr);
664 		free(r->physical.etag.ptr);
665 		free(r->physical.rel_path.ptr);
666 
667 		free(r->pathinfo.ptr);
668 		free(r->server_name_buf.ptr);
669 
670 		free(r->plugin_ctx);
671 		free(r->cond_cache);
672 		free(r->cond_match);
673 
674 		/* note: r is not zeroed here and r is not freed here */
675 }
676 
677 void connections_free(server *srv) {
678 	connections * const conns = &srv->conns;
679 	for (uint32_t i = 0; i < conns->size; ++i) {
680 		connection *con = conns->ptr[i];
681 		request_st * const r = &con->request;
682 
683 		connection_reset(con);
684 		if (con->write_queue != r->write_queue)
685 			chunkqueue_free(con->write_queue);
686 		if (con->read_queue != r->read_queue)
687 			chunkqueue_free(con->read_queue);
688 		request_free(r);
689 
690 		free(con->plugin_ctx);
691 		buffer_free(con->dst_addr_buf);
692 
693 		free(con);
694 	}
695 
696 	free(conns->ptr);
697 	conns->ptr = NULL;
698 }
699 
700 
701 static void
702 request_reset (request_st * const r) {
703 	plugins_call_handle_request_reset(r);
704 
705 	connection_response_reset(r);
706 
707 	r->resp_header_len = 0;
708 	r->loops_per_request = 0;
709 
710 	r->http_method = HTTP_METHOD_UNSET;
711 	r->http_version = HTTP_VERSION_UNSET;
712 
713 	/*con->proto_default_port = 80;*//*set to default in connection_accepted()*/
714 
715 	r->http_host = NULL;
716 	r->reqbody_length = 0;
717 	r->te_chunked = 0;
718 	r->rqst_htags = 0;
719 
720 	buffer_clear(&r->uri.scheme);
721 
722 	if (r->rqst_header_len <= BUFFER_MAX_REUSE_SIZE) {
723 		r->rqst_headers.used = 0;
724 		/* (Note: total header size not recalculated on HANDLER_COMEBACK
725 		 *  even if other request headers changed during processing)
726 		 * (While this might delay release of larger buffers, it is not
727 		 *  expected to be the general case.  For those systems where it
728 		 *  is a typical case, the larger buffers are likely to be reused) */
729 		buffer_clear(&r->target);
730 		buffer_clear(&r->pathinfo);
731 		/*buffer_clear(&r->target_orig);*/  /* reset later; used by mod_status*/
732 		/*buffer_clear(&r->uri.path);*/     /* reset later; used by mod_status*/
733 		/*buffer_clear(&r->uri.query);*/    /* reset later; used by mod_status*/
734 		/*buffer_clear(&r->uri.authority);*//* reset later; used by mod_status*/
735 		/*buffer_clear(&r->server_name_buf);*//* reset when used */
736 	}
737 	else {
738 		buffer_reset(&r->target);
739 		buffer_reset(&r->pathinfo);
740 		/*buffer_reset(&r->target_orig);*/  /* reset later; used by mod_status*/
741 		/*buffer_reset(&r->uri.path);*/     /* reset later; used by mod_status*/
742 		/*buffer_reset(&r->uri.query);*/    /* reset later; used by mod_status*/
743 		/*buffer_clear(&r->uri.authority);*//* reset later; used by mod_status*/
744 		/*buffer_clear(&r->server_name_buf);*//* reset when used */
745 		array_reset_data_strings(&r->rqst_headers);
746 	}
747 	r->rqst_header_len = 0;
748 	if (0 != r->env.used)
749 		array_reset_data_strings(&r->env);
750 
751 	chunkqueue_reset(r->reqbody_queue);
752 
753 	/* The cond_cache gets reset in response.c */
754 	/* config_cond_cache_reset(r); */
755 
756 	r->async_callback = 0;
757 	r->error_handler_saved_status = 0;
758 	/*r->error_handler_saved_method = HTTP_METHOD_UNSET;*/
759 	/*(error_handler_saved_method value is not valid unless error_handler_saved_status is set)*/
760 
761 	config_reset_config(r);
762 }
763 
764 static void connection_reset(connection *con) {
765 	request_st * const r = &con->request;
766 	request_reset(r);
767 	con->is_readable = 1;
768 
769 	con->bytes_written = 0;
770 	con->bytes_written_cur_second = 0;
771 	con->bytes_read = 0;
772 }
773 
774 
775 __attribute_noinline__
776 static void connection_discard_blank_line(request_st * const r, const char * const s, unsigned short * const hoff)  {
777     if ((s[0] == '\r' && s[1] == '\n')
778         || (s[0] == '\n'
779             && !(r->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT))) {
780         hoff[2] += hoff[1];
781         memmove(hoff+1, hoff+2, (--hoff[0] - 1) * sizeof(unsigned short));
782     }
783 }
784 
785 static chunk * connection_read_header_more(connection *con, chunkqueue *cq, chunk *c, const size_t olen) {
786     if ((NULL == c || NULL == c->next) && con->is_readable) {
787         con->read_idle_ts = log_epoch_secs;
788         if (0 != con->network_read(con, cq, MAX_READ_LIMIT)) {
789             request_st * const r = &con->request;
790             connection_set_state(r, CON_STATE_ERROR);
791         }
792     }
793 
794     if (cq->first != cq->last && 0 != olen) {
795         const size_t clen = chunkqueue_length(cq);
796         size_t block = (olen + (16384-1)) & (16384-1);
797         block += (block - olen > 1024 ? 0 : 16384);
798         chunkqueue_compact_mem(cq, block > clen ? clen : block);
799     }
800 
801     /* detect if data is added to chunk */
802     c = cq->first;
803     return (c && (size_t)c->offset + olen < buffer_string_length(c->mem))
804       ? c
805       : NULL;
806 }
807 
808 __attribute_hot__
809 static uint32_t connection_read_header_hoff(const char *n, const uint32_t clen, unsigned short hoff[8192]) {
810     uint32_t hlen = 0;
811     for (const char *b; (n = memchr((b = n),'\n',clen-hlen)); ++n) {
812         uint32_t x = (uint32_t)(n - b + 1);
813         hlen += x;
814         if (x <= 2 && (x == 1 || n[-1] == '\r')) {
815             hoff[hoff[0]+1] = hlen;
816             return hlen;
817         }
818         if (++hoff[0] >= /*sizeof(hoff)/sizeof(hoff[0])-1*/ 8192-1) break;
819         hoff[hoff[0]] = hlen;
820     }
821     return 0;
822 }
823 
824 /**
825  * handle request header read
826  *
827  * we get called by the state-engine and by the fdevent-handler
828  */
829 static int connection_handle_read_state(connection * const con)  {
830     chunkqueue * const cq = con->read_queue;
831     chunk *c = cq->first;
832     uint32_t clen = 0;
833     uint32_t header_len = 0;
834     request_st * const r = &con->request;
835     int keepalive_request_start = 0;
836     int pipelined_request_start = 0;
837     unsigned short hoff[8192]; /* max num header lines + 3; 16k on stack */
838 
839     if (con->request_count > 1 && 0 == con->bytes_read) {
840         keepalive_request_start = 1;
841         if (NULL != c) { /* !chunkqueue_is_empty(cq)) */
842             pipelined_request_start = 1;
843             /* partial header of next request has already been read,
844              * so optimistically check for more data received on
845              * socket while processing the previous request */
846             con->is_readable = 1;
847             /*(if partially read next request and unable to read() any bytes,
848              * then will unnecessarily scan again before subsequent read())*/
849         }
850     }
851 
852     do {
853         if (NULL == c) continue;
854         clen = buffer_string_length(c->mem) - c->offset;
855         if (0 == clen) continue;
856         if (c->offset > USHRT_MAX) /*(highly unlikely)*/
857             chunkqueue_compact_mem(cq, clen);
858 
859         hoff[0] = 1;                         /* number of lines */
860         hoff[1] = (unsigned short)c->offset; /* base offset for all lines */
861         /*hoff[2] = ...;*/                   /* offset from base for 2nd line */
862 
863         header_len =
864           connection_read_header_hoff(c->mem->ptr + c->offset, clen, hoff);
865 
866         /* casting to (unsigned short) might truncate, and the hoff[]
867          * addition might overflow, but max_request_field_size is USHRT_MAX,
868          * so failure will be detected below */
869         const uint32_t max_request_field_size=r->conf.max_request_field_size;
870         if ((header_len ? header_len : clen) > max_request_field_size
871             || hoff[0] >= sizeof(hoff)/sizeof(hoff[0])-1) {
872             log_error(r->conf.errh, __FILE__, __LINE__, "%s",
873                       "oversized request-header -> sending Status 431");
874             r->http_status = 431; /* Request Header Fields Too Large */
875             r->keep_alive = 0;
876             connection_set_state(r, CON_STATE_REQUEST_END);
877             return 1;
878         }
879 
880         if (0 != header_len) break;
881         if (((unsigned char *)c->mem->ptr)[c->offset] < 32) {
882             /* expecting ASCII method beginning with alpha char
883              * or HTTP/2 pseudo-header beginning with ':' */
884             /*(TLS handshake begins with SYN 0x16 (decimal 22))*/
885             log_error(r->conf.errh, __FILE__, __LINE__, "%s",
886                       "invalid request-line -> sending Status 400");
887             r->http_status = 400; /* Bad Request */
888             r->keep_alive = 0;
889             connection_set_state(r, CON_STATE_REQUEST_END);
890             return 1;
891         }
892     } while ((c = connection_read_header_more(con, cq, c, clen)));
893 
894     if (keepalive_request_start) {
895         if (0 != con->bytes_read) {
896             /* update r->start_ts timestamp when first byte of
897              * next request is received on a keep-alive connection */
898             r->start_ts = log_epoch_secs;
899             if (r->conf.high_precision_timestamps)
900                 log_clock_gettime_realtime(&r->start_hp);
901         }
902         if (pipelined_request_start && c) con->read_idle_ts = log_epoch_secs;
903     }
904 
905     if (NULL == c) return 0; /* incomplete request headers */
906 
907   #ifdef __COVERITY__
908     if (buffer_string_length(c->mem) < hoff[1]) {
909         return 1;
910     }
911   #endif
912 
913     char * const hdrs = c->mem->ptr + hoff[1];
914 
915     if (con->request_count > 1) {
916         /* skip past \r\n or \n after previous POST request when keep-alive */
917         if (hoff[2] - hoff[1] <= 2)
918             connection_discard_blank_line(r, hdrs, hoff);
919 
920         /* clear buffers which may have been kept for reporting on keep-alive,
921          * (e.g. mod_status) */
922         buffer_clear(&r->uri.authority);
923         buffer_reset(&r->uri.path);
924         buffer_reset(&r->uri.query);
925         buffer_reset(&r->target_orig);
926     }
927 
928     if (r->conf.log_request_header) {
929         log_error(r->conf.errh, __FILE__, __LINE__,
930                   "fd: %d request-len: %d\n%.*s", con->fd, (int)header_len,
931                   (int)header_len, hdrs);
932     }
933 
934     r->http_status = http_request_parse(r, hdrs, hoff, con->proto_default_port);
935     if (0 == r->http_status) {
936         r->conditional_is_valid = (1 << COMP_SERVER_SOCKET)
937                                 | (1 << COMP_HTTP_SCHEME)
938                                 | (1 << COMP_HTTP_HOST)
939                                 | (1 << COMP_HTTP_REMOTE_IP)
940                                 | (1 << COMP_HTTP_REQUEST_METHOD)
941                                 | (1 << COMP_HTTP_URL)
942                                 | (1 << COMP_HTTP_QUERY_STRING)
943                                 | (1 << COMP_HTTP_REQUEST_HEADER);
944     }
945     else {
946         r->keep_alive = 0;
947         r->reqbody_length = 0;
948 
949         if (r->conf.log_request_header_on_error) {
950             /*(http_request_parse() modifies hdrs only to
951              * undo line-wrapping in-place using spaces)*/
952             log_error(r->conf.errh, __FILE__, __LINE__, "request-header:\n%.*s",
953                       (int)header_len, hdrs);
954         }
955     }
956 
957     r->rqst_header_len = header_len;
958     chunkqueue_mark_written(cq, header_len);
959     connection_set_state(r, CON_STATE_REQUEST_END);
960     return 1;
961 }
962 
963 static handler_t connection_handle_fdevent(void *context, int revents) {
964 	connection *con = context;
965 
966 	joblist_append(con);
967 
968 	if (con->is_ssl_sock) {
969 		/* ssl may read and write for both reads and writes */
970 		if (revents & (FDEVENT_IN | FDEVENT_OUT)) {
971 			con->is_readable = 1;
972 			con->is_writable = 1;
973 		}
974 	} else {
975 		if (revents & FDEVENT_IN) {
976 			con->is_readable = 1;
977 		}
978 		if (revents & FDEVENT_OUT) {
979 			con->is_writable = 1;
980 			/* we don't need the event twice */
981 		}
982 	}
983 
984 	request_st * const r = &con->request;
985 
986 	if (r->state == CON_STATE_READ) {
987 		connection_handle_read_state(con);
988 	}
989 
990 	if (r->state == CON_STATE_WRITE &&
991 	    !chunkqueue_is_empty(con->write_queue) &&
992 	    con->is_writable) {
993 		connection_handle_write(con);
994 	}
995 
996 	if (r->state == CON_STATE_CLOSE) {
997 		/* flush the read buffers */
998 		connection_read_for_eos(con);
999 	}
1000 
1001 
1002 	/* attempt (above) to read data in kernel socket buffers
1003 	 * prior to handling FDEVENT_HUP and FDEVENT_ERR */
1004 
1005 	if ((revents & ~(FDEVENT_IN | FDEVENT_OUT)) && r->state != CON_STATE_ERROR) {
1006 		if (r->state == CON_STATE_CLOSE) {
1007 			con->close_timeout_ts = log_epoch_secs - (HTTP_LINGER_TIMEOUT+1);
1008 		} else if (revents & FDEVENT_HUP) {
1009 			connection_set_state(r, CON_STATE_ERROR);
1010 		} else if (revents & FDEVENT_RDHUP) {
1011 			int events = fdevent_fdnode_interest(con->fdn);
1012 			events &= ~(FDEVENT_IN|FDEVENT_RDHUP);
1013 			r->conf.stream_request_body &= ~(FDEVENT_STREAM_REQUEST_BUFMIN|FDEVENT_STREAM_REQUEST_POLLIN);
1014 			r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLRDHUP;
1015 			con->is_readable = 1; /*(can read 0 for end-of-stream)*/
1016 			if (chunkqueue_is_empty(con->read_queue)) r->keep_alive = 0;
1017 			if (r->reqbody_length < -1) { /*(transparent proxy mode; no more data to read)*/
1018 				r->reqbody_length = r->reqbody_queue->bytes_in;
1019 			}
1020 			if (sock_addr_get_family(&con->dst_addr) == AF_UNIX) {
1021 				/* future: will getpeername() on AF_UNIX properly check if still connected? */
1022 				fdevent_fdnode_event_set(con->srv->ev, con->fdn, events);
1023 			} else if (fdevent_is_tcp_half_closed(con->fd)) {
1024 				/* Success of fdevent_is_tcp_half_closed() after FDEVENT_RDHUP indicates TCP FIN received,
1025 				 * but does not distinguish between client shutdown(fd, SHUT_WR) and client close(fd).
1026 				 * Remove FDEVENT_RDHUP so that we do not spin on the ready event.
1027 				 * However, a later TCP RST will not be detected until next write to socket.
1028 				 * future: might getpeername() to check for TCP RST on half-closed sockets
1029 				 * (without FDEVENT_RDHUP interest) when checking for write timeouts
1030 				 * once a second in server.c, though getpeername() on Windows might not indicate this */
1031 				r->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_TCP_FIN;
1032 				fdevent_fdnode_event_set(con->srv->ev, con->fdn, events);
1033 			} else {
1034 				/* Failure of fdevent_is_tcp_half_closed() indicates TCP RST
1035 				 * (or unable to tell (unsupported OS), though should not
1036 				 * be setting FDEVENT_RDHUP in that case) */
1037 				connection_set_state(r, CON_STATE_ERROR);
1038 			}
1039 		} else if (revents & FDEVENT_ERR) { /* error, connection reset */
1040 			connection_set_state(r, CON_STATE_ERROR);
1041 		} else {
1042 			log_error(r->conf.errh, __FILE__, __LINE__,
1043 			  "connection closed: poll() -> ??? %d", revents);
1044 		}
1045 	}
1046 
1047 	return HANDLER_FINISHED;
1048 }
1049 
1050 
1051 connection *connection_accept(server *srv, server_socket *srv_socket) {
1052 	int cnt;
1053 	sock_addr cnt_addr;
1054 	size_t cnt_len = sizeof(cnt_addr); /*(size_t intentional; not socklen_t)*/
1055 
1056 	/**
1057 	 * check if we can still open a new connections
1058 	 *
1059 	 * see #1216
1060 	 */
1061 
1062 	if (srv->conns.used >= srv->max_conns) {
1063 		return NULL;
1064 	}
1065 
1066 	cnt = fdevent_accept_listenfd(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len);
1067 	if (-1 == cnt) {
1068 		switch (errno) {
1069 		case EAGAIN:
1070 #if EWOULDBLOCK != EAGAIN
1071 		case EWOULDBLOCK:
1072 #endif
1073 		case EINTR:
1074 			/* we were stopped _before_ we had a connection */
1075 		case ECONNABORTED: /* this is a FreeBSD thingy */
1076 			/* we were stopped _after_ we had a connection */
1077 			break;
1078 		case EMFILE:
1079 			/* out of fds */
1080 			break;
1081 		default:
1082 			log_perror(srv->errh, __FILE__, __LINE__, "accept failed");
1083 		}
1084 		return NULL;
1085 	} else {
1086 		if (sock_addr_get_family(&cnt_addr) != AF_UNIX) {
1087 			network_accept_tcp_nagle_disable(cnt);
1088 		}
1089 		return connection_accepted(srv, srv_socket, &cnt_addr, cnt);
1090 	}
1091 }
1092 
1093 
1094 __attribute_cold__
1095 static int connection_read_cq_err(connection *con) {
1096     request_st * const r = &con->request;
1097   #if defined(__WIN32)
1098     int lastError = WSAGetLastError();
1099     switch (lastError) {
1100     case EAGAIN:
1101         return 0;
1102     case EINTR:
1103         /* we have been interrupted before we could read */
1104         con->is_readable = 1;
1105         return 0;
1106     case ECONNRESET:
1107         /* suppress logging for this error, expected for keep-alive */
1108         break;
1109     default:
1110         log_error(r->conf.errh, __FILE__, __LINE__,
1111           "connection closed - recv failed: %d", lastError);
1112         break;
1113     }
1114   #else /* __WIN32 */
1115     switch (errno) {
1116     case EAGAIN:
1117         return 0;
1118     case EINTR:
1119         /* we have been interrupted before we could read */
1120         con->is_readable = 1;
1121         return 0;
1122     case ECONNRESET:
1123         /* suppress logging for this error, expected for keep-alive */
1124         break;
1125     default:
1126         log_perror(r->conf.errh, __FILE__, __LINE__,
1127           "connection closed - read failed");
1128         break;
1129     }
1130   #endif /* __WIN32 */
1131 
1132     connection_set_state(r, CON_STATE_ERROR);
1133     return -1;
1134 }
1135 
1136 
1137 /* 0: everything ok, -1: error, -2: con closed */
1138 static int connection_read_cq(connection *con, chunkqueue *cq, off_t max_bytes) {
1139     ssize_t len;
1140     size_t mem_len = 0;
1141 
1142     do {
1143         /* obtain chunk memory into which to read
1144          * fill previous chunk if it has a reasonable amount of space available
1145          * (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz)
1146          */
1147         chunk *ckpt = cq->last;
1148         char * const mem = chunkqueue_get_memory(cq, &mem_len);
1149         if (mem_len > (size_t)max_bytes) mem_len = (size_t)max_bytes;
1150 
1151       #if defined(__WIN32)
1152         len = recv(con->fd, mem, mem_len, 0);
1153       #else
1154         len = read(con->fd, mem, mem_len);
1155       #endif
1156 
1157         chunkqueue_use_memory(cq, ckpt, len > 0 ? len : 0);
1158 
1159         if (len != (ssize_t)mem_len) {
1160             /* we got less then expected, wait for the next fd-event */
1161             con->is_readable = 0;
1162 
1163             if (len > 0) {
1164                 con->bytes_read += len;
1165                 return 0;
1166             }
1167             else if (0 == len) /* other end close connection -> KEEP-ALIVE */
1168                 return -2;     /* (pipelining) */
1169             else
1170                 return connection_read_cq_err(con);
1171         }
1172 
1173         con->bytes_read += len;
1174         max_bytes -= len;
1175 
1176         int frd;
1177         mem_len = (0 == fdevent_ioctl_fionread(con->fd, S_IFSOCK, &frd))
1178           ? (frd < max_bytes) ? (size_t)frd : (size_t)max_bytes
1179           : 0;
1180     } while (max_bytes);
1181     return 0;
1182 }
1183 
1184 
1185 static int connection_write_cq(connection *con, chunkqueue *cq, off_t max_bytes) {
1186     request_st * const r = &con->request;
1187     return con->srv->network_backend_write(con->fd,cq,max_bytes,r->conf.errh);
1188 }
1189 
1190 
1191 connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) {
1192 		connection *con;
1193 
1194 		srv->cur_fds++;
1195 
1196 		/* ok, we have the connection, register it */
1197 #if 0
1198 		log_error(srv->errh, __FILE__, __LINE__, "accepted() %d", cnt);
1199 #endif
1200 		srv->con_opened++;
1201 
1202 		con = connections_get_new_connection(srv);
1203 
1204 		con->fd = cnt;
1205 		con->fdn = fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
1206 		con->network_read = connection_read_cq;
1207 		con->network_write = connection_write_cq;
1208 
1209 		request_st * const r = &con->request;
1210 		connection_set_state(r, CON_STATE_REQUEST_START);
1211 
1212 		con->connection_start = log_epoch_secs;
1213 		con->dst_addr = *cnt_addr;
1214 		buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
1215 		con->srv_socket = srv_socket;
1216 		con->is_ssl_sock = srv_socket->is_ssl;
1217 		con->proto_default_port = 80; /* "http" */
1218 
1219 		config_cond_cache_reset(r);
1220 		r->conditional_is_valid = (1 << COMP_SERVER_SOCKET)
1221 		                        | (1 << COMP_HTTP_REMOTE_IP);
1222 
1223 		if (HANDLER_GO_ON != plugins_call_handle_connection_accept(con)) {
1224 			connection_reset(con);
1225 			connection_close(con);
1226 			return NULL;
1227 		}
1228 		if (r->http_status < 0) connection_set_state(r, CON_STATE_WRITE);
1229 		return con;
1230 }
1231 
1232 
1233 static int connection_handle_request(request_st * const r) {
1234 			const plugin *p = r->handler_module;
1235 			int rc;
1236 			if (NULL != p
1237 			    || ((rc = http_response_prepare(r)) == HANDLER_GO_ON
1238 			        && NULL != (p = r->handler_module)))
1239 				rc = p->handle_subrequest(r, p->data);
1240 			switch (rc) {
1241 			case HANDLER_WAIT_FOR_EVENT:
1242 				if (!r->resp_body_finished && (!r->resp_body_started || 0 == r->conf.stream_response_body)) {
1243 					break; /* come back here */
1244 				}
1245 				/* response headers received from backend; fall through to start response */
1246 				/* fall through */
1247 			case HANDLER_GO_ON: /*(HANDLER_FINISHED if request not handled)*/
1248 			case HANDLER_FINISHED:
1249 				if (r->http_status == 0) r->http_status = 200;
1250 				if (r->error_handler_saved_status > 0) {
1251 					r->http_method = r->error_handler_saved_method;
1252 				}
1253 				if (NULL == r->handler_module || r->conf.error_intercept) {
1254 					if (r->error_handler_saved_status) {
1255 						const int subreq_status = r->http_status;
1256 						if (r->error_handler_saved_status > 0) {
1257 							r->http_status = r->error_handler_saved_status;
1258 						} else if (r->http_status == 404 || r->http_status == 403) {
1259 							/* error-handler-404 is a 404 */
1260 							r->http_status = -r->error_handler_saved_status;
1261 						} else {
1262 							/* error-handler-404 is back and has generated content */
1263 							/* if Status: was set, take it otherwise use 200 */
1264 						}
1265 						if (200 <= subreq_status && subreq_status <= 299) {
1266 							/*(flag value to indicate that error handler succeeded)
1267 							 *(for (NULL == r->handler_module))*/
1268 							r->error_handler_saved_status = 65535; /* >= 1000 */
1269 						}
1270 					} else if (r->http_status >= 400) {
1271 						const buffer *error_handler = NULL;
1272 						if (!buffer_string_is_empty(r->conf.error_handler)) {
1273 							error_handler = r->conf.error_handler;
1274 						} else if ((r->http_status == 404 || r->http_status == 403)
1275 							   && !buffer_string_is_empty(r->conf.error_handler_404)) {
1276 							error_handler = r->conf.error_handler_404;
1277 						}
1278 
1279 						if (error_handler) {
1280 							/* call error-handler */
1281 
1282 							/* set REDIRECT_STATUS to save current HTTP status code
1283 							 * for access by dynamic handlers
1284 							 * https://redmine.lighttpd.net/issues/1828 */
1285 							buffer * const tb = r->tmp_buf;
1286 							buffer_clear(tb);
1287 							buffer_append_int(tb, r->http_status);
1288 							http_header_env_set(r, CONST_STR_LEN("REDIRECT_STATUS"), CONST_BUF_LEN(tb));
1289 
1290 							if (error_handler == r->conf.error_handler) {
1291 								plugins_call_handle_request_reset(r);
1292 
1293 								if (r->reqbody_length) {
1294 									if (r->reqbody_length != r->reqbody_queue->bytes_in) {
1295 										r->keep_alive = 0;
1296 									}
1297 									r->reqbody_length = 0;
1298 									chunkqueue_reset(r->reqbody_queue);
1299 								}
1300 
1301 								r->con->is_writable = 1;
1302 								r->resp_body_finished = 0;
1303 								r->resp_body_started = 0;
1304 
1305 								r->error_handler_saved_status = r->http_status;
1306 								r->error_handler_saved_method = r->http_method;
1307 
1308 								r->http_method = HTTP_METHOD_GET;
1309 							} else { /*(preserve behavior for server.error-handler-404)*/
1310 								r->error_handler_saved_status = -r->http_status; /*(negative to flag old behavior)*/
1311 							}
1312 
1313 							if (r->http_version == HTTP_VERSION_UNSET) r->http_version = HTTP_VERSION_1_0;
1314 
1315 							buffer_copy_buffer(&r->target, error_handler);
1316 							connection_handle_errdoc_init(r);
1317 							r->http_status = 0; /*(after connection_handle_errdoc_init())*/
1318 							http_response_comeback(r);
1319 							return 1;
1320 						}
1321 					}
1322 				}
1323 
1324 				/* we have something to send, go on */
1325 				connection_set_state(r, CON_STATE_RESPONSE_START);
1326 				break;
1327 			case HANDLER_WAIT_FOR_FD:
1328 				connection_fdwaitqueue_append(r->con);
1329 				break;
1330 			case HANDLER_COMEBACK:
1331 				http_response_comeback(r);
1332 				return 1;
1333 			/*case HANDLER_ERROR:*/
1334 			default:
1335 				/* something went wrong */
1336 				connection_set_state(r, CON_STATE_ERROR);
1337 				break;
1338 			}
1339 
1340 			return 0;
1341 }
1342 
1343 
1344 int connection_state_machine(connection *con) {
1345 	request_st * const r = &con->request;
1346 	request_state_t ostate;
1347 	int rc;
1348 	const int log_state_handling = r->conf.log_state_handling;
1349 
1350 	if (log_state_handling) {
1351 		log_error(r->conf.errh, __FILE__, __LINE__,
1352 		  "state at enter %d %s", con->fd, connection_get_state(r->state));
1353 	}
1354 
1355 	do {
1356 		if (log_state_handling) {
1357 			log_error(r->conf.errh, __FILE__, __LINE__,
1358 			  "state for fd %d %s", con->fd, connection_get_state(r->state));
1359 		}
1360 
1361 		switch ((ostate = r->state)) {
1362 		case CON_STATE_REQUEST_START: /* transient */
1363 			r->start_ts = con->read_idle_ts = log_epoch_secs;
1364 			if (r->conf.high_precision_timestamps)
1365 				log_clock_gettime_realtime(&r->start_hp);
1366 
1367 			con->request_count++;
1368 			r->loops_per_request = 0;
1369 
1370 			connection_set_state(r, CON_STATE_READ);
1371 			/* fall through */
1372 		case CON_STATE_READ:
1373 			if (!connection_handle_read_state(con)) break;
1374 			/*if (r->state != CON_STATE_REQUEST_END) break;*/
1375 			/* fall through */
1376 		case CON_STATE_REQUEST_END: /* transient */
1377 			ostate = (0 == r->reqbody_length)
1378 			  ? CON_STATE_HANDLE_REQUEST
1379 			  : CON_STATE_READ_POST;
1380 			connection_set_state(r, ostate);
1381 			/* fall through */
1382 		case CON_STATE_READ_POST:
1383 		case CON_STATE_HANDLE_REQUEST:
1384 			if (connection_handle_request(r)) {
1385 				/* redo loop; will not match r->state */
1386 				ostate = CON_STATE_CONNECT;
1387 				break;
1388 			}
1389 
1390 			if (r->state == CON_STATE_HANDLE_REQUEST
1391 			    && ostate == CON_STATE_READ_POST) {
1392 				ostate = CON_STATE_HANDLE_REQUEST;
1393 			}
1394 
1395 			if (r->state != CON_STATE_RESPONSE_START) break;
1396 			/* fall through */
1397 		case CON_STATE_RESPONSE_START: /* transient */
1398 			if (-1 == connection_handle_write_prepare(r)) {
1399 				connection_set_state(r, CON_STATE_ERROR);
1400 				break;
1401 			}
1402 			connection_set_state(r, CON_STATE_WRITE);
1403 			/* fall through */
1404 		case CON_STATE_WRITE:
1405 			connection_handle_write_state(r, con);
1406 			if (r->state != CON_STATE_RESPONSE_END) break;
1407 			/* fall through */
1408 		case CON_STATE_RESPONSE_END: /* transient */
1409 		case CON_STATE_ERROR:        /* transient */
1410 			connection_handle_response_end_state(r, con);
1411 			break;
1412 		case CON_STATE_CLOSE:
1413 			connection_handle_close_state(con);
1414 			break;
1415 		case CON_STATE_CONNECT:
1416 			break;
1417 		default:
1418 			log_error(r->conf.errh, __FILE__, __LINE__,
1419 			  "unknown state: %d %d", con->fd, r->state);
1420 			break;
1421 		}
1422 	} while (ostate != (request_state_t)r->state);
1423 
1424 	if (log_state_handling) {
1425 		log_error(r->conf.errh, __FILE__, __LINE__,
1426 		  "state at exit: %d %s", con->fd, connection_get_state(r->state));
1427 	}
1428 
1429 	rc = 0;
1430 	switch(r->state) {
1431 	case CON_STATE_READ:
1432 		rc = FDEVENT_IN | FDEVENT_RDHUP;
1433 		break;
1434 	case CON_STATE_WRITE:
1435 		/* request write-fdevent only if we really need it
1436 		 * - if we have data to write
1437 		 * - if the socket is not writable yet
1438 		 */
1439 		if (!chunkqueue_is_empty(con->write_queue) &&
1440 		    (con->is_writable == 0) &&
1441 		    (con->traffic_limit_reached == 0)) {
1442 			rc |= FDEVENT_OUT;
1443 		}
1444 		/* fall through */
1445 	case CON_STATE_READ_POST:
1446 		if (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLIN) {
1447 			rc |= FDEVENT_IN | FDEVENT_RDHUP;
1448 		}
1449 		break;
1450 	case CON_STATE_CLOSE:
1451 		rc = FDEVENT_IN;
1452 		break;
1453 	default:
1454 		break;
1455 	}
1456 	if (con->fd >= 0) {
1457 		const int events = fdevent_fdnode_interest(con->fdn);
1458 		if (con->is_readable < 0) {
1459 			con->is_readable = 0;
1460 			rc |= FDEVENT_IN;
1461 		}
1462 		if (con->is_writable < 0) {
1463 			con->is_writable = 0;
1464 			rc |= FDEVENT_OUT;
1465 		}
1466 		if (events & FDEVENT_RDHUP) {
1467 			rc |= FDEVENT_RDHUP;
1468 		}
1469 		if (rc != events) {
1470 			/* update timestamps when enabling interest in events */
1471 			if ((rc & FDEVENT_IN) && !(events & FDEVENT_IN)) {
1472 				con->read_idle_ts = log_epoch_secs;
1473 			}
1474 			if ((rc & FDEVENT_OUT) && !(events & FDEVENT_OUT)) {
1475 				con->write_request_ts = log_epoch_secs;
1476 			}
1477 			fdevent_fdnode_event_set(con->srv->ev, con->fdn, rc);
1478 		}
1479 	}
1480 
1481 	return 0;
1482 }
1483 
1484 static void connection_check_timeout (connection * const con, const time_t cur_ts) {
1485     const int waitevents = fdevent_fdnode_interest(con->fdn);
1486     int changed = 0;
1487     int t_diff;
1488 
1489     request_st * const r = &con->request;
1490     if (r->state == CON_STATE_CLOSE) {
1491         if (cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
1492             changed = 1;
1493         }
1494     } else if (waitevents & FDEVENT_IN) {
1495         if (con->request_count == 1 || r->state != CON_STATE_READ) {
1496             /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */
1497             if (cur_ts - con->read_idle_ts > r->conf.max_read_idle) {
1498                 /* time - out */
1499                 if (r->conf.log_request_handling) {
1500                     log_error(r->conf.errh, __FILE__, __LINE__,
1501                               "connection closed - read timeout: %d", con->fd);
1502                 }
1503 
1504                 connection_set_state(r, CON_STATE_ERROR);
1505                 changed = 1;
1506             }
1507         } else {
1508             if (cur_ts - con->read_idle_ts > con->keep_alive_idle) {
1509                 /* time - out */
1510                 if (r->conf.log_request_handling) {
1511                     log_error(r->conf.errh, __FILE__, __LINE__,
1512                               "connection closed - keep-alive timeout: %d",
1513                               con->fd);
1514                 }
1515 
1516                 connection_set_state(r, CON_STATE_ERROR);
1517                 changed = 1;
1518             }
1519         }
1520     }
1521 
1522     /* max_write_idle timeout currently functions as backend timeout,
1523      * too, after response has been started.
1524      * future: have separate backend timeout, and then change this
1525      * to check for write interest before checking for timeout */
1526     /*if (waitevents & FDEVENT_OUT)*/
1527     if ((r->state == CON_STATE_WRITE) &&
1528         (con->write_request_ts != 0)) {
1529       #if 0
1530         if (cur_ts - con->write_request_ts > 60) {
1531             log_error(r->conf.errh, __FILE__, __LINE__,
1532                       "connection closed - pre-write-request-timeout: %d %d",
1533                       con->fd, cur_ts - con->write_request_ts);
1534         }
1535       #endif
1536 
1537         if (cur_ts - con->write_request_ts > r->conf.max_write_idle) {
1538             /* time - out */
1539             if (r->conf.log_timeouts) {
1540                 log_error(r->conf.errh, __FILE__, __LINE__,
1541                   "NOTE: a request from %.*s for %.*s timed out after writing "
1542                   "%lld bytes. We waited %d seconds.  If this is a problem, "
1543                   "increase server.max-write-idle",
1544                   BUFFER_INTLEN_PTR(con->dst_addr_buf),
1545                   BUFFER_INTLEN_PTR(&r->target),
1546                   (long long)con->bytes_written, (int)r->conf.max_write_idle);
1547             }
1548             connection_set_state(r, CON_STATE_ERROR);
1549             changed = 1;
1550         }
1551     }
1552 
1553     if (0 == (t_diff = cur_ts - con->connection_start)) t_diff = 1;
1554 
1555     if (con->traffic_limit_reached &&
1556         (r->conf.bytes_per_second == 0 ||
1557          con->bytes_written < (off_t)r->conf.bytes_per_second * t_diff)) {
1558         /* enable connection again */
1559         con->traffic_limit_reached = 0;
1560 
1561         changed = 1;
1562     }
1563 
1564     con->bytes_written_cur_second = 0;
1565 
1566     if (changed) {
1567         connection_state_machine(con);
1568     }
1569 }
1570 
1571 void connection_periodic_maint (server * const srv, const time_t cur_ts) {
1572     /* check all connections for timeouts */
1573     connections * const conns = &srv->conns;
1574     for (size_t ndx = 0; ndx < conns->used; ++ndx) {
1575         connection_check_timeout(conns->ptr[ndx], cur_ts);
1576     }
1577 }
1578 
1579 void connection_graceful_shutdown_maint (server *srv) {
1580     connections * const conns = &srv->conns;
1581     for (size_t ndx = 0; ndx < conns->used; ++ndx) {
1582         connection * const con = conns->ptr[ndx];
1583         int changed = 0;
1584 
1585         request_st * const r = &con->request;
1586         if (r->state == CON_STATE_CLOSE) {
1587             /* reduce remaining linger timeout to be
1588              * (from zero) *up to* one more second, but no more */
1589             if (HTTP_LINGER_TIMEOUT > 1)
1590                 con->close_timeout_ts -= (HTTP_LINGER_TIMEOUT - 1);
1591             if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)
1592                 changed = 1;
1593         }
1594         else if (r->state == CON_STATE_READ && con->request_count > 1
1595                  && chunkqueue_is_empty(con->read_queue)) {
1596             /* close connections in keep-alive waiting for next request */
1597             connection_set_state(r, CON_STATE_ERROR);
1598             changed = 1;
1599         }
1600 
1601         r->keep_alive = 0;            /* disable keep-alive */
1602 
1603         r->conf.bytes_per_second = 0;         /* disable rate limit */
1604         r->conf.global_bytes_per_second = 0;  /* disable rate limit */
1605         if (con->traffic_limit_reached) {
1606             con->traffic_limit_reached = 0;
1607             changed = 1;
1608         }
1609 
1610         if (changed) {
1611             connection_state_machine(con);
1612         }
1613     }
1614 }
1615