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"
41 static connection
*connection_init(server
*srv
);
43 static int connection_reset(server
*srv
, connection
*con
);
46 static connection
*connections_get_new_connection(server
*srv
) {
47 connections
*conns
= srv
->conns
;
50 if (conns
->size
== conns
->used
) {
51 conns
->size
+= srv
->max_conns
>= 128 ? 128 : srv
->max_conns
> 16 ? 16 : srv
->max_conns
;
52 conns
->ptr
= realloc(conns
->ptr
, sizeof(*conns
->ptr
) * conns
->size
);
53 force_assert(NULL
!= conns
->ptr
);
55 for (i
= conns
->used
; i
< conns
->size
; i
++) {
56 conns
->ptr
[i
] = connection_init(srv
);
57 connection_reset(srv
, conns
->ptr
[i
]);
61 conns
->ptr
[conns
->used
]->ndx
= conns
->used
;
62 return conns
->ptr
[conns
->used
++];
65 static int connection_del(server
*srv
, connection
*con
) {
67 connections
*conns
= srv
->conns
;
70 if (con
== NULL
) return -1;
72 if (-1 == con
->ndx
) return -1;
74 buffer_clear(con
->uri
.authority
);
75 buffer_reset(con
->uri
.path
);
76 buffer_reset(con
->uri
.query
);
77 buffer_reset(con
->request
.orig_uri
);
81 /* not last element */
83 if (i
!= conns
->used
- 1) {
85 conns
->ptr
[i
] = conns
->ptr
[conns
->used
- 1];
86 conns
->ptr
[conns
->used
- 1] = temp
;
88 conns
->ptr
[i
]->ndx
= i
;
89 conns
->ptr
[conns
->used
- 1]->ndx
= -1;
96 fprintf(stderr
, "%s.%d: del: (%d)", __FILE__
, __LINE__
, conns
->used
);
97 for (i
= 0; i
< conns
->used
; i
++) {
98 fprintf(stderr
, "%d ", conns
->ptr
[i
]->fd
);
100 fprintf(stderr
, "\n");
105 static int connection_close(server
*srv
, connection
*con
) {
106 if (con
->fd
< 0) con
->fd
= -con
->fd
;
108 plugins_call_handle_connection_close(srv
, con
);
110 con
->request_count
= 0;
111 chunkqueue_reset(con
->read_queue
);
113 fdevent_fdnode_event_del(srv
->ev
, con
->fdn
);
114 fdevent_unregister(srv
->ev
, con
->fd
);
117 if (closesocket(con
->fd
)) {
118 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
119 "(warning) close:", con
->fd
, strerror(errno
));
122 if (close(con
->fd
)) {
123 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
124 "(warning) close:", con
->fd
, strerror(errno
));
131 if (srv
->srvconf
.log_state_handling
) {
132 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
133 "connection closed for fd", con
->fd
);
136 con
->is_ssl_sock
= 0;
138 /* plugins should have cleaned themselves up */
139 for (size_t i
= 0; i
< srv
->plugins
.used
; ++i
) {
140 plugin
*p
= ((plugin
**)(srv
->plugins
.ptr
))[i
];
141 plugin_data
*pd
= p
->data
;
142 if (!pd
|| NULL
== con
->plugin_ctx
[pd
->id
]) continue;
143 log_error_write(srv
, __FILE__
, __LINE__
, "sb",
144 "missing cleanup in", p
->name
);
145 con
->plugin_ctx
[pd
->id
] = NULL
;
148 connection_del(srv
, con
);
149 connection_set_state(srv
, con
, CON_STATE_CONNECT
);
154 static void connection_read_for_eos_plain(server
*srv
, connection
*con
) {
155 /* we have to do the linger_on_close stuff regardless
156 * of con->keep_alive; even non-keepalive sockets may
157 * still have unread data, and closing before reading
158 * it will make the client not see all our output.
161 const int type
= con
->dst_addr
.plain
.sa_family
;
164 len
= fdevent_socket_read_discard(con
->fd
, buf
, sizeof(buf
),
166 } while (len
> 0 || (len
< 0 && errno
== EINTR
));
168 if (len
< 0 && errno
== EAGAIN
) return;
169 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
170 if (len
< 0 && errno
== EWOULDBLOCK
) return;
173 /* 0 == len || (len < 0 && (errno is a non-recoverable error)) */
174 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
177 static void connection_read_for_eos_ssl(server
*srv
, connection
*con
) {
178 if (con
->network_read(srv
, con
, con
->read_queue
, MAX_READ_LIMIT
) < 0)
179 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
180 chunkqueue_reset(con
->read_queue
);
183 static void connection_read_for_eos(server
*srv
, connection
*con
) {
185 ? connection_read_for_eos_plain(srv
, con
)
186 : connection_read_for_eos_ssl(srv
, con
);
189 static void connection_handle_close_state(server
*srv
, connection
*con
) {
190 connection_read_for_eos(srv
, con
);
192 if (srv
->cur_ts
- con
->close_timeout_ts
> HTTP_LINGER_TIMEOUT
) {
193 connection_close(srv
, con
);
197 static void connection_handle_shutdown(server
*srv
, connection
*con
) {
198 plugins_call_handle_connection_shut_wr(srv
, con
);
201 connection_reset(srv
, con
);
203 /* close the connection */
205 && (con
->is_ssl_sock
|| 0 == shutdown(con
->fd
, SHUT_WR
))) {
206 con
->close_timeout_ts
= srv
->cur_ts
;
207 connection_set_state(srv
, con
, CON_STATE_CLOSE
);
209 if (srv
->srvconf
.log_state_handling
) {
210 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
211 "shutdown for fd", con
->fd
);
214 connection_close(srv
, con
);
218 static void connection_handle_response_end_state(server
*srv
, connection
*con
) {
219 /* log the request */
220 /* (even if error, connection dropped, still write to access log if http_status) */
221 if (con
->http_status
) {
222 plugins_call_handle_request_done(srv
, con
);
225 if (con
->state
!= CON_STATE_ERROR
) srv
->con_written
++;
227 if (con
->request
.content_length
!= con
->request_content_queue
->bytes_in
228 || con
->state
== CON_STATE_ERROR
) {
229 /* request body is present and has not been read completely */
233 if (con
->keep_alive
) {
234 connection_reset(srv
, con
);
236 con
->request_start
= srv
->cur_ts
;
237 con
->read_idle_ts
= srv
->cur_ts
;
239 connection_set_state(srv
, con
, CON_STATE_REQUEST_START
);
241 connection_handle_shutdown(srv
, con
);
245 static void connection_handle_errdoc_init(connection
*con
) {
246 /* modules that produce headers required with error response should
247 * typically also produce an error document. Make an exception for
248 * mod_auth WWW-Authenticate response header. */
249 buffer
*www_auth
= NULL
;
250 if (401 == con
->http_status
) {
251 buffer
*vb
= http_header_response_get(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("WWW-Authenticate"));
252 if (NULL
!= vb
) www_auth
= buffer_init_buffer(vb
);
255 buffer_reset(con
->physical
.path
);
256 con
->response
.htags
= 0;
257 array_reset_data_strings(con
->response
.headers
);
258 http_response_body_clear(con
, 0);
260 if (NULL
!= www_auth
) {
261 http_header_response_set(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(www_auth
));
262 buffer_free(www_auth
);
266 static int connection_handle_write_prepare(server
*srv
, connection
*con
) {
267 if (con
->mode
== DIRECT
) {
269 switch(con
->request
.http_method
) {
270 case HTTP_METHOD_GET
:
271 case HTTP_METHOD_POST
:
272 case HTTP_METHOD_HEAD
:
274 case HTTP_METHOD_OPTIONS
:
276 * 400 is coming from the request-parser BEFORE uri.path is set
277 * 403 is from the response handler when noone else catched it
280 if ((!con
->http_status
|| con
->http_status
== 200) && !buffer_string_is_empty(con
->uri
.path
) &&
281 con
->uri
.path
->ptr
[0] != '*') {
282 http_response_body_clear(con
, 0);
283 http_header_response_append(con
, HTTP_HEADER_OTHER
, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
284 con
->http_status
= 200;
285 con
->file_finished
= 1;
290 if (0 == con
->http_status
) {
291 con
->http_status
= 501;
297 if (con
->http_status
== 0) {
298 con
->http_status
= 403;
301 switch(con
->http_status
) {
302 case 204: /* class: header only */
305 /* disable chunked encoding again as we have no body */
306 http_response_body_clear(con
, 1);
307 con
->file_finished
= 1;
309 default: /* class: header + body */
310 /* only custom body for 4xx and 5xx */
311 if (con
->http_status
< 400 || con
->http_status
>= 600) break;
313 if (con
->mode
!= DIRECT
&& (!con
->conf
.error_intercept
|| con
->error_handler_saved_status
)) break;
314 if (con
->mode
== DIRECT
&& con
->error_handler_saved_status
>= 65535) break;
316 con
->file_finished
= 0;
318 connection_handle_errdoc_init(con
);
320 /* try to send static errorfile */
321 if (!buffer_string_is_empty(con
->conf
.errorfile_prefix
)) {
322 stat_cache_entry
*sce
= NULL
;
324 buffer_copy_buffer(con
->physical
.path
, con
->conf
.errorfile_prefix
);
325 buffer_append_int(con
->physical
.path
, con
->http_status
);
326 buffer_append_string_len(con
->physical
.path
, CONST_STR_LEN(".html"));
328 if (0 == http_chunk_append_file(srv
, con
, con
->physical
.path
)) {
329 con
->file_finished
= 1;
330 if (HANDLER_ERROR
!= stat_cache_get_entry(srv
, con
, con
->physical
.path
, &sce
)) {
331 stat_cache_content_type_get(srv
, con
, con
->physical
.path
, sce
);
332 http_header_response_set(con
, HTTP_HEADER_CONTENT_TYPE
, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce
->content_type
));
337 if (!con
->file_finished
) {
338 buffer
*b
= srv
->tmp_buf
;
340 buffer_reset(con
->physical
.path
);
342 con
->file_finished
= 1;
344 /* build default error-page */
345 buffer_copy_string_len(b
, CONST_STR_LEN(
346 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
347 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
348 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
349 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
352 http_status_append(b
, con
->http_status
);
354 buffer_append_string_len(b
, CONST_STR_LEN(
359 http_status_append(b
, con
->http_status
);
361 buffer_append_string_len(b
, CONST_STR_LEN("</h1>\n"
366 (void)http_chunk_append_mem(srv
, con
, CONST_BUF_LEN(b
));
368 http_header_response_set(con
, HTTP_HEADER_CONTENT_TYPE
, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
373 /* Allow filter plugins to change response headers before they are written. */
374 switch(plugins_call_handle_response_start(srv
, con
)) {
376 case HANDLER_FINISHED
:
379 log_error_write(srv
, __FILE__
, __LINE__
, "s", "response_start plugin failed");
383 if (con
->file_finished
) {
384 /* we have all the content and chunked encoding is not used, set a content-length */
386 if (!(con
->response
.htags
& (HTTP_HEADER_CONTENT_LENGTH
|HTTP_HEADER_TRANSFER_ENCODING
))) {
387 off_t qlen
= chunkqueue_length(con
->write_queue
);
390 * The Content-Length header only can be sent if we have content:
391 * - HEAD doesn't have a content-body (but have a content-length)
392 * - 1xx, 204 and 304 don't have a content-body (RFC 2616 Section 4.3)
394 * Otherwise generate a Content-Length header as chunked encoding is not
397 if ((con
->http_status
>= 100 && con
->http_status
< 200) ||
398 con
->http_status
== 204 ||
399 con
->http_status
== 304) {
400 /* no Content-Body, no Content-Length */
401 http_header_response_unset(con
, HTTP_HEADER_CONTENT_LENGTH
, CONST_STR_LEN("Content-Length"));
402 } else if (qlen
> 0 || con
->request
.http_method
!= HTTP_METHOD_HEAD
) {
403 /* qlen = 0 is important for Redirects (301, ...) as they MAY have
404 * a content. Browsers are waiting for a Content otherwise
406 buffer_copy_int(srv
->tmp_buf
, qlen
);
407 http_header_response_set(con
, HTTP_HEADER_CONTENT_LENGTH
, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv
->tmp_buf
));
412 * the file isn't finished yet, but we have all headers
414 * to get keep-alive we either need:
415 * - Content-Length: ... (HTTP/1.0 and HTTP/1.0) or
416 * - Transfer-Encoding: chunked (HTTP/1.1)
417 * - Upgrade: ... (lighttpd then acts as transparent proxy)
420 if (!(con
->response
.htags
& (HTTP_HEADER_CONTENT_LENGTH
|HTTP_HEADER_TRANSFER_ENCODING
|HTTP_HEADER_UPGRADE
))) {
421 if (con
->request
.http_method
== HTTP_METHOD_CONNECT
422 && con
->http_status
== 200) {
423 /*(no transfer-encoding if successful CONNECT)*/
424 } else if (con
->request
.http_version
== HTTP_VERSION_1_1
) {
425 off_t qlen
= chunkqueue_length(con
->write_queue
);
426 con
->response
.send_chunked
= 1;
428 /* create initial Transfer-Encoding: chunked segment */
429 buffer
* const b
= chunkqueue_prepend_buffer_open(con
->write_queue
);
430 buffer_append_uint_hex(b
, (uintmax_t)qlen
);
431 buffer_append_string_len(b
, CONST_STR_LEN("\r\n"));
432 chunkqueue_prepend_buffer_commit(con
->write_queue
);
433 chunkqueue_append_mem(con
->write_queue
, CONST_STR_LEN("\r\n"));
435 http_header_response_append(con
, HTTP_HEADER_TRANSFER_ENCODING
, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN("chunked"));
442 if (con
->request
.http_method
== HTTP_METHOD_HEAD
) {
444 * a HEAD request has the same as a GET
445 * without the content
447 http_response_body_clear(con
, 1);
448 con
->file_finished
= 1;
451 http_response_write_header(srv
, con
);
456 static void connection_handle_write(server
*srv
, connection
*con
) {
457 switch(connection_write_chunkqueue(srv
, con
, con
->write_queue
, MAX_WRITE_LIMIT
)) {
459 con
->write_request_ts
= srv
->cur_ts
;
460 if (con
->file_finished
) {
461 connection_set_state(srv
, con
, CON_STATE_RESPONSE_END
);
464 case -1: /* error on our side */
465 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
466 "connection closed: write failed on fd", con
->fd
);
467 connection_set_state(srv
, con
, CON_STATE_ERROR
);
469 case -2: /* remote close */
470 connection_set_state(srv
, con
, CON_STATE_ERROR
);
473 con
->write_request_ts
= srv
->cur_ts
;
474 con
->is_writable
= 0;
476 /* not finished yet -> WRITE */
481 static void connection_handle_write_state(server
*srv
, connection
*con
) {
483 /* only try to write if we have something in the queue */
484 if (!chunkqueue_is_empty(con
->write_queue
)) {
485 if (con
->is_writable
) {
486 connection_handle_write(srv
, con
);
487 if (con
->state
!= CON_STATE_WRITE
) break;
489 } else if (con
->file_finished
) {
490 connection_set_state(srv
, con
, CON_STATE_RESPONSE_END
);
494 if (con
->mode
!= DIRECT
&& !con
->file_finished
) {
495 int r
= plugins_call_handle_subrequest(srv
, con
);
497 case HANDLER_WAIT_FOR_EVENT
:
498 case HANDLER_FINISHED
:
501 case HANDLER_WAIT_FOR_FD
:
503 fdwaitqueue_append(srv
, con
);
505 case HANDLER_COMEBACK
:
507 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
508 "unexpected subrequest handler ret-value:",
512 connection_set_state(srv
, con
, CON_STATE_ERROR
);
516 } while (con
->state
== CON_STATE_WRITE
517 && (!chunkqueue_is_empty(con
->write_queue
)
519 : con
->file_finished
));
525 static connection
*connection_init(server
*srv
) {
530 con
= calloc(1, sizeof(*con
));
531 force_assert(NULL
!= con
);
535 con
->bytes_written
= 0;
537 con
->bytes_header
= 0;
538 con
->loops_per_request
= 0;
541 con->x = buffer_init();
544 CLEAN(request
.request
);
545 CLEAN(request
.pathinfo
);
547 CLEAN(request
.orig_uri
);
550 CLEAN(uri
.authority
);
555 CLEAN(physical
.doc_root
);
556 CLEAN(physical
.path
);
557 CLEAN(physical
.basedir
);
558 CLEAN(physical
.rel_path
);
559 CLEAN(physical
.etag
);
566 con
->write_queue
= chunkqueue_init();
567 con
->read_queue
= chunkqueue_init();
568 con
->request_content_queue
= chunkqueue_init();
570 con
->request
.headers
= array_init();
571 con
->response
.headers
= array_init();
572 con
->environment
= array_init();
574 /* init plugin specific connection structures */
576 con
->plugin_ctx
= calloc(1, (srv
->plugins
.used
+ 1) * sizeof(void *));
577 force_assert(NULL
!= con
->plugin_ctx
);
579 con
->cond_cache
= calloc(srv
->config_context
->used
, sizeof(cond_cache_t
));
580 force_assert(NULL
!= con
->cond_cache
);
581 config_setup_connection(srv
, con
);
586 void connections_free(server
*srv
) {
587 connections
*conns
= srv
->conns
;
590 if (NULL
== conns
) return;
592 for (i
= 0; i
< conns
->size
; i
++) {
593 connection
*con
= conns
->ptr
[i
];
595 connection_reset(srv
, con
);
597 chunkqueue_free(con
->write_queue
);
598 chunkqueue_free(con
->read_queue
);
599 chunkqueue_free(con
->request_content_queue
);
600 array_free(con
->request
.headers
);
601 array_free(con
->response
.headers
);
602 array_free(con
->environment
);
608 CLEAN(request
.request
);
609 CLEAN(request
.pathinfo
);
611 CLEAN(request
.orig_uri
);
614 CLEAN(uri
.authority
);
619 CLEAN(physical
.doc_root
);
620 CLEAN(physical
.path
);
621 CLEAN(physical
.basedir
);
622 CLEAN(physical
.etag
);
623 CLEAN(physical
.rel_path
);
629 free(con
->plugin_ctx
);
630 free(con
->cond_cache
);
641 static int connection_reset(server
*srv
, connection
*con
) {
642 plugins_call_connection_reset(srv
, con
);
644 connection_response_reset(srv
, con
);
645 con
->is_readable
= 1;
647 con
->bytes_written
= 0;
648 con
->bytes_written_cur_second
= 0;
650 con
->bytes_header
= 0;
651 con
->loops_per_request
= 0;
653 con
->request
.http_method
= HTTP_METHOD_UNSET
;
654 con
->request
.http_version
= HTTP_VERSION_UNSET
;
657 buffer_reset(con->x);
660 CLEAN(request
.pathinfo
);
662 /* CLEAN(request.orig_uri); */
664 /* CLEAN(uri.path); */
666 /* CLEAN(uri.query); */
669 buffer_clear(con
->uri
.scheme
);
670 /*buffer_clear(con->proto);*//* set to default in connection_accepted() */
671 /*buffer_clear(con->uri.authority);*/
672 buffer_clear(con
->server_name
);
674 con
->request
.http_host
= NULL
;
675 con
->request
.content_length
= 0;
676 con
->request
.te_chunked
= 0;
677 con
->request
.htags
= 0;
679 array_reset_data_strings(con
->request
.headers
);
680 array_reset_data_strings(con
->environment
);
682 chunkqueue_reset(con
->request_content_queue
);
684 /* The cond_cache gets reset in response.c */
685 /* config_cond_cache_reset(srv, con); */
688 con
->async_callback
= 0;
689 con
->error_handler_saved_status
= 0;
690 /*con->error_handler_saved_method = HTTP_METHOD_UNSET;*/
691 /*(error_handler_saved_method value is not valid unless error_handler_saved_status is set)*/
693 config_setup_connection(srv
, con
);
698 static void connection_read_header(server
*srv
, connection
*con
) {
699 chunkqueue
* const cq
= con
->read_queue
;
705 for (c
= cq
->first
; c
; c
= c
->next
) {
706 size_t clen
= buffer_string_length(c
->mem
) - c
->offset
;
707 const char * const b
= c
->mem
->ptr
+ c
->offset
;
709 if (0 == clen
) continue;
710 if (le
) { /*(line end sequence cross chunk boundary)*/
711 if (n
[0] == '\r') ++n
;
712 if (n
[0] == '\n') { ++n
; hlen
+= n
- b
; break; }
713 if (n
[0] == '\0') { hlen
+= n
- b
; continue; }
716 for (const char * const end
= b
+clen
; (n
= memchr(n
,'\n',end
-n
)); ++n
) {
717 if (n
[1] == '\r') ++n
;
718 if (n
[1] == '\n') { hlen
+= n
- b
+ 2; break; }
719 if (n
[1] == '\0') { n
= NULL
; le
= 1; break; }
725 if (hlen
> srv
->srvconf
.max_request_field_size
) {
726 log_error_write(srv
, __FILE__
, __LINE__
, "s",
727 "oversized request-header -> sending Status 431");
728 con
->http_status
= 431; /* Request Header Fields Too Large */
730 connection_set_state(srv
, con
, CON_STATE_HANDLE_REQUEST
);
733 if (NULL
== c
) return; /* incomplete request headers */
735 con
->header_len
= hlen
;
737 buffer_clear(con
->request
.request
);
739 for (c
= cq
->first
; c
; c
= c
->next
) {
740 size_t len
= buffer_string_length(c
->mem
) - c
->offset
;
741 if (len
> hlen
) len
= hlen
;
742 buffer_append_string_len(con
->request
.request
,
743 c
->mem
->ptr
+ c
->offset
, len
);
744 if (0 == (hlen
-= len
)) break;
747 chunkqueue_mark_written(cq
, con
->header_len
);
749 /* skip past \r\n or \n after previous POST request when keep-alive */
750 if (con
->request_count
> 1) {
751 char * const s
= con
->request
.request
->ptr
;
753 if (buffer_string_length(con
->request
.request
) < 2) {
757 if (s
[0] == '\r' && s
[1] == '\n') {
758 size_t len
= buffer_string_length(con
->request
.request
);
759 memmove(s
, s
+2, len
-2);
760 buffer_string_set_length(con
->request
.request
, len
-2);
762 else if (s
[0] == '\n') {
763 if (!(con
->conf
.http_parseopts
& HTTP_PARSEOPT_HEADER_STRICT
)) {
764 size_t len
= buffer_string_length(con
->request
.request
);
765 memmove(s
, s
+1, len
-1);
766 buffer_string_set_length(con
->request
.request
, len
-1);
771 if (con
->conf
.log_request_header
) {
772 log_error_write(srv
, __FILE__
, __LINE__
, "sdsdSb",
774 "request-len:", buffer_string_length(con
->request
.request
),
775 "\n", con
->request
.request
);
778 buffer_clear(con
->uri
.authority
);
779 buffer_reset(con
->uri
.path
);
780 buffer_reset(con
->uri
.query
);
781 buffer_reset(con
->request
.orig_uri
);
783 if (srv
->srvconf
.log_request_header_on_error
) {
784 /* copy request only if we may need to log it upon error */
785 save
= buffer_init_buffer(con
->request
.request
);
788 con
->http_status
= http_request_parse(srv
, con
, con
->request
.request
);
789 if (0 != con
->http_status
) {
791 con
->request
.content_length
= 0;
793 if (srv
->srvconf
.log_request_header_on_error
) {
794 log_error_write(srv
, __FILE__
, __LINE__
, "Sb",
795 "request-header:\n", save
);
799 if (NULL
!= save
) buffer_free(save
);
800 buffer_reset(con
->request
.request
);
802 connection_set_state(srv
, con
, CON_STATE_REQUEST_END
);
806 * handle request header read
808 * we get called by the state-engine and by the fdevent-handler
810 static int connection_handle_read_state(server
*srv
, connection
*con
) {
811 int is_closed
= 0; /* the connection got closed, if we don't have a complete header, -> error */
813 if (con
->request_count
> 1 && 0 == con
->bytes_read
) {
815 /* update request_start timestamp when first byte of
816 * next request is received on a keep-alive connection */
817 con
->request_start
= srv
->cur_ts
;
818 if (con
->conf
.high_precision_timestamps
)
819 log_clock_gettime_realtime(&con
->request_start_hp
);
821 if (!chunkqueue_is_empty(con
->read_queue
)) {
822 /*(if partially read next request and unable to read() any bytes below,
823 * then will unnecessarily scan again here before subsequent read())*/
824 connection_read_header(srv
, con
);
825 if (con
->state
!= CON_STATE_READ
) {
826 con
->read_idle_ts
= srv
->cur_ts
;
832 if (con
->is_readable
) {
833 con
->read_idle_ts
= srv
->cur_ts
;
835 switch (con
->network_read(srv
, con
, con
->read_queue
, MAX_READ_LIMIT
)) {
837 connection_set_state(srv
, con
, CON_STATE_ERROR
);
847 connection_read_header(srv
, con
);
849 if (con
->state
== CON_STATE_READ
&& is_closed
) {
850 /* the connection got closed and we didn't got enough data to leave CON_STATE_READ;
851 * the only way is to leave here */
852 connection_set_state(srv
, con
, CON_STATE_ERROR
);
858 static handler_t
connection_handle_fdevent(server
*srv
, void *context
, int revents
) {
859 connection
*con
= context
;
861 joblist_append(srv
, con
);
863 if (con
->is_ssl_sock
) {
864 /* ssl may read and write for both reads and writes */
865 if (revents
& (FDEVENT_IN
| FDEVENT_OUT
)) {
866 con
->is_readable
= 1;
867 con
->is_writable
= 1;
870 if (revents
& FDEVENT_IN
) {
871 con
->is_readable
= 1;
873 if (revents
& FDEVENT_OUT
) {
874 con
->is_writable
= 1;
875 /* we don't need the event twice */
880 if (con
->state
== CON_STATE_READ
) {
881 connection_handle_read_state(srv
, con
);
884 if (con
->state
== CON_STATE_WRITE
&&
885 !chunkqueue_is_empty(con
->write_queue
) &&
887 connection_handle_write(srv
, con
);
890 if (con
->state
== CON_STATE_CLOSE
) {
891 /* flush the read buffers */
892 connection_read_for_eos(srv
, con
);
896 /* attempt (above) to read data in kernel socket buffers
897 * prior to handling FDEVENT_HUP and FDEVENT_ERR */
899 if ((revents
& ~(FDEVENT_IN
| FDEVENT_OUT
)) && con
->state
!= CON_STATE_ERROR
) {
900 if (con
->state
== CON_STATE_CLOSE
) {
901 con
->close_timeout_ts
= srv
->cur_ts
- (HTTP_LINGER_TIMEOUT
+1);
902 } else if (revents
& FDEVENT_HUP
) {
903 connection_set_state(srv
, con
, CON_STATE_ERROR
);
904 } else if (revents
& FDEVENT_RDHUP
) {
905 int events
= fdevent_fdnode_interest(con
->fdn
);
906 events
&= ~(FDEVENT_IN
|FDEVENT_RDHUP
);
907 con
->conf
.stream_request_body
&= ~(FDEVENT_STREAM_REQUEST_BUFMIN
|FDEVENT_STREAM_REQUEST_POLLIN
);
908 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_POLLRDHUP
;
909 con
->is_readable
= 1; /*(can read 0 for end-of-stream)*/
910 if (chunkqueue_is_empty(con
->read_queue
)) con
->keep_alive
= 0;
911 if (con
->request
.content_length
< -1) { /*(transparent proxy mode; no more data to read)*/
912 con
->request
.content_length
= con
->request_content_queue
->bytes_in
;
914 if (sock_addr_get_family(&con
->dst_addr
) == AF_UNIX
) {
915 /* future: will getpeername() on AF_UNIX properly check if still connected? */
916 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, events
);
917 } else if (fdevent_is_tcp_half_closed(con
->fd
)) {
918 /* Success of fdevent_is_tcp_half_closed() after FDEVENT_RDHUP indicates TCP FIN received,
919 * but does not distinguish between client shutdown(fd, SHUT_WR) and client close(fd).
920 * Remove FDEVENT_RDHUP so that we do not spin on the ready event.
921 * However, a later TCP RST will not be detected until next write to socket.
922 * future: might getpeername() to check for TCP RST on half-closed sockets
923 * (without FDEVENT_RDHUP interest) when checking for write timeouts
924 * once a second in server.c, though getpeername() on Windows might not indicate this */
925 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_TCP_FIN
;
926 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, events
);
928 /* Failure of fdevent_is_tcp_half_closed() indicates TCP RST
929 * (or unable to tell (unsupported OS), though should not
930 * be setting FDEVENT_RDHUP in that case) */
931 connection_set_state(srv
, con
, CON_STATE_ERROR
);
933 } else if (revents
& FDEVENT_ERR
) { /* error, connection reset */
934 connection_set_state(srv
, con
, CON_STATE_ERROR
);
936 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
937 "connection closed: poll() -> ???", revents
);
941 return HANDLER_FINISHED
;
945 connection
*connection_accept(server
*srv
, server_socket
*srv_socket
) {
948 size_t cnt_len
= sizeof(cnt_addr
); /*(size_t intentional; not socklen_t)*/
951 * check if we can still open a new connections
956 if (srv
->conns
->used
>= srv
->max_conns
) {
960 cnt
= fdevent_accept_listenfd(srv_socket
->fd
, (struct sockaddr
*) &cnt_addr
, &cnt_len
);
964 #if EWOULDBLOCK != EAGAIN
968 /* we were stopped _before_ we had a connection */
969 case ECONNABORTED
: /* this is a FreeBSD thingy */
970 /* we were stopped _after_ we had a connection */
976 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "accept failed:", strerror(errno
), errno
);
980 if (sock_addr_get_family(&cnt_addr
) != AF_UNIX
) {
981 network_accept_tcp_nagle_disable(cnt
);
983 return connection_accepted(srv
, srv_socket
, &cnt_addr
, cnt
);
988 /* 0: everything ok, -1: error, -2: con closed */
989 static int connection_read_cq(server
*srv
, connection
*con
, chunkqueue
*cq
, off_t max_bytes
) {
993 force_assert(cq
== con
->read_queue
); /*(code transform assumption; minimize diff)*/
994 force_assert(max_bytes
== MAX_READ_LIMIT
); /*(code transform assumption; minimize diff)*/
996 /* check avail data to read and obtain memory into which to read
997 * fill previous chunk if it has sufficient space
998 * (use mem_len=0 to obtain large buffer at least half of chunk_buf_sz)
1002 if (0 == fdevent_ioctl_fionread(con
->fd
, S_IFSOCK
, &frd
)) {
1003 mem_len
= (frd
< MAX_READ_LIMIT
) ? (size_t)frd
: MAX_READ_LIMIT
;
1006 mem
= chunkqueue_get_memory(con
->read_queue
, &mem_len
);
1008 #if defined(__WIN32)
1009 len
= recv(con
->fd
, mem
, mem_len
, 0);
1011 len
= read(con
->fd
, mem
, mem_len
);
1012 #endif /* __WIN32 */
1014 chunkqueue_use_memory(con
->read_queue
, len
> 0 ? len
: 0);
1017 con
->is_readable
= 0;
1019 #if defined(__WIN32)
1021 int lastError
= WSAGetLastError();
1022 switch (lastError
) {
1026 /* we have been interrupted before we could read */
1027 con
->is_readable
= 1;
1030 /* suppress logging for this error, expected for keep-alive */
1033 log_error_write(srv
, __FILE__
, __LINE__
, "sd", "connection closed - recv failed: ", lastError
);
1042 /* we have been interrupted before we could read */
1043 con
->is_readable
= 1;
1046 /* suppress logging for this error, expected for keep-alive */
1049 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "connection closed - read failed: ", strerror(errno
), errno
);
1052 #endif /* __WIN32 */
1054 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1057 } else if (len
== 0) {
1058 con
->is_readable
= 0;
1059 /* the other end close the connection -> KEEP-ALIVE */
1064 } else if (len
!= (ssize_t
) mem_len
) {
1065 /* we got less then expected, wait for the next fd-event */
1067 con
->is_readable
= 0;
1070 con
->bytes_read
+= len
;
1075 static int connection_write_cq(server
*srv
, connection
*con
, chunkqueue
*cq
, off_t max_bytes
) {
1076 return srv
->network_backend_write(srv
, con
->fd
, cq
, max_bytes
);
1080 connection
*connection_accepted(server
*srv
, server_socket
*srv_socket
, sock_addr
*cnt_addr
, int cnt
) {
1085 /* ok, we have the connection, register it */
1087 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
1092 con
= connections_get_new_connection(srv
);
1093 con
->errh
= srv
->errh
;
1096 con
->fdn
= fdevent_register(srv
->ev
, con
->fd
, connection_handle_fdevent
, con
);
1097 con
->network_read
= connection_read_cq
;
1098 con
->network_write
= connection_write_cq
;
1100 connection_set_state(srv
, con
, CON_STATE_REQUEST_START
);
1102 con
->connection_start
= srv
->cur_ts
;
1103 con
->dst_addr
= *cnt_addr
;
1104 buffer_copy_string(con
->dst_addr_buf
, inet_ntop_cache_get_ip(srv
, &(con
->dst_addr
)));
1105 con
->srv_socket
= srv_socket
;
1106 con
->is_ssl_sock
= srv_socket
->is_ssl
;
1108 config_cond_cache_reset(srv
, con
);
1109 con
->conditional_is_valid
[COMP_SERVER_SOCKET
] = 1;
1110 con
->conditional_is_valid
[COMP_HTTP_REMOTE_IP
] = 1;
1112 buffer_copy_string_len(con
->proto
, CONST_STR_LEN("http"));
1113 if (HANDLER_GO_ON
!= plugins_call_handle_connection_accept(srv
, con
)) {
1114 connection_reset(srv
, con
);
1115 connection_close(srv
, con
);
1118 if (con
->http_status
< 0) connection_set_state(srv
, con
, CON_STATE_WRITE
);
1123 static int connection_handle_request(server
*srv
, connection
*con
) {
1124 int r
= http_response_prepare(srv
, con
);
1126 case HANDLER_WAIT_FOR_EVENT
:
1127 if (!con
->file_finished
&& (!con
->file_started
|| 0 == con
->conf
.stream_response_body
)) {
1128 break; /* come back here */
1130 /* response headers received from backend; fall through to start response */
1132 case HANDLER_FINISHED
:
1133 if (con
->http_status
== 0) con
->http_status
= 200;
1134 if (con
->error_handler_saved_status
> 0) {
1135 con
->request
.http_method
= con
->error_handler_saved_method
;
1137 if (con
->mode
== DIRECT
|| con
->conf
.error_intercept
) {
1138 if (con
->error_handler_saved_status
) {
1139 const int subreq_status
= con
->http_status
;
1140 if (con
->error_handler_saved_status
> 0) {
1141 con
->http_status
= con
->error_handler_saved_status
;
1142 } else if (con
->http_status
== 404 || con
->http_status
== 403) {
1143 /* error-handler-404 is a 404 */
1144 con
->http_status
= -con
->error_handler_saved_status
;
1146 /* error-handler-404 is back and has generated content */
1147 /* if Status: was set, take it otherwise use 200 */
1149 if (200 <= subreq_status
&& subreq_status
<= 299) {
1150 /*(flag value to indicate that error handler succeeded)
1151 *(for (con->mode == DIRECT))*/
1152 con
->error_handler_saved_status
= 65535; /* >= 1000 */
1154 } else if (con
->http_status
>= 400) {
1155 buffer
*error_handler
= NULL
;
1156 if (!buffer_string_is_empty(con
->conf
.error_handler
)) {
1157 error_handler
= con
->conf
.error_handler
;
1158 } else if ((con
->http_status
== 404 || con
->http_status
== 403)
1159 && !buffer_string_is_empty(con
->conf
.error_handler_404
)) {
1160 error_handler
= con
->conf
.error_handler_404
;
1163 if (error_handler
) {
1164 /* call error-handler */
1166 /* set REDIRECT_STATUS to save current HTTP status code
1167 * for access by dynamic handlers
1168 * https://redmine.lighttpd.net/issues/1828 */
1169 buffer_copy_int(srv
->tmp_buf
, con
->http_status
);
1170 http_header_env_set(con
, CONST_STR_LEN("REDIRECT_STATUS"), CONST_BUF_LEN(srv
->tmp_buf
));
1172 if (error_handler
== con
->conf
.error_handler
) {
1173 plugins_call_connection_reset(srv
, con
);
1175 if (con
->request
.content_length
) {
1176 if (con
->request
.content_length
!= con
->request_content_queue
->bytes_in
) {
1177 con
->keep_alive
= 0;
1179 con
->request
.content_length
= 0;
1180 chunkqueue_reset(con
->request_content_queue
);
1183 con
->is_writable
= 1;
1184 con
->file_finished
= 0;
1185 con
->file_started
= 0;
1187 con
->error_handler_saved_status
= con
->http_status
;
1188 con
->error_handler_saved_method
= con
->request
.http_method
;
1190 con
->request
.http_method
= HTTP_METHOD_GET
;
1191 } else { /*(preserve behavior for server.error-handler-404)*/
1192 con
->error_handler_saved_status
= -con
->http_status
; /*(negative to flag old behavior)*/
1195 if (con
->request
.http_version
== HTTP_VERSION_UNSET
) con
->request
.http_version
= HTTP_VERSION_1_0
;
1197 buffer_copy_buffer(con
->request
.uri
, error_handler
);
1198 connection_handle_errdoc_init(con
);
1199 con
->http_status
= 0; /*(after connection_handle_errdoc_init())*/
1206 /* we have something to send, go on */
1207 connection_set_state(srv
, con
, CON_STATE_RESPONSE_START
);
1209 case HANDLER_WAIT_FOR_FD
:
1212 fdwaitqueue_append(srv
, con
);
1215 case HANDLER_COMEBACK
:
1218 /* something went wrong */
1219 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1222 log_error_write(srv
, __FILE__
, __LINE__
, "sdd", "unknown ret-value: ", con
->fd
, r
);
1230 int connection_state_machine(server
*srv
, connection
*con
) {
1231 connection_state_t ostate
;
1233 const int log_state_handling
= srv
->srvconf
.log_state_handling
;
1235 if (log_state_handling
) {
1236 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1239 connection_get_state(con
->state
));
1243 if (log_state_handling
) {
1244 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1245 "state for fd", con
->fd
, connection_get_state(con
->state
));
1248 switch ((ostate
= con
->state
)) {
1249 case CON_STATE_REQUEST_START
: /* transient */
1250 con
->request_start
= srv
->cur_ts
;
1251 con
->read_idle_ts
= srv
->cur_ts
;
1252 if (con
->conf
.high_precision_timestamps
)
1253 log_clock_gettime_realtime(&con
->request_start_hp
);
1255 con
->request_count
++;
1256 con
->loops_per_request
= 0;
1258 connection_set_state(srv
, con
, CON_STATE_READ
);
1260 case CON_STATE_READ
:
1261 connection_handle_read_state(srv
, con
);
1262 if (con
->state
!= CON_STATE_REQUEST_END
) break;
1264 case CON_STATE_REQUEST_END
: /* transient */
1265 ostate
= (0 == con
->request
.content_length
)
1266 ? CON_STATE_HANDLE_REQUEST
1267 : CON_STATE_READ_POST
;
1268 connection_set_state(srv
, con
, ostate
);
1270 case CON_STATE_READ_POST
:
1271 case CON_STATE_HANDLE_REQUEST
:
1272 if (connection_handle_request(srv
, con
)) {
1273 /* redo loop; will not match con->state */
1274 ostate
= CON_STATE_CONNECT
;
1278 if (con
->state
== CON_STATE_HANDLE_REQUEST
1279 && ostate
== CON_STATE_READ_POST
) {
1280 ostate
= CON_STATE_HANDLE_REQUEST
;
1283 if (con
->state
!= CON_STATE_RESPONSE_START
) break;
1285 case CON_STATE_RESPONSE_START
: /* transient */
1286 if (-1 == connection_handle_write_prepare(srv
, con
)) {
1287 connection_set_state(srv
, con
, CON_STATE_ERROR
);
1290 connection_set_state(srv
, con
, CON_STATE_WRITE
);
1292 case CON_STATE_WRITE
:
1293 connection_handle_write_state(srv
, con
);
1294 if (con
->state
!= CON_STATE_RESPONSE_END
) break;
1296 case CON_STATE_RESPONSE_END
: /* transient */
1297 case CON_STATE_ERROR
: /* transient */
1298 connection_handle_response_end_state(srv
, con
);
1300 case CON_STATE_CLOSE
:
1301 connection_handle_close_state(srv
, con
);
1303 case CON_STATE_CONNECT
:
1306 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
1307 "unknown state:", con
->fd
, con
->state
);
1310 } while (ostate
!= con
->state
);
1312 if (log_state_handling
) {
1313 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
1316 connection_get_state(con
->state
));
1320 switch(con
->state
) {
1321 case CON_STATE_READ
:
1322 r
= FDEVENT_IN
| FDEVENT_RDHUP
;
1324 case CON_STATE_WRITE
:
1325 /* request write-fdevent only if we really need it
1326 * - if we have data to write
1327 * - if the socket is not writable yet
1329 if (!chunkqueue_is_empty(con
->write_queue
) &&
1330 (con
->is_writable
== 0) &&
1331 (con
->traffic_limit_reached
== 0)) {
1335 case CON_STATE_READ_POST
:
1336 if (con
->conf
.stream_request_body
& FDEVENT_STREAM_REQUEST_POLLIN
) {
1337 r
|= FDEVENT_IN
| FDEVENT_RDHUP
;
1340 case CON_STATE_CLOSE
:
1347 const int events
= fdevent_fdnode_interest(con
->fdn
);
1348 if (con
->is_readable
< 0) {
1349 con
->is_readable
= 0;
1352 if (con
->is_writable
< 0) {
1353 con
->is_writable
= 0;
1356 if (events
& FDEVENT_RDHUP
) {
1360 /* update timestamps when enabling interest in events */
1361 if ((r
& FDEVENT_IN
) && !(events
& FDEVENT_IN
)) {
1362 con
->read_idle_ts
= srv
->cur_ts
;
1364 if ((r
& FDEVENT_OUT
) && !(events
& FDEVENT_OUT
)) {
1365 con
->write_request_ts
= srv
->cur_ts
;
1367 fdevent_fdnode_event_set(srv
->ev
, con
->fdn
, r
);