5 #include "burl.h" /* HTTP_PARSEOPT_HEADER_STRICT */
7 #include "connections.h"
9 #include "http_header.h"
11 #include "configfile.h"
15 #include "http_chunk.h"
16 #include "stat_cache.h"
21 #include "inet_ntop_cache.h"
30 #ifdef HAVE_SYS_FILIO_H
31 # include <sys/filio.h>
34 #include "sys-socket.h"
36 #define HTTP_LINGER_TIMEOUT 5
43 static connection
*connection_init(server
*srv
);
45 static int connection_reset(server
*srv
, connection
*con
);
48 static connection
*connections_get_new_connection(server
*srv
) {
49 connections
*conns
= srv
->conns
;
52 if (conns
->size
== conns
->used
) {
53 conns
->size
+= srv
->max_conns
>= 128 ? 128 : srv
->max_conns
> 16 ? 16 : srv
->max_conns
;
54 conns
->ptr
= realloc(conns
->ptr
, sizeof(*conns
->ptr
) * conns
->size
);
55 force_assert(NULL
!= conns
->ptr
);
57 for (i
= conns
->used
; i
< conns
->size
; i
++) {
58 conns
->ptr
[i
] = connection_init(srv
);
59 connection_reset(srv
, conns
->ptr
[i
]);
63 conns
->ptr
[conns
->used
]->ndx
= conns
->used
;
64 return conns
->ptr
[conns
->used
++];
67 static int connection_del(server
*srv
, connection
*con
) {
69 connections
*conns
= srv
->conns
;
72 if (con
== NULL
) return -1;
74 if (-1 == con
->ndx
) return -1;
76 buffer_clear(con
->uri
.authority
);
77 buffer_reset(con
->uri
.path
);
78 buffer_reset(con
->uri
.query
);
79 buffer_reset(con
->request
.orig_uri
);
83 /* not last element */
85 if (i
!= conns
->used
- 1) {
87 conns
->ptr
[i
] = conns
->ptr
[conns
->used
- 1];
88 conns
->ptr
[conns
->used
- 1] = temp
;
90 conns
->ptr
[i
]->ndx
= i
;
91 conns
->ptr
[conns
->used
- 1]->ndx
= -1;
98 fprintf(stderr
, "%s.%d: del: (%d)", __FILE__
, __LINE__
, conns
->used
);
99 for (i
= 0; i
< conns
->used
; i
++) {
100 fprintf(stderr
, "%d ", conns
->ptr
[i
]->fd
);
102 fprintf(stderr
, "\n");
107 static int connection_close(server
*srv
, connection
*con
) {
108 if (con
->fd
< 0) con
->fd
= -con
->fd
;
110 plugins_call_handle_connection_close(srv
, con
);
112 con
->request_count
= 0;
113 chunkqueue_reset(con
->read_queue
);
115 fdevent_fdnode_event_del(srv
->ev
, con
->fdn
);
116 fdevent_unregister(srv
->ev
, con
->fd
);
119 if (closesocket(con
->fd
)) {
120 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
121 "(warning) close:", con
->fd
, strerror(errno
));
124 if (close(con
->fd
)) {
125 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
126 "(warning) close:", con
->fd
, strerror(errno
));
133 if (srv
->srvconf
.log_state_handling
) {
134 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
135 "connection closed for fd", con
->fd
);
138 con
->is_ssl_sock
= 0;
140 /* plugins should have cleaned themselves up */
141 for (size_t i
= 0; i
< srv
->plugins
.used
; ++i
) {
142 plugin
*p
= ((plugin
**)(srv
->plugins
.ptr
))[i
];
143 plugin_data
*pd
= p
->data
;
144 if (!pd
|| NULL
== con
->plugin_ctx
[pd
->id
]) continue;
145 log_error_write(srv
, __FILE__
, __LINE__
, "sb",
146 "missing cleanup in", p
->name
);
147 con
->plugin_ctx
[pd
->id
] = NULL
;
150 connection_del(srv
, con
);
151 connection_set_state(srv
, con
, CON_STATE_CONNECT
);
156 static void connection_read_for_eos_plain(server
*srv
, connection
*con
) {
157 /* we have to do the linger_on_close stuff regardless
158 * of con->keep_alive; even non-keepalive sockets may
159 * still have unread data, and closing before reading
160 * it will make the client not see all our output.
163 const int type
= con
->dst_addr
.plain
.sa_family
;
166 len
= fdevent_socket_read_discard(con
->fd
, buf
, sizeof(buf
),
168 } while (len
> 0 || (len
< 0 && errno
== EINTR
));
170 if (len
< 0 && errno
== EAGAIN
) return;
171 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
172 if (len
< 0 && errno
== EWOULDBLOCK
) return;
175 /* 0 == len || (len < 0 && (errno is a non-recoverable error)) */
176 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
179 static void connection_read_for_eos_ssl(server
*srv
, connection
*con
) {
180 if (con
->network_read(srv
, con
, con
->read_queue
, MAX_READ_LIMIT
) < 0)
181 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
182 chunkqueue_reset(con
->read_queue
);
185 static void connection_read_for_eos(server
*srv
, connection
*con
) {
187 ? connection_read_for_eos_plain(srv
, con
)
188 : connection_read_for_eos_ssl(srv
, con
);
191 static void connection_handle_close_state(server
*srv
, connection
*con
) {
192 connection_read_for_eos(srv
, con
);
194 if (srv
->cur_ts
- con
->close_timeout_ts
> HTTP_LINGER_TIMEOUT
) {
195 connection_close(srv
, con
);
199 static void connection_handle_shutdown(server
*srv
, connection
*con
) {
200 plugins_call_handle_connection_shut_wr(srv
, con
);
203 connection_reset(srv
, con
);
205 /* close the connection */
207 && (con
->is_ssl_sock
|| 0 == shutdown(con
->fd
, SHUT_WR
))) {
208 con
->close_timeout_ts
= srv
->cur_ts
;
209 connection_set_state(srv
, con
, CON_STATE_CLOSE
);
211 if (srv
->srvconf
.log_state_handling
) {
212 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
213 "shutdown for fd", con
->fd
);
216 connection_close(srv
, con
);
220 static void connection_handle_response_end_state(server
*srv
, connection
*con
) {
221 /* log the request */
222 /* (even if error, connection dropped, still write to access log if http_status) */
223 if (con
->http_status
) {
224 plugins_call_handle_request_done(srv
, con
);
227 if (con
->state
!= CON_STATE_ERROR
) srv
->con_written
++;
229 if (con
->request
.content_length
!= con
->request_content_queue
->bytes_in
230 || con
->state
== CON_STATE_ERROR
) {
231 /* request body is present and has not been read completely */
235 if (con
->keep_alive
) {
236 connection_reset(srv
, con
);
238 con
->request_start
= srv
->cur_ts
;
239 con
->read_idle_ts
= srv
->cur_ts
;
241 connection_set_state(srv
, con
, CON_STATE_REQUEST_START
);
243 connection_handle_shutdown(srv
, con
);
247 static void connection_handle_errdoc_init(connection
*con
) {
248 /* modules that produce headers required with error response should
249 * typically also produce an error document. Make an exception for
250 * mod_auth WWW-Authenticate response header. */
251 buffer
*www_auth
= NULL
;
252 if (401 == con
->http_status
) {
253 buffer
*vb
= http_header_response_get(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("WWW-Authenticate"));
254 if (NULL
!= vb
) www_auth
= buffer_init_buffer(vb
);
257 buffer_reset(con
->physical
.path
);
258 con
->response
.htags
= 0;
259 array_reset_data_strings(con
->response
.headers
);
260 http_response_body_clear(con
, 0);
262 if (NULL
!= www_auth
) {
263 http_header_response_set(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(www_auth
));
264 buffer_free(www_auth
);
268 static int connection_handle_write_prepare(server
*srv
, connection
*con
) {
269 if (con
->mode
== DIRECT
) {
271 switch(con
->request
.http_method
) {
272 case HTTP_METHOD_GET
:
273 case HTTP_METHOD_POST
:
274 case HTTP_METHOD_HEAD
:
276 case HTTP_METHOD_OPTIONS
:
278 * 400 is coming from the request-parser BEFORE uri.path is set
279 * 403 is from the response handler when noone else catched it
282 if ((!con
->http_status
|| con
->http_status
== 200) && !buffer_string_is_empty(con
->uri
.path
) &&
283 con
->uri
.path
->ptr
[0] != '*') {
284 http_response_body_clear(con
, 0);
285 http_header_response_append(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
286 con
->http_status
= 200;
287 con
->file_finished
= 1;
292 if (0 == con
->http_status
) {
293 con
->http_status
= 501;
299 if (con
->http_status
== 0) {
300 con
->http_status
= 403;
303 switch(con
->http_status
) {
304 case 204: /* class: header only */
307 /* disable chunked encoding again as we have no body */
308 http_response_body_clear(con
, 1);
309 con
->file_finished
= 1;
311 default: /* class: header + body */
312 /* only custom body for 4xx and 5xx */
313 if (con
->http_status
< 400 || con
->http_status
>= 600) break;
315 if (con
->mode
!= DIRECT
&& (!con
->conf
.error_intercept
|| con
->error_handler_saved_status
)) break;
316 if (con
->mode
== DIRECT
&& con
->error_handler_saved_status
>= 65535) break;
318 con
->file_finished
= 0;
320 connection_handle_errdoc_init(con
);
322 /* try to send static errorfile */
323 if (!buffer_string_is_empty(con
->conf
.errorfile_prefix
)) {
324 stat_cache_entry
*sce
= NULL
;
326 buffer_copy_buffer(con
->physical
.path
, con
->conf
.errorfile_prefix
);
327 buffer_append_int(con
->physical
.path
, con
->http_status
);
328 buffer_append_string_len(con
->physical
.path
, CONST_STR_LEN(".html"));
330 if (0 == http_chunk_append_file(srv
, con
, con
->physical
.path
)) {
331 con
->file_finished
= 1;
332 if (HANDLER_ERROR
!= stat_cache_get_entry(srv
, con
, con
->physical
.path
, &sce
)) {
333 stat_cache_content_type_get(srv
, con
, con
->physical
.path
, sce
);
334 http_header_response_set(con
, HTTP_HEADER_CONTENT_TYPE
, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce
->content_type
));
339 if (!con
->file_finished
) {
340 buffer
*b
= srv
->tmp_buf
;
342 buffer_reset(con
->physical
.path
);
344 con
->file_finished
= 1;
346 /* build default error-page */
347 buffer_copy_string_len(b
, CONST_STR_LEN(
348 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
349 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
350 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
351 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
354 http_status_append(b
, con
->http_status
);
356 buffer_append_string_len(b
, CONST_STR_LEN(
361 http_status_append(b
, con
->http_status
);
363 buffer_append_string_len(b
, CONST_STR_LEN("</h1>\n"
368 (void)http_chunk_append_mem(srv
, con
, CONST_BUF_LEN(b
));
370 http_header_response_set(con
, HTTP_HEADER_CONTENT_TYPE
, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
375 /* Allow filter plugins to change response headers before they are written. */
376 switch(plugins_call_handle_response_start(srv
, con
)) {
378 case HANDLER_FINISHED
:
381 log_error_write(srv
, __FILE__
, __LINE__
, "s", "response_start plugin failed");
385 if (con
->file_finished
) {
386 /* we have all the content and chunked encoding is not used, set a content-length */
388 if (!(con
->response
.htags
& (HTTP_HEADER_CONTENT_LENGTH
|HTTP_HEADER_TRANSFER_ENCODING
))) {
389 off_t qlen
= chunkqueue_length(con
->write_queue
);
392 * The Content-Length header only can be sent if we have content:
393 * - HEAD doesn't have a content-body (but have a content-length)
394 * - 1xx, 204 and 304 don't have a content-body (RFC 2616 Section 4.3)
396 * Otherwise generate a Content-Length header as chunked encoding is not
399 if ((con
->http_status
>= 100 && con
->http_status
< 200) ||
400 con
->http_status
== 204 ||
401 con
->http_status
== 304) {
402 /* no Content-Body, no Content-Length */
403 http_header_response_unset(con
, HTTP_HEADER_CONTENT_LENGTH
, CONST_STR_LEN("Content-Length"));
404 } else if (qlen
> 0 || con
->request
.http_method
!= HTTP_METHOD_HEAD
) {
405 /* qlen = 0 is important for Redirects (301, ...) as they MAY have
406 * a content. Browsers are waiting for a Content otherwise
408 buffer_copy_int(srv
->tmp_buf
, qlen
);
409 http_header_response_set(con
, HTTP_HEADER_CONTENT_LENGTH
, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv
->tmp_buf
));
414 * the file isn't finished yet, but we have all headers
416 * to get keep-alive we either need:
417 * - Content-Length: ... (HTTP/1.0 and HTTP/1.0) or
418 * - Transfer-Encoding: chunked (HTTP/1.1)
419 * - Upgrade: ... (lighttpd then acts as transparent proxy)
422 if (!(con
->response
.htags
& (HTTP_HEADER_CONTENT_LENGTH
|HTTP_HEADER_TRANSFER_ENCODING
|HTTP_HEADER_UPGRADE
))) {
423 if (con
->request
.http_method
== HTTP_METHOD_CONNECT
424 && con
->http_status
== 200) {
425 /*(no transfer-encoding if successful CONNECT)*/
426 } else if (con
->request
.http_version
== HTTP_VERSION_1_1
) {
427 off_t qlen
= chunkqueue_length(con
->write_queue
);
428 con
->response
.send_chunked
= 1;
430 /* create initial Transfer-Encoding: chunked segment */
431 buffer
* const b
= chunkqueue_prepend_buffer_open(con
->write_queue
);
432 buffer_append_uint_hex(b
, (uintmax_t)qlen
);
433 buffer_append_string_len(b
, CONST_STR_LEN("\r\n"));
434 chunkqueue_prepend_buffer_commit(con
->write_queue
);
435 chunkqueue_append_mem(con
->write_queue
, CONST_STR_LEN("\r\n"));
437 http_header_response_append(con
, HTTP_HEADER_TRANSFER_ENCODING
, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN("chunked"));
444 if (con
->request
.http_method
== HTTP_METHOD_HEAD
) {
446 * a HEAD request has the same as a GET
447 * without the content
449 http_response_body_clear(con
, 1);
450 con
->file_finished
= 1;
453 http_response_write_header(srv
, con
);
458 static void connection_handle_write(server
*srv
, connection
*con
) {
459 switch(connection_write_chunkqueue(srv
, con
, con
->write_queue
, MAX_WRITE_LIMIT
)) {
461 con
->write_request_ts
= srv
->cur_ts
;
462 if (con
->file_finished
) {
463 connection_set_state(srv
, con
, CON_STATE_RESPONSE_END
);
466 case -1: /* error on our side */
467 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
468 "connection closed: write failed on fd", con
->fd
);
469 connection_set_state(srv
, con
, CON_STATE_ERROR
);
471 case -2: /* remote close */
472 connection_set_state(srv
, con
, CON_STATE_ERROR
);
475 con
->write_request_ts
= srv
->cur_ts
;
476 con
->is_writable
= 0;
478 /* not finished yet -> WRITE */
483 static void connection_handle_write_state(server
*srv
, connection
*con
) {
485 /* only try to write if we have something in the queue */
486 if (!chunkqueue_is_empty(con
->write_queue
)) {
487 if (con
->is_writable
) {
488 connection_handle_write(srv
, con
);
489 if (con
->state
!= CON_STATE_WRITE
) break;
491 } else if (con
->file_finished
) {
492 connection_set_state(srv
, con
, CON_STATE_RESPONSE_END
);
496 if (con
->mode
!= DIRECT
&& !con
->file_finished
) {
497 int r
= plugins_call_handle_subrequest(srv
, con
);
499 case HANDLER_WAIT_FOR_EVENT
:
500 case HANDLER_FINISHED
:
503 case HANDLER_WAIT_FOR_FD
:
505 fdwaitqueue_append(srv
, con
);
507 case HANDLER_COMEBACK
:
509 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
510 "unexpected subrequest handler ret-value:",
514 connection_set_state(srv
, con
, CON_STATE_ERROR
);
518 } while (con
->state
== CON_STATE_WRITE
519 && (!chunkqueue_is_empty(con
->write_queue
)
521 : con
->file_finished
));
527 static connection
*connection_init(server
*srv
) {
532 con
= calloc(1, sizeof(*con
));
533 force_assert(NULL
!= con
);
537 con
->bytes_written
= 0;
539 con
->bytes_header
= 0;
540 con
->loops_per_request
= 0;
543 con->x = buffer_init();
546 CLEAN(request
.request
);
547 CLEAN(request
.pathinfo
);
549 CLEAN(request
.orig_uri
);
552 CLEAN(uri
.authority
);
557 CLEAN(physical
.doc_root
);
558 CLEAN(physical
.path
);
559 CLEAN(physical
.basedir
);
560 CLEAN(physical
.rel_path
);
561 CLEAN(physical
.etag
);
568 con
->write_queue
= chunkqueue_init();
569 con
->read_queue
= chunkqueue_init();
570 con
->request_content_queue
= chunkqueue_init();
572 con
->request
.headers
= array_init();
573 con
->response
.headers
= array_init();
574 con
->environment
= array_init();
576 /* init plugin specific connection structures */
578 con
->plugin_ctx
= calloc(1, (srv
->plugins
.used
+ 1) * sizeof(void *));
579 force_assert(NULL
!= con
->plugin_ctx
);
581 con
->cond_cache
= calloc(srv
->config_context
->used
, sizeof(cond_cache_t
));
582 force_assert(NULL
!= con
->cond_cache
);
583 config_setup_connection(srv
, con
);
588 void connections_free(server
*srv
) {
589 connections
*conns
= srv
->conns
;
592 if (NULL
== conns
) return;
594 for (i
= 0; i
< conns
->size
; i
++) {
595 connection
*con
= conns
->ptr
[i
];
597 connection_reset(srv
, con
);
599 chunkqueue_free(con
->write_queue
);
600 chunkqueue_free(con
->read_queue
);
601 chunkqueue_free(con
->request_content_queue
);
602 array_free(con
->request
.headers
);
603 array_free(con
->response
.headers
);
604 array_free(con
->environment
);
610 CLEAN(request
.request
);
611 CLEAN(request
.pathinfo
);
613 CLEAN(request
.orig_uri
);
616 CLEAN(uri
.authority
);
621 CLEAN(physical
.doc_root
);
622 CLEAN(physical
.path
);
623 CLEAN(physical
.basedir
);
624 CLEAN(physical
.etag
);
625 CLEAN(physical
.rel_path
);
631 free(con
->plugin_ctx
);
632 free(con
->cond_cache
);
643 static int connection_reset(server
*srv
, connection
*con
) {
644 plugins_call_connection_reset(srv
, con
);
646 connection_response_reset(srv
, con
);
647 con
->is_readable
= 1;
649 con
->bytes_written
= 0;
650 con
->bytes_written_cur_second
= 0;
652 con
->bytes_header
= 0;
653 con
->loops_per_request
= 0;
655 con
->request
.http_method
= HTTP_METHOD_UNSET
;
656 con
->request
.http_version
= HTTP_VERSION_UNSET
;
659 buffer_reset(con->x);
662 CLEAN(request
.pathinfo
);
664 /* CLEAN(request.orig_uri); */
666 /* CLEAN(uri.path); */
668 /* CLEAN(uri.query); */
671 buffer_clear(con
->uri
.scheme
);
672 /*buffer_clear(con->proto);*//* set to default in connection_accepted() */
673 /*buffer_clear(con->uri.authority);*/
674 buffer_clear(con
->server_name
);
676 con
->request
.http_host
= NULL
;
677 con
->request
.content_length
= 0;
678 con
->request
.te_chunked
= 0;
679 con
->request
.htags
= 0;
681 array_reset_data_strings(con
->request
.headers
);
682 array_reset_data_strings(con
->environment
);
684 chunkqueue_reset(con
->request_content_queue
);
686 /* The cond_cache gets reset in response.c */
687 /* config_cond_cache_reset(srv, con); */
690 con
->async_callback
= 0;
691 con
->error_handler_saved_status
= 0;
692 /*con->error_handler_saved_method = HTTP_METHOD_UNSET;*/
693 /*(error_handler_saved_method value is not valid unless error_handler_saved_status is set)*/
695 config_setup_connection(srv
, con
);
700 static void connection_read_header(server
*srv
, connection
*con
) {
701 chunkqueue
* const cq
= con
->read_queue
;
707 for (c
= cq
->first
; c
; c
= c
->next
) {
708 size_t clen
= buffer_string_length(c
->mem
) - c
->offset
;
709 const char * const b
= c
->mem
->ptr
+ c
->offset
;
711 if (0 == clen
) continue;
712 if (le
) { /*(line end sequence cross chunk boundary)*/
713 if (n
[0] == '\r') ++n
;
714 if (n
[0] == '\n') { ++n
; hlen
+= n
- b
; break; }
715 if (n
[0] == '\0') { hlen
+= n
- b
; continue; }
718 for (const char * const end
= b
+clen
; (n
= memchr(n
,'\n',end
-n
)); ++n
) {
719 if (n
[1] == '\r') ++n
;
720 if (n
[1] == '\n') { hlen
+= n
- b
+ 2; break; }
721 if (n
[1] == '\0') { n
= NULL
; le
= 1; break; }
727 if (hlen
> srv
->srvconf
.max_request_field_size
) {
728 log_error_write(srv
, __FILE__
, __LINE__
, "s",
729 "oversized request-header -> sending Status 431");
730 con
->http_status
= 431; /* Request Header Fields Too Large */
732 connection_set_state(srv
, con
, CON_STATE_HANDLE_REQUEST
);
735 if (NULL
== c
) return; /* incomplete request headers */
737 con
->header_len
= hlen
;
739 buffer_clear(con
->request
.request
);
741 for (c
= cq
->first
; c
; c
= c
->next
) {
742 size_t len
= buffer_string_length(c
->mem
) - c
->offset
;
743 if (len
> hlen
) len
= hlen
;
744 buffer_append_string_len(con
->request
.request
,
745 c
->mem
->ptr
+ c
->offset
, len
);
746 if (0 == (hlen
-= len
)) break;
749 chunkqueue_mark_written(cq
, con
->header_len
);
751 /* skip past \r\n or \n after previous POST request when keep-alive */
752 if (con
->request_count
> 1) {
753 char * const s
= con
->request
.request
->ptr
;
755 if (buffer_string_length(con
->request
.request
) < 2) {
759 if (s
[0] == '\r' && s
[1] == '\n') {
760 size_t len
= buffer_string_length(con
->request
.request
);
761 memmove(s
, s
+2, len
-2);
762 buffer_string_set_length(con
->request
.request
, len
-2);
764 else if (s
[0] == '\n') {
765 if (!(con
->conf
.http_parseopts
& HTTP_PARSEOPT_HEADER_STRICT
)) {
766 size_t len
= buffer_string_length(con
->request
.request
);
767 memmove(s
, s
+1, len
-1);
768 buffer_string_set_length(con
->request
.request
, len
-1);
773 if (con
->conf
.log_request_header
) {
774 log_error_write(srv
, __FILE__
, __LINE__
, "sdsdSb",
776 "request-len:", buffer_string_length(con
->request
.request
),
777 "\n", con
->request
.request
);
780 buffer_clear(con
->uri
.authority
);
781 buffer_reset(con
->uri
.path
);
782 buffer_reset(con
->uri
.query
);
783 buffer_reset(con
->request
.orig_uri
);
785 if (srv
->srvconf
.log_request_header_on_error
) {
786 /* copy request only if we may need to log it upon error */
787 save
= buffer_init_buffer(con
->request
.request
);
790 con
->http_status
= http_request_parse(srv
, con
, con
->request
.request
);
791 if (0 != con
->http_status
) {
793 con
->request
.content_length
= 0;
795 if (srv
->srvconf
.log_request_header_on_error
) {
796 log_error_write(srv
, __FILE__
, __LINE__
, "Sb",
797 "request-header:\n", save
);
801 if (NULL
!= save
) buffer_free(save
);
802 buffer_reset(con
->request
.request
);
804 connection_set_state(srv
, con
, CON_STATE_REQUEST_END
);
808 * handle request header read
810 * we get called by the state-engine and by the fdevent-handler
812 static int connection_handle_read_state(server
*srv
, connection
*con
) {
813 int is_closed
= 0; /* the connection got closed, if we don't have a complete header, -> error */
815 if (con
->request_count
> 1 && 0 == con
->bytes_read
) {
817 /* update request_start timestamp when first byte of
818 * next request is received on a keep-alive connection */
819 con
->request_start
= srv
->cur_ts
;
820 if (con
->conf
.high_precision_timestamps
)
821 log_clock_gettime_realtime(&con
->request_start_hp
);
823 if (!chunkqueue_is_empty(con
->read_queue
)) {
824 /*(if partially read next request and unable to read() any bytes below,
825 * then will unnecessarily scan again here before subsequent read())*/
826 connection_read_header(srv
, con
);
827 if (con
->state
!= CON_STATE_READ
) {
828 con
->read_idle_ts
= srv
->cur_ts
;
834 if (con
->is_readable
) {
835 con
->read_idle_ts
= srv
->cur_ts
;
837 switch (con
->network_read(srv
, con
, con
->read_queue
, MAX_READ_LIMIT
)) {
839 connection_set_state(srv
, con
, CON_STATE_ERROR
);
849 connection_read_header(srv
, con
);
851 if (con
->state
== CON_STATE_READ
&& is_closed
) {
852 /* the connection got closed and we didn't got enough data to leave CON_STATE_READ;
853 * the only way is to leave here */
854 connection_set_state(srv
, con
, CON_STATE_ERROR
);
860 static handler_t
connection_handle_fdevent(server
*srv
, void *context
, int revents
) {
861 connection
*con
= context
;
863 joblist_append(srv
, con
);
865 if (con
->is_ssl_sock
) {
866 /* ssl may read and write for both reads and writes */
867 if (revents
& (FDEVENT_IN
| FDEVENT_OUT
)) {
868 con
->is_readable
= 1;
869 con
->is_writable
= 1;
872 if (revents
& FDEVENT_IN
) {
873 con
->is_readable
= 1;
875 if (revents
& FDEVENT_OUT
) {
876 con
->is_writable
= 1;
877 /* we don't need the event twice */
882 if (con
->state
== CON_STATE_READ
) {
883 connection_handle_read_state(srv
, con
);
886 if (con
->state
== CON_STATE_WRITE
&&
887 !chunkqueue_is_empty(con
->write_queue
) &&
889 connection_handle_write(srv
, con
);
892 if (con
->state
== CON_STATE_CLOSE
) {
893 /* flush the read buffers */
894 connection_read_for_eos(srv
, con
);
898 /* attempt (above) to read data in kernel socket buffers
899 * prior to handling FDEVENT_HUP and FDEVENT_ERR */
901 if ((revents
& ~(FDEVENT_IN
| FDEVENT_OUT
)) && con
->state
!= CON_STATE_ERROR
) {
902 if (con
->state
== CON_STATE_CLOSE
) {
903 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
904 } else if (revents
& FDEVENT_HUP
) {
905 connection_set_state(srv
, con
, CON_STATE_ERROR
);
906 } else if (revents
& FDEVENT_RDHUP
) {
907 int events
= fdevent_fdnode_interest(con
->fdn
);
908 events
&= ~(FDEVENT_IN
|FDEVENT_RDHUP
);
909 con
->conf
.stream_request_body
&= ~(FDEVENT_STREAM_REQUEST_BUFMIN
|FDEVENT_STREAM_REQUEST_POLLIN
);
910 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_POLLRDHUP
;
911 con
->is_readable
= 1; /*(can read 0 for end-of-stream)*/
912 if (chunkqueue_is_empty(con
->read_queue
)) con
->keep_alive
= 0;
913 if (con
->request
.content_length
< -1) { /*(transparent proxy mode; no more data to read)*/
914 con
->request
.content_length
= con
->request_content_queue
->bytes_in
;
916 if (sock_addr_get_family(&con
->dst_addr
) == AF_UNIX
) {
917 /* future: will getpeername() on AF_UNIX properly check if still connected? */
918 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, events
);
919 } else if (fdevent_is_tcp_half_closed(con
->fd
)) {
920 /* Success of fdevent_is_tcp_half_closed() after FDEVENT_RDHUP indicates TCP FIN received,
921 * but does not distinguish between client shutdown(fd, SHUT_WR) and client close(fd).
922 * Remove FDEVENT_RDHUP so that we do not spin on the ready event.
923 * However, a later TCP RST will not be detected until next write to socket.
924 * future: might getpeername() to check for TCP RST on half-closed sockets
925 * (without FDEVENT_RDHUP interest) when checking for write timeouts
926 * once a second in server.c, though getpeername() on Windows might not indicate this */
927 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_TCP_FIN
;
928 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, events
);
930 /* Failure of fdevent_is_tcp_half_closed() indicates TCP RST
931 * (or unable to tell (unsupported OS), though should not
932 * be setting FDEVENT_RDHUP in that case) */
933 connection_set_state(srv
, con
, CON_STATE_ERROR
);
935 } else if (revents
& FDEVENT_ERR
) { /* error, connection reset */
936 connection_set_state(srv
, con
, CON_STATE_ERROR
);
938 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
939 "connection closed: poll() -> ???", revents
);
943 return HANDLER_FINISHED
;
947 connection
*connection_accept(server
*srv
, server_socket
*srv_socket
) {
950 size_t cnt_len
= sizeof(cnt_addr
); /*(size_t intentional; not socklen_t)*/
953 * check if we can still open a new connections
958 if (srv
->conns
->used
>= srv
->max_conns
) {
962 cnt
= fdevent_accept_listenfd(srv_socket
->fd
, (struct sockaddr
*) &cnt_addr
, &cnt_len
);
966 #if EWOULDBLOCK != EAGAIN
970 /* we were stopped _before_ we had a connection */
971 case ECONNABORTED
: /* this is a FreeBSD thingy */
972 /* we were stopped _after_ we had a connection */
978 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "accept failed:", strerror(errno
), errno
);
982 if (sock_addr_get_family(&cnt_addr
) != AF_UNIX
) {
983 network_accept_tcp_nagle_disable(cnt
);
985 return connection_accepted(srv
, srv_socket
, &cnt_addr
, cnt
);
990 /* 0: everything ok, -1: error, -2: con closed */
991 static int connection_read_cq(server
*srv
, connection
*con
, chunkqueue
*cq
, off_t max_bytes
) {
995 force_assert(cq
== con
->read_queue
); /*(code transform assumption; minimize diff)*/
996 force_assert(max_bytes
== MAX_READ_LIMIT
); /*(code transform assumption; minimize diff)*/
998 /* check avail data to read and obtain memory into which to read
999 * fill previous chunk if it has sufficient space
1000 * (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz)
1004 if (0 == fdevent_ioctl_fionread(con
->fd
, S_IFSOCK
, &frd
)) {
1005 mem_len
= (frd
< MAX_READ_LIMIT
) ? (size_t)frd
: MAX_READ_LIMIT
;
1008 mem
= chunkqueue_get_memory(con
->read_queue
, &mem_len
);
1010 #if defined(__WIN32)
1011 len
= recv(con
->fd
, mem
, mem_len
, 0);
1013 len
= read(con
->fd
, mem
, mem_len
);
1014 #endif /* __WIN32 */
1016 chunkqueue_use_memory(con
->read_queue
, len
> 0 ? len
: 0);
1019 con
->is_readable
= 0;
1021 #if defined(__WIN32)
1023 int lastError
= WSAGetLastError();
1024 switch (lastError
) {
1028 /* we have been interrupted before we could read */
1029 con
->is_readable
= 1;
1032 /* suppress logging for this error, expected for keep-alive */
1035 log_error_write(srv
, __FILE__
, __LINE__
, "sd", "connection closed - recv failed: ", lastError
);
1044 /* we have been interrupted before we could read */
1045 con
->is_readable
= 1;
1048 /* suppress logging for this error, expected for keep-alive */
1051 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "connection closed - read failed: ", strerror(errno
), errno
);
1054 #endif /* __WIN32 */
1056 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1059 } else if (len
== 0) {
1060 con
->is_readable
= 0;
1061 /* the other end close the connection -> KEEP-ALIVE */
1066 } else if (len
!= (ssize_t
) mem_len
) {
1067 /* we got less then expected, wait for the next fd-event */
1069 con
->is_readable
= 0;
1072 con
->bytes_read
+= len
;
1077 static int connection_write_cq(server
*srv
, connection
*con
, chunkqueue
*cq
, off_t max_bytes
) {
1078 return srv
->network_backend_write(srv
, con
->fd
, cq
, max_bytes
);
1082 connection
*connection_accepted(server
*srv
, server_socket
*srv_socket
, sock_addr
*cnt_addr
, int cnt
) {
1087 /* ok, we have the connection, register it */
1089 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
1094 con
= connections_get_new_connection(srv
);
1095 con
->errh
= srv
->errh
;
1098 con
->fdn
= fdevent_register(srv
->ev
, con
->fd
, connection_handle_fdevent
, con
);
1099 con
->network_read
= connection_read_cq
;
1100 con
->network_write
= connection_write_cq
;
1102 connection_set_state(srv
, con
, CON_STATE_REQUEST_START
);
1104 con
->connection_start
= srv
->cur_ts
;
1105 con
->dst_addr
= *cnt_addr
;
1106 buffer_copy_string(con
->dst_addr_buf
, inet_ntop_cache_get_ip(srv
, &(con
->dst_addr
)));
1107 con
->srv_socket
= srv_socket
;
1108 con
->is_ssl_sock
= srv_socket
->is_ssl
;
1110 config_cond_cache_reset(srv
, con
);
1111 con
->conditional_is_valid
[COMP_SERVER_SOCKET
] = 1;
1112 con
->conditional_is_valid
[COMP_HTTP_REMOTE_IP
] = 1;
1114 buffer_copy_string_len(con
->proto
, CONST_STR_LEN("http"));
1115 if (HANDLER_GO_ON
!= plugins_call_handle_connection_accept(srv
, con
)) {
1116 connection_reset(srv
, con
);
1117 connection_close(srv
, con
);
1120 if (con
->http_status
< 0) connection_set_state(srv
, con
, CON_STATE_WRITE
);
1125 static int connection_handle_request(server
*srv
, connection
*con
) {
1126 int r
= http_response_prepare(srv
, con
);
1128 case HANDLER_WAIT_FOR_EVENT
:
1129 if (!con
->file_finished
&& (!con
->file_started
|| 0 == con
->conf
.stream_response_body
)) {
1130 break; /* come back here */
1132 /* response headers received from backend; fall through to start response */
1134 case HANDLER_FINISHED
:
1135 if (con
->http_status
== 0) con
->http_status
= 200;
1136 if (con
->error_handler_saved_status
> 0) {
1137 con
->request
.http_method
= con
->error_handler_saved_method
;
1139 if (con
->mode
== DIRECT
|| con
->conf
.error_intercept
) {
1140 if (con
->error_handler_saved_status
) {
1141 const int subreq_status
= con
->http_status
;
1142 if (con
->error_handler_saved_status
> 0) {
1143 con
->http_status
= con
->error_handler_saved_status
;
1144 } else if (con
->http_status
== 404 || con
->http_status
== 403) {
1145 /* error-handler-404 is a 404 */
1146 con
->http_status
= -con
->error_handler_saved_status
;
1148 /* error-handler-404 is back and has generated content */
1149 /* if Status: was set, take it otherwise use 200 */
1151 if (200 <= subreq_status
&& subreq_status
<= 299) {
1152 /*(flag value to indicate that error handler succeeded)
1153 *(for (con->mode == DIRECT))*/
1154 con
->error_handler_saved_status
= 65535; /* >= 1000 */
1156 } else if (con
->http_status
>= 400) {
1157 buffer
*error_handler
= NULL
;
1158 if (!buffer_string_is_empty(con
->conf
.error_handler
)) {
1159 error_handler
= con
->conf
.error_handler
;
1160 } else if ((con
->http_status
== 404 || con
->http_status
== 403)
1161 && !buffer_string_is_empty(con
->conf
.error_handler_404
)) {
1162 error_handler
= con
->conf
.error_handler_404
;
1165 if (error_handler
) {
1166 /* call error-handler */
1168 /* set REDIRECT_STATUS to save current HTTP status code
1169 * for access by dynamic handlers
1170 * https://redmine.lighttpd.net/issues/1828 */
1171 buffer_copy_int(srv
->tmp_buf
, con
->http_status
);
1172 http_header_env_set(con
, CONST_STR_LEN("REDIRECT_STATUS"), CONST_BUF_LEN(srv
->tmp_buf
));
1174 if (error_handler
== con
->conf
.error_handler
) {
1175 plugins_call_connection_reset(srv
, con
);
1177 if (con
->request
.content_length
) {
1178 if (con
->request
.content_length
!= con
->request_content_queue
->bytes_in
) {
1179 con
->keep_alive
= 0;
1181 con
->request
.content_length
= 0;
1182 chunkqueue_reset(con
->request_content_queue
);
1185 con
->is_writable
= 1;
1186 con
->file_finished
= 0;
1187 con
->file_started
= 0;
1189 con
->error_handler_saved_status
= con
->http_status
;
1190 con
->error_handler_saved_method
= con
->request
.http_method
;
1192 con
->request
.http_method
= HTTP_METHOD_GET
;
1193 } else { /*(preserve behavior for server.error-handler-404)*/
1194 con
->error_handler_saved_status
= -con
->http_status
; /*(negative to flag old behavior)*/
1197 if (con
->request
.http_version
== HTTP_VERSION_UNSET
) con
->request
.http_version
= HTTP_VERSION_1_0
;
1199 buffer_copy_buffer(con
->request
.uri
, error_handler
);
1200 connection_handle_errdoc_init(con
);
1201 con
->http_status
= 0; /*(after connection_handle_errdoc_init())*/
1208 /* we have something to send, go on */
1209 connection_set_state(srv
, con
, CON_STATE_RESPONSE_START
);
1211 case HANDLER_WAIT_FOR_FD
:
1214 fdwaitqueue_append(srv
, con
);
1217 case HANDLER_COMEBACK
:
1220 /* something went wrong */
1221 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1224 log_error_write(srv
, __FILE__
, __LINE__
, "sdd", "unknown ret-value: ", con
->fd
, r
);
1232 int connection_state_machine(server
*srv
, connection
*con
) {
1233 connection_state_t ostate
;
1235 const int log_state_handling
= srv
->srvconf
.log_state_handling
;
1237 if (log_state_handling
) {
1238 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1241 connection_get_state(con
->state
));
1245 if (log_state_handling
) {
1246 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1247 "state for fd", con
->fd
, connection_get_state(con
->state
));
1250 switch ((ostate
= con
->state
)) {
1251 case CON_STATE_REQUEST_START
: /* transient */
1252 con
->request_start
= srv
->cur_ts
;
1253 con
->read_idle_ts
= srv
->cur_ts
;
1254 if (con
->conf
.high_precision_timestamps
)
1255 log_clock_gettime_realtime(&con
->request_start_hp
);
1257 con
->request_count
++;
1258 con
->loops_per_request
= 0;
1260 connection_set_state(srv
, con
, CON_STATE_READ
);
1262 case CON_STATE_READ
:
1263 connection_handle_read_state(srv
, con
);
1264 if (con
->state
!= CON_STATE_REQUEST_END
) break;
1266 case CON_STATE_REQUEST_END
: /* transient */
1267 ostate
= (0 == con
->request
.content_length
)
1268 ? CON_STATE_HANDLE_REQUEST
1269 : CON_STATE_READ_POST
;
1270 connection_set_state(srv
, con
, ostate
);
1272 case CON_STATE_READ_POST
:
1273 case CON_STATE_HANDLE_REQUEST
:
1274 if (connection_handle_request(srv
, con
)) {
1275 /* redo loop; will not match con->state */
1276 ostate
= CON_STATE_CONNECT
;
1280 if (con
->state
== CON_STATE_HANDLE_REQUEST
1281 && ostate
== CON_STATE_READ_POST
) {
1282 ostate
= CON_STATE_HANDLE_REQUEST
;
1285 if (con
->state
!= CON_STATE_RESPONSE_START
) break;
1287 case CON_STATE_RESPONSE_START
: /* transient */
1288 if (-1 == connection_handle_write_prepare(srv
, con
)) {
1289 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1292 connection_set_state(srv
, con
, CON_STATE_WRITE
);
1294 case CON_STATE_WRITE
:
1295 connection_handle_write_state(srv
, con
);
1296 if (con
->state
!= CON_STATE_RESPONSE_END
) break;
1298 case CON_STATE_RESPONSE_END
: /* transient */
1299 case CON_STATE_ERROR
: /* transient */
1300 connection_handle_response_end_state(srv
, con
);
1302 case CON_STATE_CLOSE
:
1303 connection_handle_close_state(srv
, con
);
1305 case CON_STATE_CONNECT
:
1308 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
1309 "unknown state:", con
->fd
, con
->state
);
1312 } while (ostate
!= con
->state
);
1314 if (log_state_handling
) {
1315 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1318 connection_get_state(con
->state
));
1322 switch(con
->state
) {
1323 case CON_STATE_READ
:
1324 r
= FDEVENT_IN
| FDEVENT_RDHUP
;
1326 case CON_STATE_WRITE
:
1327 /* request write-fdevent only if we really need it
1328 * - if we have data to write
1329 * - if the socket is not writable yet
1331 if (!chunkqueue_is_empty(con
->write_queue
) &&
1332 (con
->is_writable
== 0) &&
1333 (con
->traffic_limit_reached
== 0)) {
1337 case CON_STATE_READ_POST
:
1338 if (con
->conf
.stream_request_body
& FDEVENT_STREAM_REQUEST_POLLIN
) {
1339 r
|= FDEVENT_IN
| FDEVENT_RDHUP
;
1342 case CON_STATE_CLOSE
:
1349 const int events
= fdevent_fdnode_interest(con
->fdn
);
1350 if (con
->is_readable
< 0) {
1351 con
->is_readable
= 0;
1354 if (con
->is_writable
< 0) {
1355 con
->is_writable
= 0;
1358 if (events
& FDEVENT_RDHUP
) {
1362 /* update timestamps when enabling interest in events */
1363 if ((r
& FDEVENT_IN
) && !(events
& FDEVENT_IN
)) {
1364 con
->read_idle_ts
= srv
->cur_ts
;
1366 if ((r
& FDEVENT_OUT
) && !(events
& FDEVENT_OUT
)) {
1367 con
->write_request_ts
= srv
->cur_ts
;
1369 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, r
);
1376 static void connection_check_timeout (server
* const srv
, const time_t cur_ts
, connection
* const con
) {
1377 const int waitevents
= fdevent_fdnode_interest(con
->fdn
);
1381 if (con
->state
== CON_STATE_CLOSE
) {
1382 if (cur_ts
- con
->close_timeout_ts
> HTTP_LINGER_TIMEOUT
) {
1385 } else if (waitevents
& FDEVENT_IN
) {
1386 if (con
->request_count
== 1 || con
->state
!= CON_STATE_READ
) {
1387 /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */
1388 if (cur_ts
- con
->read_idle_ts
> con
->conf
.max_read_idle
) {
1390 if (con
->conf
.log_request_handling
) {
1391 log_error(con
->errh
, __FILE__
, __LINE__
,
1392 "connection closed - read timeout: %d", con
->fd
);
1395 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1399 if (cur_ts
- con
->read_idle_ts
> con
->keep_alive_idle
) {
1401 if (con
->conf
.log_request_handling
) {
1402 log_error(con
->errh
, __FILE__
, __LINE__
,
1403 "connection closed - keep-alive timeout: %d",
1407 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1413 /* max_write_idle timeout currently functions as backend timeout,
1414 * too, after response has been started.
1415 * future: have separate backend timeout, and then change this
1416 * to check for write interest before checking for timeout */
1417 /*if (waitevents & FDEVENT_OUT)*/
1418 if ((con
->state
== CON_STATE_WRITE
) &&
1419 (con
->write_request_ts
!= 0)) {
1421 if (cur_ts
- con
->write_request_ts
> 60) {
1422 log_error(con
->errh
, __FILE__
, __LINE__
,
1423 "connection closed - pre-write-request-timeout: %d %d",
1424 con
->fd
, cur_ts
- con
->write_request_ts
);
1428 if (cur_ts
- con
->write_request_ts
> con
->conf
.max_write_idle
) {
1430 if (con
->conf
.log_timeouts
) {
1431 log_error(con
->errh
, __FILE__
, __LINE__
,
1432 "NOTE: a request from %.*s for %.*s timed out after writing "
1433 "%zd bytes. We waited %d seconds. If this is a problem, "
1434 "increase server.max-write-idle",
1435 BUFFER_INTLEN_PTR(con
->dst_addr_buf
),
1436 BUFFER_INTLEN_PTR(con
->request
.uri
),
1437 con
->bytes_written
, (int)con
->conf
.max_write_idle
);
1439 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1444 /* we don't like div by zero */
1445 if (0 == (t_diff
= cur_ts
- con
->connection_start
)) t_diff
= 1;
1447 if (con
->traffic_limit_reached
&&
1448 (con
->conf
.kbytes_per_second
== 0 ||
1449 ((con
->bytes_written
/ t_diff
) < con
->conf
.kbytes_per_second
* 1024))){
1450 /* enable connection again */
1451 con
->traffic_limit_reached
= 0;
1456 con
->bytes_written_cur_second
= 0;
1459 connection_state_machine(srv
, con
);
1463 void connection_periodic_maint (server
* const srv
, const time_t cur_ts
) {
1464 /* check all connections for timeouts */
1465 connections
* const conns
= srv
->conns
;
1466 for (size_t ndx
= 0; ndx
< conns
->used
; ++ndx
) {
1467 connection_check_timeout(srv
, cur_ts
, conns
->ptr
[ndx
]);
1471 void connection_graceful_shutdown_maint (server
*srv
) {
1472 connections
*conns
= srv
->conns
;
1473 for (size_t ndx
= 0; ndx
< conns
->used
; ++ndx
) {
1474 connection
* const con
= conns
->ptr
[ndx
];
1477 if (con
->state
== CON_STATE_CLOSE
) {
1478 /* reduce remaining linger timeout to be
1479 * (from zero) *up to* one more second, but no more */
1480 if (HTTP_LINGER_TIMEOUT
> 1)
1481 con
->close_timeout_ts
-= (HTTP_LINGER_TIMEOUT
- 1);
1482 if (srv
->cur_ts
- con
->close_timeout_ts
> HTTP_LINGER_TIMEOUT
)
1485 else if (con
->state
== CON_STATE_READ
&& con
->request_count
> 1
1486 && chunkqueue_is_empty(con
->read_queue
)) {
1487 /* close connections in keep-alive waiting for next request */
1488 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1492 con
->keep_alive
= 0; /* disable keep-alive */
1494 con
->conf
.kbytes_per_second
= 0; /* disable rate limit */
1495 con
->conf
.global_kbytes_per_second
= 0; /* disable rate limit */
1496 if (con
->traffic_limit_reached
) {
1497 con
->traffic_limit_reached
= 0;
1502 connection_state_machine(srv
, con
);