Annotation of embedaddon/lighttpd/src/connections.c, revision 1.1.1.1
1.1 misho 1: #include "buffer.h"
2: #include "server.h"
3: #include "log.h"
4: #include "connections.h"
5: #include "fdevent.h"
6:
7: #include "request.h"
8: #include "response.h"
9: #include "network.h"
10: #include "http_chunk.h"
11: #include "stat_cache.h"
12: #include "joblist.h"
13:
14: #include "plugin.h"
15:
16: #include "inet_ntop_cache.h"
17:
18: #include <sys/stat.h>
19:
20: #include <stdlib.h>
21: #include <stdio.h>
22: #include <unistd.h>
23: #include <errno.h>
24: #include <string.h>
25: #include <fcntl.h>
26: #include <assert.h>
27:
28: #ifdef USE_OPENSSL
29: # include <openssl/ssl.h>
30: # include <openssl/err.h>
31: #endif
32:
33: #ifdef HAVE_SYS_FILIO_H
34: # include <sys/filio.h>
35: #endif
36:
37: #include "sys-socket.h"
38:
39: typedef struct {
40: PLUGIN_DATA;
41: } plugin_data;
42:
43: static connection *connections_get_new_connection(server *srv) {
44: connections *conns = srv->conns;
45: size_t i;
46:
47: if (conns->size == 0) {
48: conns->size = 128;
49: conns->ptr = NULL;
50: conns->ptr = malloc(sizeof(*conns->ptr) * conns->size);
51: for (i = 0; i < conns->size; i++) {
52: conns->ptr[i] = connection_init(srv);
53: }
54: } else if (conns->size == conns->used) {
55: conns->size += 128;
56: conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
57:
58: for (i = conns->used; i < conns->size; i++) {
59: conns->ptr[i] = connection_init(srv);
60: }
61: }
62:
63: connection_reset(srv, conns->ptr[conns->used]);
64: #if 0
65: fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
66: for (i = 0; i < conns->used + 1; i++) {
67: fprintf(stderr, "%d ", conns->ptr[i]->fd);
68: }
69: fprintf(stderr, "\n");
70: #endif
71:
72: conns->ptr[conns->used]->ndx = conns->used;
73: return conns->ptr[conns->used++];
74: }
75:
76: static int connection_del(server *srv, connection *con) {
77: size_t i;
78: connections *conns = srv->conns;
79: connection *temp;
80:
81: if (con == NULL) return -1;
82:
83: if (-1 == con->ndx) return -1;
84:
85: buffer_reset(con->uri.authority);
86: buffer_reset(con->uri.path);
87: buffer_reset(con->uri.query);
88: buffer_reset(con->request.orig_uri);
89:
90: i = con->ndx;
91:
92: /* not last element */
93:
94: if (i != conns->used - 1) {
95: temp = conns->ptr[i];
96: conns->ptr[i] = conns->ptr[conns->used - 1];
97: conns->ptr[conns->used - 1] = temp;
98:
99: conns->ptr[i]->ndx = i;
100: conns->ptr[conns->used - 1]->ndx = -1;
101: }
102:
103: conns->used--;
104:
105: con->ndx = -1;
106: #if 0
107: fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
108: for (i = 0; i < conns->used; i++) {
109: fprintf(stderr, "%d ", conns->ptr[i]->fd);
110: }
111: fprintf(stderr, "\n");
112: #endif
113: return 0;
114: }
115:
116: int connection_close(server *srv, connection *con) {
117: #ifdef USE_OPENSSL
118: server_socket *srv_sock = con->srv_socket;
119: #endif
120:
121: #ifdef USE_OPENSSL
122: if (srv_sock->is_ssl) {
123: if (con->ssl) SSL_free(con->ssl);
124: con->ssl = NULL;
125: }
126: #endif
127:
128: fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
129: fdevent_unregister(srv->ev, con->fd);
130: #ifdef __WIN32
131: if (closesocket(con->fd)) {
132: log_error_write(srv, __FILE__, __LINE__, "sds",
133: "(warning) close:", con->fd, strerror(errno));
134: }
135: #else
136: if (close(con->fd)) {
137: log_error_write(srv, __FILE__, __LINE__, "sds",
138: "(warning) close:", con->fd, strerror(errno));
139: }
140: #endif
141:
142: srv->cur_fds--;
143: #if 0
144: log_error_write(srv, __FILE__, __LINE__, "sd",
145: "closed()", con->fd);
146: #endif
147:
148: connection_del(srv, con);
149: connection_set_state(srv, con, CON_STATE_CONNECT);
150:
151: return 0;
152: }
153:
154: #if 0
155: static void dump_packet(const unsigned char *data, size_t len) {
156: size_t i, j;
157:
158: if (len == 0) return;
159:
160: for (i = 0; i < len; i++) {
161: if (i % 16 == 0) fprintf(stderr, " ");
162:
163: fprintf(stderr, "%02x ", data[i]);
164:
165: if ((i + 1) % 16 == 0) {
166: fprintf(stderr, " ");
167: for (j = 0; j <= i % 16; j++) {
168: unsigned char c;
169:
170: if (i-15+j >= len) break;
171:
172: c = data[i-15+j];
173:
174: fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
175: }
176:
177: fprintf(stderr, "\n");
178: }
179: }
180:
181: if (len % 16 != 0) {
182: for (j = i % 16; j < 16; j++) {
183: fprintf(stderr, " ");
184: }
185:
186: fprintf(stderr, " ");
187: for (j = i & ~0xf; j < len; j++) {
188: unsigned char c;
189:
190: c = data[j];
191: fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
192: }
193: fprintf(stderr, "\n");
194: }
195: }
196: #endif
197:
198: static int connection_handle_read_ssl(server *srv, connection *con) {
199: #ifdef USE_OPENSSL
200: int r, ssl_err, len, count = 0, read_offset, toread;
201: buffer *b = NULL;
202:
203: if (!con->srv_socket->is_ssl) return -1;
204:
205: ERR_clear_error();
206: do {
207: if (NULL != con->read_queue->last) {
208: b = con->read_queue->last->mem;
209: }
210:
211: if (NULL == b || b->size - b->used < 1024) {
212: b = chunkqueue_get_append_buffer(con->read_queue);
213: len = SSL_pending(con->ssl);
214: if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */
215: buffer_prepare_copy(b, len + 1);
216:
217: /* overwrite everything with 0 */
218: memset(b->ptr, 0, b->size);
219: }
220:
221: read_offset = (b->used > 0) ? b->used - 1 : 0;
222: toread = b->size - 1 - read_offset;
223:
224: len = SSL_read(con->ssl, b->ptr + read_offset, toread);
225:
226: if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
227: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client, killing connection");
228: connection_set_state(srv, con, CON_STATE_ERROR);
229: return -1;
230: }
231:
232: if (len > 0) {
233: if (b->used > 0) b->used--;
234: b->used += len;
235: b->ptr[b->used++] = '\0';
236:
237: con->bytes_read += len;
238:
239: count += len;
240: }
241: } while (len == toread && count < MAX_READ_LIMIT);
242:
243:
244: if (len < 0) {
245: int oerrno = errno;
246: switch ((r = SSL_get_error(con->ssl, len))) {
247: case SSL_ERROR_WANT_READ:
248: case SSL_ERROR_WANT_WRITE:
249: con->is_readable = 0;
250:
251: /* the manual says we have to call SSL_read with the same arguments next time.
252: * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway.
253: */
254:
255: return 0;
256: case SSL_ERROR_SYSCALL:
257: /**
258: * man SSL_get_error()
259: *
260: * SSL_ERROR_SYSCALL
261: * Some I/O error occurred. The OpenSSL error queue may contain more
262: * information on the error. If the error queue is empty (i.e.
263: * ERR_get_error() returns 0), ret can be used to find out more about
264: * the error: If ret == 0, an EOF was observed that violates the
265: * protocol. If ret == -1, the underlying BIO reported an I/O error
266: * (for socket I/O on Unix systems, consult errno for details).
267: *
268: */
269: while((ssl_err = ERR_get_error())) {
270: /* get all errors from the error-queue */
271: log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
272: r, ERR_error_string(ssl_err, NULL));
273: }
274:
275: switch(oerrno) {
276: default:
277: log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
278: len, r, oerrno,
279: strerror(oerrno));
280: break;
281: }
282:
283: break;
284: case SSL_ERROR_ZERO_RETURN:
285: /* clean shutdown on the remote side */
286:
287: if (r == 0) {
288: /* FIXME: later */
289: }
290:
291: /* fall thourgh */
292: default:
293: while((ssl_err = ERR_get_error())) {
294: switch (ERR_GET_REASON(ssl_err)) {
295: case SSL_R_SSL_HANDSHAKE_FAILURE:
296: case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
297: case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
298: case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
299: if (!con->conf.log_ssl_noise) continue;
300: break;
301: default:
302: break;
303: }
304: /* get all errors from the error-queue */
305: log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
306: r, ERR_error_string(ssl_err, NULL));
307: }
308: break;
309: }
310:
311: connection_set_state(srv, con, CON_STATE_ERROR);
312:
313: return -1;
314: } else if (len == 0) {
315: con->is_readable = 0;
316: /* the other end close the connection -> KEEP-ALIVE */
317:
318: return -2;
319: } else {
320: joblist_append(srv, con);
321: }
322:
323: return 0;
324: #else
325: UNUSED(srv);
326: UNUSED(con);
327: return -1;
328: #endif
329: }
330:
331: /* 0: everything ok, -1: error, -2: con closed */
332: static int connection_handle_read(server *srv, connection *con) {
333: int len;
334: buffer *b;
335: int toread, read_offset;
336:
337: if (con->srv_socket->is_ssl) {
338: return connection_handle_read_ssl(srv, con);
339: }
340:
341: b = (NULL != con->read_queue->last) ? con->read_queue->last->mem : NULL;
342:
343: /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
344: * us more than 4kb is available
345: * if FIONREAD doesn't signal a big chunk we fill the previous buffer
346: * if it has >= 1kb free
347: */
348: #if defined(__WIN32)
349: if (NULL == b || b->size - b->used < 1024) {
350: b = chunkqueue_get_append_buffer(con->read_queue);
351: buffer_prepare_copy(b, 4 * 1024);
352: }
353:
354: read_offset = (b->used == 0) ? 0 : b->used - 1;
355: len = recv(con->fd, b->ptr + read_offset, b->size - 1 - read_offset, 0);
356: #else
357: if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
358: if (NULL == b || b->size - b->used < 1024) {
359: b = chunkqueue_get_append_buffer(con->read_queue);
360: buffer_prepare_copy(b, 4 * 1024);
361: }
362: } else {
363: if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
364: b = chunkqueue_get_append_buffer(con->read_queue);
365: buffer_prepare_copy(b, toread + 1);
366: }
367:
368: read_offset = (b->used == 0) ? 0 : b->used - 1;
369: len = read(con->fd, b->ptr + read_offset, b->size - 1 - read_offset);
370: #endif
371:
372: if (len < 0) {
373: con->is_readable = 0;
374:
375: if (errno == EAGAIN) return 0;
376: if (errno == EINTR) {
377: /* we have been interrupted before we could read */
378: con->is_readable = 1;
379: return 0;
380: }
381:
382: if (errno != ECONNRESET) {
383: /* expected for keep-alive */
384: log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
385: }
386:
387: connection_set_state(srv, con, CON_STATE_ERROR);
388:
389: return -1;
390: } else if (len == 0) {
391: con->is_readable = 0;
392: /* the other end close the connection -> KEEP-ALIVE */
393:
394: /* pipelining */
395:
396: return -2;
397: } else if ((size_t)len < b->size - 1) {
398: /* we got less then expected, wait for the next fd-event */
399:
400: con->is_readable = 0;
401: }
402:
403: if (b->used > 0) b->used--;
404: b->used += len;
405: b->ptr[b->used++] = '\0';
406:
407: con->bytes_read += len;
408: #if 0
409: dump_packet(b->ptr, len);
410: #endif
411:
412: return 0;
413: }
414:
415: static int connection_handle_write_prepare(server *srv, connection *con) {
416: if (con->mode == DIRECT) {
417: /* static files */
418: switch(con->request.http_method) {
419: case HTTP_METHOD_GET:
420: case HTTP_METHOD_POST:
421: case HTTP_METHOD_HEAD:
422: break;
423: case HTTP_METHOD_OPTIONS:
424: /*
425: * 400 is coming from the request-parser BEFORE uri.path is set
426: * 403 is from the response handler when noone else catched it
427: *
428: * */
429: if ((!con->http_status || con->http_status == 200) && con->uri.path->used &&
430: con->uri.path->ptr[0] != '*') {
431: response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
432:
433: con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
434: con->parsed_response &= ~HTTP_CONTENT_LENGTH;
435:
436: con->http_status = 200;
437: con->file_finished = 1;
438:
439: chunkqueue_reset(con->write_queue);
440: }
441: break;
442: default:
443: if (0 == con->http_status) {
444: con->http_status = 501;
445: }
446: break;
447: }
448: }
449:
450: if (con->http_status == 0) {
451: con->http_status = 403;
452: }
453:
454: switch(con->http_status) {
455: case 204: /* class: header only */
456: case 205:
457: case 304:
458: /* disable chunked encoding again as we have no body */
459: con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
460: con->parsed_response &= ~HTTP_CONTENT_LENGTH;
461: chunkqueue_reset(con->write_queue);
462:
463: con->file_finished = 1;
464: break;
465: default: /* class: header + body */
466: if (con->mode != DIRECT) break;
467:
468: /* only custom body for 4xx and 5xx */
469: if (con->http_status < 400 || con->http_status >= 600) break;
470:
471: con->file_finished = 0;
472:
473: buffer_reset(con->physical.path);
474:
475: /* try to send static errorfile */
476: if (!buffer_is_empty(con->conf.errorfile_prefix)) {
477: stat_cache_entry *sce = NULL;
478:
479: buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
480: buffer_append_long(con->physical.path, con->http_status);
481: buffer_append_string_len(con->physical.path, CONST_STR_LEN(".html"));
482:
483: if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
484: con->file_finished = 1;
485:
486: http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
487: response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
488: }
489: }
490:
491: if (!con->file_finished) {
492: buffer *b;
493:
494: buffer_reset(con->physical.path);
495:
496: con->file_finished = 1;
497: b = chunkqueue_get_append_buffer(con->write_queue);
498:
499: /* build default error-page */
500: buffer_copy_string_len(b, CONST_STR_LEN(
501: "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
502: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
503: " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
504: "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
505: " <head>\n"
506: " <title>"));
507: buffer_append_long(b, con->http_status);
508: buffer_append_string_len(b, CONST_STR_LEN(" - "));
509: buffer_append_string(b, get_http_status_name(con->http_status));
510:
511: buffer_append_string_len(b, CONST_STR_LEN(
512: "</title>\n"
513: " </head>\n"
514: " <body>\n"
515: " <h1>"));
516: buffer_append_long(b, con->http_status);
517: buffer_append_string_len(b, CONST_STR_LEN(" - "));
518: buffer_append_string(b, get_http_status_name(con->http_status));
519:
520: buffer_append_string_len(b, CONST_STR_LEN("</h1>\n"
521: " </body>\n"
522: "</html>\n"
523: ));
524:
525: response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
526: }
527: break;
528: }
529:
530: if (con->file_finished) {
531: /* we have all the content and chunked encoding is not used, set a content-length */
532:
533: if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) &&
534: (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
535: off_t qlen = chunkqueue_length(con->write_queue);
536:
537: /**
538: * The Content-Length header only can be sent if we have content:
539: * - HEAD doesn't have a content-body (but have a content-length)
540: * - 1xx, 204 and 304 don't have a content-body (RFC 2616 Section 4.3)
541: *
542: * Otherwise generate a Content-Length header as chunked encoding is not
543: * available
544: */
545: if ((con->http_status >= 100 && con->http_status < 200) ||
546: con->http_status == 204 ||
547: con->http_status == 304) {
548: data_string *ds;
549: /* no Content-Body, no Content-Length */
550: if (NULL != (ds = (data_string*) array_get_element(con->response.headers, "Content-Length"))) {
551: buffer_reset(ds->value); /* Headers with empty values are ignored for output */
552: }
553: } else if (qlen > 0 || con->request.http_method != HTTP_METHOD_HEAD) {
554: /* qlen = 0 is important for Redirects (301, ...) as they MAY have
555: * a content. Browsers are waiting for a Content otherwise
556: */
557: buffer_copy_off_t(srv->tmp_buf, qlen);
558:
559: response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
560: }
561: }
562: } else {
563: /**
564: * the file isn't finished yet, but we have all headers
565: *
566: * to get keep-alive we either need:
567: * - Content-Length: ... (HTTP/1.0 and HTTP/1.0) or
568: * - Transfer-Encoding: chunked (HTTP/1.1)
569: */
570:
571: if (((con->parsed_response & HTTP_CONTENT_LENGTH) == 0) &&
572: ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) {
573: con->keep_alive = 0;
574: }
575:
576: /**
577: * if the backend sent a Connection: close, follow the wish
578: *
579: * NOTE: if the backend sent Connection: Keep-Alive, but no Content-Length, we
580: * will close the connection. That's fine. We can always decide the close
581: * the connection
582: *
583: * FIXME: to be nice we should remove the Connection: ...
584: */
585: if (con->parsed_response & HTTP_CONNECTION) {
586: /* a subrequest disable keep-alive although the client wanted it */
587: if (con->keep_alive && !con->response.keep_alive) {
588: con->keep_alive = 0;
589: }
590: }
591: }
592:
593: if (con->request.http_method == HTTP_METHOD_HEAD) {
594: /**
595: * a HEAD request has the same as a GET
596: * without the content
597: */
598: con->file_finished = 1;
599:
600: chunkqueue_reset(con->write_queue);
601: con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
602: }
603:
604: http_response_write_header(srv, con);
605:
606: return 0;
607: }
608:
609: static int connection_handle_write(server *srv, connection *con) {
610: switch(network_write_chunkqueue(srv, con, con->write_queue, MAX_WRITE_LIMIT)) {
611: case 0:
612: con->write_request_ts = srv->cur_ts;
613: if (con->file_finished) {
614: connection_set_state(srv, con, CON_STATE_RESPONSE_END);
615: joblist_append(srv, con);
616: }
617: break;
618: case -1: /* error on our side */
619: log_error_write(srv, __FILE__, __LINE__, "sd",
620: "connection closed: write failed on fd", con->fd);
621: connection_set_state(srv, con, CON_STATE_ERROR);
622: joblist_append(srv, con);
623: break;
624: case -2: /* remote close */
625: connection_set_state(srv, con, CON_STATE_ERROR);
626: joblist_append(srv, con);
627: break;
628: case 1:
629: con->write_request_ts = srv->cur_ts;
630: con->is_writable = 0;
631:
632: /* not finished yet -> WRITE */
633: break;
634: }
635:
636: return 0;
637: }
638:
639:
640:
641: connection *connection_init(server *srv) {
642: connection *con;
643:
644: UNUSED(srv);
645:
646: con = calloc(1, sizeof(*con));
647:
648: con->fd = 0;
649: con->ndx = -1;
650: con->fde_ndx = -1;
651: con->bytes_written = 0;
652: con->bytes_read = 0;
653: con->bytes_header = 0;
654: con->loops_per_request = 0;
655:
656: #define CLEAN(x) \
657: con->x = buffer_init();
658:
659: CLEAN(request.uri);
660: CLEAN(request.request_line);
661: CLEAN(request.request);
662: CLEAN(request.pathinfo);
663:
664: CLEAN(request.orig_uri);
665:
666: CLEAN(uri.scheme);
667: CLEAN(uri.authority);
668: CLEAN(uri.path);
669: CLEAN(uri.path_raw);
670: CLEAN(uri.query);
671:
672: CLEAN(physical.doc_root);
673: CLEAN(physical.path);
674: CLEAN(physical.basedir);
675: CLEAN(physical.rel_path);
676: CLEAN(physical.etag);
677: CLEAN(parse_request);
678:
679: CLEAN(server_name);
680: CLEAN(error_handler);
681: CLEAN(dst_addr_buf);
682: #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
683: CLEAN(tlsext_server_name);
684: #endif
685:
686: #undef CLEAN
687: con->write_queue = chunkqueue_init();
688: con->read_queue = chunkqueue_init();
689: con->request_content_queue = chunkqueue_init();
690: chunkqueue_set_tempdirs(con->request_content_queue, srv->srvconf.upload_tempdirs);
691:
692: con->request.headers = array_init();
693: con->response.headers = array_init();
694: con->environment = array_init();
695:
696: /* init plugin specific connection structures */
697:
698: con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
699:
700: con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
701: config_setup_connection(srv, con);
702:
703: return con;
704: }
705:
706: void connections_free(server *srv) {
707: connections *conns = srv->conns;
708: size_t i;
709:
710: for (i = 0; i < conns->size; i++) {
711: connection *con = conns->ptr[i];
712:
713: connection_reset(srv, con);
714:
715: chunkqueue_free(con->write_queue);
716: chunkqueue_free(con->read_queue);
717: chunkqueue_free(con->request_content_queue);
718: array_free(con->request.headers);
719: array_free(con->response.headers);
720: array_free(con->environment);
721:
722: #define CLEAN(x) \
723: buffer_free(con->x);
724:
725: CLEAN(request.uri);
726: CLEAN(request.request_line);
727: CLEAN(request.request);
728: CLEAN(request.pathinfo);
729:
730: CLEAN(request.orig_uri);
731:
732: CLEAN(uri.scheme);
733: CLEAN(uri.authority);
734: CLEAN(uri.path);
735: CLEAN(uri.path_raw);
736: CLEAN(uri.query);
737:
738: CLEAN(physical.doc_root);
739: CLEAN(physical.path);
740: CLEAN(physical.basedir);
741: CLEAN(physical.etag);
742: CLEAN(physical.rel_path);
743: CLEAN(parse_request);
744:
745: CLEAN(server_name);
746: CLEAN(error_handler);
747: CLEAN(dst_addr_buf);
748: #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
749: CLEAN(tlsext_server_name);
750: #endif
751: #undef CLEAN
752: free(con->plugin_ctx);
753: free(con->cond_cache);
754:
755: free(con);
756: }
757:
758: free(conns->ptr);
759: }
760:
761:
762: int connection_reset(server *srv, connection *con) {
763: size_t i;
764:
765: plugins_call_connection_reset(srv, con);
766:
767: con->is_readable = 1;
768: con->is_writable = 1;
769: con->http_status = 0;
770: con->file_finished = 0;
771: con->file_started = 0;
772: con->got_response = 0;
773:
774: con->parsed_response = 0;
775:
776: con->bytes_written = 0;
777: con->bytes_written_cur_second = 0;
778: con->bytes_read = 0;
779: con->bytes_header = 0;
780: con->loops_per_request = 0;
781:
782: con->request.http_method = HTTP_METHOD_UNSET;
783: con->request.http_version = HTTP_VERSION_UNSET;
784:
785: con->request.http_if_modified_since = NULL;
786: con->request.http_if_none_match = NULL;
787:
788: con->response.keep_alive = 0;
789: con->response.content_length = -1;
790: con->response.transfer_encoding = 0;
791:
792: con->mode = DIRECT;
793:
794: #define CLEAN(x) \
795: if (con->x) buffer_reset(con->x);
796:
797: CLEAN(request.uri);
798: CLEAN(request.request_line);
799: CLEAN(request.pathinfo);
800: CLEAN(request.request);
801:
802: /* CLEAN(request.orig_uri); */
803:
804: CLEAN(uri.scheme);
805: /* CLEAN(uri.authority); */
806: /* CLEAN(uri.path); */
807: CLEAN(uri.path_raw);
808: /* CLEAN(uri.query); */
809:
810: CLEAN(physical.doc_root);
811: CLEAN(physical.path);
812: CLEAN(physical.basedir);
813: CLEAN(physical.rel_path);
814: CLEAN(physical.etag);
815:
816: CLEAN(parse_request);
817:
818: CLEAN(server_name);
819: CLEAN(error_handler);
820: #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
821: CLEAN(tlsext_server_name);
822: #endif
823: #undef CLEAN
824:
825: #define CLEAN(x) \
826: if (con->x) con->x->used = 0;
827:
828: #undef CLEAN
829:
830: #define CLEAN(x) \
831: con->request.x = NULL;
832:
833: CLEAN(http_host);
834: CLEAN(http_range);
835: CLEAN(http_content_type);
836: #undef CLEAN
837: con->request.content_length = 0;
838:
839: array_reset(con->request.headers);
840: array_reset(con->response.headers);
841: array_reset(con->environment);
842:
843: chunkqueue_reset(con->write_queue);
844: chunkqueue_reset(con->request_content_queue);
845:
846: /* the plugins should cleanup themself */
847: for (i = 0; i < srv->plugins.used; i++) {
848: plugin *p = ((plugin **)(srv->plugins.ptr))[i];
849: plugin_data *pd = p->data;
850:
851: if (!pd) continue;
852:
853: if (con->plugin_ctx[pd->id] != NULL) {
854: log_error_write(srv, __FILE__, __LINE__, "sb", "missing cleanup in", p->name);
855: }
856:
857: con->plugin_ctx[pd->id] = NULL;
858: }
859:
860: /* The cond_cache gets reset in response.c */
861: /* config_cond_cache_reset(srv, con); */
862:
863: con->header_len = 0;
864: con->in_error_handler = 0;
865:
866: config_setup_connection(srv, con);
867:
868: return 0;
869: }
870:
871: /**
872: * handle all header and content read
873: *
874: * we get called by the state-engine and by the fdevent-handler
875: */
876: static int connection_handle_read_state(server *srv, connection *con) {
877: connection_state_t ostate = con->state;
878: chunk *c, *last_chunk;
879: off_t last_offset;
880: chunkqueue *cq = con->read_queue;
881: chunkqueue *dst_cq = con->request_content_queue;
882: int is_closed = 0; /* the connection got closed, if we don't have a complete header, -> error */
883:
884: if (con->is_readable) {
885: con->read_idle_ts = srv->cur_ts;
886:
887: switch(connection_handle_read(srv, con)) {
888: case -1:
889: return -1;
890: case -2:
891: is_closed = 1;
892: break;
893: default:
894: break;
895: }
896: }
897:
898: /* the last chunk might be empty */
899: for (c = cq->first; c;) {
900: if (cq->first == c && c->mem->used == 0) {
901: /* the first node is empty */
902: /* ... and it is empty, move it to unused */
903:
904: cq->first = c->next;
905: if (cq->first == NULL) cq->last = NULL;
906:
907: c->next = cq->unused;
908: cq->unused = c;
909: cq->unused_chunks++;
910:
911: c = cq->first;
912: } else if (c->next && c->next->mem->used == 0) {
913: chunk *fc;
914: /* next node is the last one */
915: /* ... and it is empty, move it to unused */
916:
917: fc = c->next;
918: c->next = fc->next;
919:
920: fc->next = cq->unused;
921: cq->unused = fc;
922: cq->unused_chunks++;
923:
924: /* the last node was empty */
925: if (c->next == NULL) {
926: cq->last = c;
927: }
928:
929: c = c->next;
930: } else {
931: c = c->next;
932: }
933: }
934:
935: /* we might have got several packets at once
936: */
937:
938: switch(ostate) {
939: case CON_STATE_READ:
940: /* if there is a \r\n\r\n in the chunkqueue
941: *
942: * scan the chunk-queue twice
943: * 1. to find the \r\n\r\n
944: * 2. to copy the header-packet
945: *
946: */
947:
948: last_chunk = NULL;
949: last_offset = 0;
950:
951: for (c = cq->first; c; c = c->next) {
952: buffer b;
953: size_t i;
954:
955: b.ptr = c->mem->ptr + c->offset;
956: b.used = c->mem->used - c->offset;
957: if (b.used > 0) b.used--; /* buffer "used" includes terminating zero */
958:
959: for (i = 0; i < b.used; i++) {
960: char ch = b.ptr[i];
961:
962: if ('\r' == ch) {
963: /* chec if \n\r\n follows */
964: size_t j = i+1;
965: chunk *cc = c;
966: const char header_end[] = "\r\n\r\n";
967: int header_end_match_pos = 1;
968:
969: for ( ; cc; cc = cc->next, j = 0 ) {
970: buffer bb;
971: bb.ptr = cc->mem->ptr + cc->offset;
972: bb.used = cc->mem->used - cc->offset;
973: if (bb.used > 0) bb.used--; /* buffer "used" includes terminating zero */
974:
975: for ( ; j < bb.used; j++) {
976: ch = bb.ptr[j];
977:
978: if (ch == header_end[header_end_match_pos]) {
979: header_end_match_pos++;
980: if (4 == header_end_match_pos) {
981: last_chunk = cc;
982: last_offset = j+1;
983: goto found_header_end;
984: }
985: } else {
986: goto reset_search;
987: }
988: }
989: }
990: }
991: reset_search: ;
992: }
993: }
994: found_header_end:
995:
996: /* found */
997: if (last_chunk) {
998: buffer_reset(con->request.request);
999:
1000: for (c = cq->first; c; c = c->next) {
1001: buffer b;
1002:
1003: b.ptr = c->mem->ptr + c->offset;
1004: b.used = c->mem->used - c->offset;
1005:
1006: if (c == last_chunk) {
1007: b.used = last_offset + 1;
1008: }
1009:
1010: buffer_append_string_buffer(con->request.request, &b);
1011:
1012: if (c == last_chunk) {
1013: c->offset += last_offset;
1014:
1015: break;
1016: } else {
1017: /* the whole packet was copied */
1018: c->offset = c->mem->used - 1;
1019: }
1020: }
1021:
1022: connection_set_state(srv, con, CON_STATE_REQUEST_END);
1023: } else if (chunkqueue_length(cq) > 64 * 1024) {
1024: log_error_write(srv, __FILE__, __LINE__, "s", "oversized request-header -> sending Status 414");
1025:
1026: con->http_status = 414; /* Request-URI too large */
1027: con->keep_alive = 0;
1028: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1029: }
1030: break;
1031: case CON_STATE_READ_POST:
1032: for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) {
1033: off_t weWant, weHave, toRead;
1034:
1035: weWant = con->request.content_length - dst_cq->bytes_in;
1036:
1037: assert(c->mem->used);
1038:
1039: weHave = c->mem->used - c->offset - 1;
1040:
1041: toRead = weHave > weWant ? weWant : weHave;
1042:
1043: /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
1044: if (con->request.content_length > 64 * 1024) {
1045: chunk *dst_c = NULL;
1046: /* copy everything to max 1Mb sized tempfiles */
1047:
1048: /*
1049: * if the last chunk is
1050: * - smaller than 1Mb (size < 1Mb)
1051: * - not read yet (offset == 0)
1052: * -> append to it
1053: * otherwise
1054: * -> create a new chunk
1055: *
1056: * */
1057:
1058: if (dst_cq->last &&
1059: dst_cq->last->type == FILE_CHUNK &&
1060: dst_cq->last->file.is_temp &&
1061: dst_cq->last->offset == 0) {
1062: /* ok, take the last chunk for our job */
1063:
1064: if (dst_cq->last->file.length < 1 * 1024 * 1024) {
1065: dst_c = dst_cq->last;
1066:
1067: if (dst_c->file.fd == -1) {
1068: /* this should not happen as we cache the fd, but you never know */
1069: dst_c->file.fd = open(dst_c->file.name->ptr, O_WRONLY | O_APPEND);
1070: #ifdef FD_CLOEXEC
1071: fcntl(dst_c->file.fd, F_SETFD, FD_CLOEXEC);
1072: #endif
1073: }
1074: } else {
1075: /* the chunk is too large now, close it */
1076: dst_c = dst_cq->last;
1077:
1078: if (dst_c->file.fd != -1) {
1079: close(dst_c->file.fd);
1080: dst_c->file.fd = -1;
1081: }
1082: dst_c = chunkqueue_get_append_tempfile(dst_cq);
1083: }
1084: } else {
1085: dst_c = chunkqueue_get_append_tempfile(dst_cq);
1086: }
1087:
1088: /* we have a chunk, let's write to it */
1089:
1090: if (dst_c->file.fd == -1) {
1091: /* we don't have file to write to,
1092: * EACCES might be one reason.
1093: *
1094: * Instead of sending 500 we send 413 and say the request is too large
1095: * */
1096:
1097: log_error_write(srv, __FILE__, __LINE__, "sbs",
1098: "denying upload as opening to temp-file for upload failed:",
1099: dst_c->file.name, strerror(errno));
1100:
1101: con->http_status = 413; /* Request-Entity too large */
1102: con->keep_alive = 0;
1103: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1104:
1105: break;
1106: }
1107:
1108: if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
1109: /* write failed for some reason ... disk full ? */
1110: log_error_write(srv, __FILE__, __LINE__, "sbs",
1111: "denying upload as writing to file failed:",
1112: dst_c->file.name, strerror(errno));
1113:
1114: con->http_status = 413; /* Request-Entity too large */
1115: con->keep_alive = 0;
1116: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1117:
1118: close(dst_c->file.fd);
1119: dst_c->file.fd = -1;
1120:
1121: break;
1122: }
1123:
1124: dst_c->file.length += toRead;
1125:
1126: if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
1127: /* we read everything, close the chunk */
1128: close(dst_c->file.fd);
1129: dst_c->file.fd = -1;
1130: }
1131: } else {
1132: buffer *b;
1133:
1134: if (dst_cq->last &&
1135: dst_cq->last->type == MEM_CHUNK) {
1136: b = dst_cq->last->mem;
1137: } else {
1138: b = chunkqueue_get_append_buffer(dst_cq);
1139: /* prepare buffer size for remaining POST data; is < 64kb */
1140: buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1);
1141: }
1142: buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
1143: }
1144:
1145: c->offset += toRead;
1146: dst_cq->bytes_in += toRead;
1147: }
1148:
1149: /* Content is ready */
1150: if (dst_cq->bytes_in == (off_t)con->request.content_length) {
1151: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1152: }
1153:
1154: break;
1155: default: break;
1156: }
1157:
1158: /* the connection got closed and we didn't got enough data to leave one of the READ states
1159: * the only way is to leave here */
1160: if (is_closed && ostate == con->state) {
1161: connection_set_state(srv, con, CON_STATE_ERROR);
1162: }
1163:
1164: chunkqueue_remove_finished_chunks(cq);
1165:
1166: return 0;
1167: }
1168:
1169: static handler_t connection_handle_fdevent(server *srv, void *context, int revents) {
1170: connection *con = context;
1171:
1172: joblist_append(srv, con);
1173:
1174: if (con->srv_socket->is_ssl) {
1175: /* ssl may read and write for both reads and writes */
1176: if (revents & (FDEVENT_IN | FDEVENT_OUT)) {
1177: con->is_readable = 1;
1178: con->is_writable = 1;
1179: }
1180: } else {
1181: if (revents & FDEVENT_IN) {
1182: con->is_readable = 1;
1183: }
1184: if (revents & FDEVENT_OUT) {
1185: con->is_writable = 1;
1186: /* we don't need the event twice */
1187: }
1188: }
1189:
1190:
1191: if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) {
1192: /* looks like an error */
1193:
1194: /* FIXME: revents = 0x19 still means that we should read from the queue */
1195: if (revents & FDEVENT_HUP) {
1196: if (con->state == CON_STATE_CLOSE) {
1197: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1198: } else {
1199: /* sigio reports the wrong event here
1200: *
1201: * there was no HUP at all
1202: */
1203: #ifdef USE_LINUX_SIGIO
1204: if (srv->ev->in_sigio == 1) {
1205: log_error_write(srv, __FILE__, __LINE__, "sd",
1206: "connection closed: poll() -> HUP", con->fd);
1207: } else {
1208: connection_set_state(srv, con, CON_STATE_ERROR);
1209: }
1210: #else
1211: connection_set_state(srv, con, CON_STATE_ERROR);
1212: #endif
1213:
1214: }
1215: } else if (revents & FDEVENT_ERR) {
1216: /* error, connection reset, whatever... we don't want to spam the logfile */
1217: #if 0
1218: log_error_write(srv, __FILE__, __LINE__, "sd",
1219: "connection closed: poll() -> ERR", con->fd);
1220: #endif
1221: connection_set_state(srv, con, CON_STATE_ERROR);
1222: } else {
1223: log_error_write(srv, __FILE__, __LINE__, "sd",
1224: "connection closed: poll() -> ???", revents);
1225: }
1226: }
1227:
1228: if (con->state == CON_STATE_READ ||
1229: con->state == CON_STATE_READ_POST) {
1230: connection_handle_read_state(srv, con);
1231: }
1232:
1233: if (con->state == CON_STATE_WRITE &&
1234: !chunkqueue_is_empty(con->write_queue) &&
1235: con->is_writable) {
1236:
1237: if (-1 == connection_handle_write(srv, con)) {
1238: connection_set_state(srv, con, CON_STATE_ERROR);
1239:
1240: log_error_write(srv, __FILE__, __LINE__, "ds",
1241: con->fd,
1242: "handle write failed.");
1243: }
1244: }
1245:
1246: if (con->state == CON_STATE_CLOSE) {
1247: /* flush the read buffers */
1248: int len;
1249: char buf[1024];
1250:
1251: len = read(con->fd, buf, sizeof(buf));
1252: if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
1253: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1254: }
1255: }
1256:
1257: return HANDLER_FINISHED;
1258: }
1259:
1260:
1261: connection *connection_accept(server *srv, server_socket *srv_socket) {
1262: /* accept everything */
1263:
1264: /* search an empty place */
1265: int cnt;
1266: sock_addr cnt_addr;
1267: socklen_t cnt_len;
1268: /* accept it and register the fd */
1269:
1270: /**
1271: * check if we can still open a new connections
1272: *
1273: * see #1216
1274: */
1275:
1276: if (srv->conns->used >= srv->max_conns) {
1277: return NULL;
1278: }
1279:
1280: cnt_len = sizeof(cnt_addr);
1281:
1282: if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
1283: switch (errno) {
1284: case EAGAIN:
1285: #if EWOULDBLOCK != EAGAIN
1286: case EWOULDBLOCK:
1287: #endif
1288: case EINTR:
1289: /* we were stopped _before_ we had a connection */
1290: case ECONNABORTED: /* this is a FreeBSD thingy */
1291: /* we were stopped _after_ we had a connection */
1292: break;
1293: case EMFILE:
1294: /* out of fds */
1295: break;
1296: default:
1297: log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
1298: }
1299: return NULL;
1300: } else {
1301: connection *con;
1302:
1303: srv->cur_fds++;
1304:
1305: /* ok, we have the connection, register it */
1306: #if 0
1307: log_error_write(srv, __FILE__, __LINE__, "sd",
1308: "appected()", cnt);
1309: #endif
1310: srv->con_opened++;
1311:
1312: con = connections_get_new_connection(srv);
1313:
1314: con->fd = cnt;
1315: con->fde_ndx = -1;
1316: #if 0
1317: gettimeofday(&(con->start_tv), NULL);
1318: #endif
1319: fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
1320:
1321: connection_set_state(srv, con, CON_STATE_REQUEST_START);
1322:
1323: con->connection_start = srv->cur_ts;
1324: con->dst_addr = cnt_addr;
1325: buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
1326: con->srv_socket = srv_socket;
1327:
1328: if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
1329: log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
1330: return NULL;
1331: }
1332: #ifdef USE_OPENSSL
1333: /* connect FD to SSL */
1334: if (srv_socket->is_ssl) {
1335: if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
1336: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1337: ERR_error_string(ERR_get_error(), NULL));
1338:
1339: return NULL;
1340: }
1341:
1342: con->renegotiations = 0;
1343: SSL_set_app_data(con->ssl, con);
1344: SSL_set_accept_state(con->ssl);
1345:
1346: if (1 != (SSL_set_fd(con->ssl, cnt))) {
1347: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1348: ERR_error_string(ERR_get_error(), NULL));
1349: return NULL;
1350: }
1351: }
1352: #endif
1353: return con;
1354: }
1355: }
1356:
1357:
1358: int connection_state_machine(server *srv, connection *con) {
1359: int done = 0, r;
1360: #ifdef USE_OPENSSL
1361: server_socket *srv_sock = con->srv_socket;
1362: #endif
1363:
1364: if (srv->srvconf.log_state_handling) {
1365: log_error_write(srv, __FILE__, __LINE__, "sds",
1366: "state at start",
1367: con->fd,
1368: connection_get_state(con->state));
1369: }
1370:
1371: while (done == 0) {
1372: size_t ostate = con->state;
1373:
1374: switch (con->state) {
1375: case CON_STATE_REQUEST_START: /* transient */
1376: if (srv->srvconf.log_state_handling) {
1377: log_error_write(srv, __FILE__, __LINE__, "sds",
1378: "state for fd", con->fd, connection_get_state(con->state));
1379: }
1380:
1381: con->request_start = srv->cur_ts;
1382: con->read_idle_ts = srv->cur_ts;
1383:
1384: con->request_count++;
1385: con->loops_per_request = 0;
1386:
1387: connection_set_state(srv, con, CON_STATE_READ);
1388:
1389: break;
1390: case CON_STATE_REQUEST_END: /* transient */
1391: if (srv->srvconf.log_state_handling) {
1392: log_error_write(srv, __FILE__, __LINE__, "sds",
1393: "state for fd", con->fd, connection_get_state(con->state));
1394: }
1395:
1396: buffer_reset(con->uri.authority);
1397: buffer_reset(con->uri.path);
1398: buffer_reset(con->uri.query);
1399: buffer_reset(con->request.orig_uri);
1400:
1401: if (http_request_parse(srv, con)) {
1402: /* we have to read some data from the POST request */
1403:
1404: connection_set_state(srv, con, CON_STATE_READ_POST);
1405:
1406: break;
1407: }
1408:
1409: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1410:
1411: break;
1412: case CON_STATE_HANDLE_REQUEST:
1413: /*
1414: * the request is parsed
1415: *
1416: * decided what to do with the request
1417: * -
1418: *
1419: *
1420: */
1421:
1422: if (srv->srvconf.log_state_handling) {
1423: log_error_write(srv, __FILE__, __LINE__, "sds",
1424: "state for fd", con->fd, connection_get_state(con->state));
1425: }
1426:
1427: switch (r = http_response_prepare(srv, con)) {
1428: case HANDLER_FINISHED:
1429: if (con->mode == DIRECT) {
1430: if (con->http_status == 404 ||
1431: con->http_status == 403) {
1432: /* 404 error-handler */
1433:
1434: if (con->in_error_handler == 0 &&
1435: (!buffer_is_empty(con->conf.error_handler) ||
1436: !buffer_is_empty(con->error_handler))) {
1437: /* call error-handler */
1438:
1439: con->error_handler_saved_status = con->http_status;
1440: con->http_status = 0;
1441:
1442: if (buffer_is_empty(con->error_handler)) {
1443: buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
1444: } else {
1445: buffer_copy_string_buffer(con->request.uri, con->error_handler);
1446: }
1447: buffer_reset(con->physical.path);
1448:
1449: con->in_error_handler = 1;
1450:
1451: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1452:
1453: done = -1;
1454: break;
1455: } else if (con->in_error_handler) {
1456: /* error-handler is a 404 */
1457:
1458: con->http_status = con->error_handler_saved_status;
1459: }
1460: } else if (con->in_error_handler) {
1461: /* error-handler is back and has generated content */
1462: /* if Status: was set, take it otherwise use 200 */
1463: }
1464: }
1465: if (con->http_status == 0) con->http_status = 200;
1466:
1467: /* we have something to send, go on */
1468: connection_set_state(srv, con, CON_STATE_RESPONSE_START);
1469: break;
1470: case HANDLER_WAIT_FOR_FD:
1471: srv->want_fds++;
1472:
1473: fdwaitqueue_append(srv, con);
1474:
1475: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1476:
1477: break;
1478: case HANDLER_COMEBACK:
1479: done = -1;
1480: case HANDLER_WAIT_FOR_EVENT:
1481: /* come back here */
1482: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1483:
1484: break;
1485: case HANDLER_ERROR:
1486: /* something went wrong */
1487: connection_set_state(srv, con, CON_STATE_ERROR);
1488: break;
1489: default:
1490: log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
1491: break;
1492: }
1493:
1494: break;
1495: case CON_STATE_RESPONSE_START:
1496: /*
1497: * the decision is done
1498: * - create the HTTP-Response-Header
1499: *
1500: */
1501:
1502: if (srv->srvconf.log_state_handling) {
1503: log_error_write(srv, __FILE__, __LINE__, "sds",
1504: "state for fd", con->fd, connection_get_state(con->state));
1505: }
1506:
1507: if (-1 == connection_handle_write_prepare(srv, con)) {
1508: connection_set_state(srv, con, CON_STATE_ERROR);
1509:
1510: break;
1511: }
1512:
1513: connection_set_state(srv, con, CON_STATE_WRITE);
1514: break;
1515: case CON_STATE_RESPONSE_END: /* transient */
1516: /* log the request */
1517:
1518: if (srv->srvconf.log_state_handling) {
1519: log_error_write(srv, __FILE__, __LINE__, "sds",
1520: "state for fd", con->fd, connection_get_state(con->state));
1521: }
1522:
1523: plugins_call_handle_request_done(srv, con);
1524:
1525: srv->con_written++;
1526:
1527: if (con->keep_alive) {
1528: connection_set_state(srv, con, CON_STATE_REQUEST_START);
1529:
1530: #if 0
1531: con->request_start = srv->cur_ts;
1532: con->read_idle_ts = srv->cur_ts;
1533: #endif
1534: } else {
1535: switch(r = plugins_call_handle_connection_close(srv, con)) {
1536: case HANDLER_GO_ON:
1537: case HANDLER_FINISHED:
1538: break;
1539: default:
1540: log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
1541: break;
1542: }
1543:
1544: #ifdef USE_OPENSSL
1545: if (srv_sock->is_ssl) {
1546: switch (SSL_shutdown(con->ssl)) {
1547: case 1:
1548: /* done */
1549: break;
1550: case 0:
1551: /* wait for fd-event
1552: *
1553: * FIXME: wait for fdevent and call SSL_shutdown again
1554: *
1555: */
1556:
1557: break;
1558: default:
1559: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1560: ERR_error_string(ERR_get_error(), NULL));
1561: }
1562: }
1563: #endif
1564: if ((0 == shutdown(con->fd, SHUT_WR))) {
1565: con->close_timeout_ts = srv->cur_ts;
1566: connection_set_state(srv, con, CON_STATE_CLOSE);
1567: } else {
1568: connection_close(srv, con);
1569: }
1570:
1571: srv->con_closed++;
1572: }
1573:
1574: connection_reset(srv, con);
1575:
1576: break;
1577: case CON_STATE_CONNECT:
1578: if (srv->srvconf.log_state_handling) {
1579: log_error_write(srv, __FILE__, __LINE__, "sds",
1580: "state for fd", con->fd, connection_get_state(con->state));
1581: }
1582:
1583: chunkqueue_reset(con->read_queue);
1584:
1585: con->request_count = 0;
1586:
1587: break;
1588: case CON_STATE_CLOSE:
1589: if (srv->srvconf.log_state_handling) {
1590: log_error_write(srv, __FILE__, __LINE__, "sds",
1591: "state for fd", con->fd, connection_get_state(con->state));
1592: }
1593:
1594: /* we have to do the linger_on_close stuff regardless
1595: * of con->keep_alive; even non-keepalive sockets may
1596: * still have unread data, and closing before reading
1597: * it will make the client not see all our output.
1598: */
1599: {
1600: int len;
1601: char buf[1024];
1602:
1603: len = read(con->fd, buf, sizeof(buf));
1604: if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
1605: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1606: }
1607: }
1608:
1609: if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
1610: connection_close(srv, con);
1611:
1612: if (srv->srvconf.log_state_handling) {
1613: log_error_write(srv, __FILE__, __LINE__, "sd",
1614: "connection closed for fd", con->fd);
1615: }
1616: }
1617:
1618: break;
1619: case CON_STATE_READ_POST:
1620: case CON_STATE_READ:
1621: if (srv->srvconf.log_state_handling) {
1622: log_error_write(srv, __FILE__, __LINE__, "sds",
1623: "state for fd", con->fd, connection_get_state(con->state));
1624: }
1625:
1626: connection_handle_read_state(srv, con);
1627: break;
1628: case CON_STATE_WRITE:
1629: if (srv->srvconf.log_state_handling) {
1630: log_error_write(srv, __FILE__, __LINE__, "sds",
1631: "state for fd", con->fd, connection_get_state(con->state));
1632: }
1633:
1634: /* only try to write if we have something in the queue */
1635: if (!chunkqueue_is_empty(con->write_queue)) {
1636: #if 0
1637: log_error_write(srv, __FILE__, __LINE__, "dsd",
1638: con->fd,
1639: "packets to write:",
1640: con->write_queue->used);
1641: #endif
1642: }
1643: if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) {
1644: if (-1 == connection_handle_write(srv, con)) {
1645: log_error_write(srv, __FILE__, __LINE__, "ds",
1646: con->fd,
1647: "handle write failed.");
1648: connection_set_state(srv, con, CON_STATE_ERROR);
1649: }
1650: }
1651:
1652: break;
1653: case CON_STATE_ERROR: /* transient */
1654:
1655: /* even if the connection was drop we still have to write it to the access log */
1656: if (con->http_status) {
1657: plugins_call_handle_request_done(srv, con);
1658: }
1659: #ifdef USE_OPENSSL
1660: if (srv_sock->is_ssl) {
1661: int ret, ssl_r;
1662: unsigned long err;
1663: ERR_clear_error();
1664: switch ((ret = SSL_shutdown(con->ssl))) {
1665: case 1:
1666: /* ok */
1667: break;
1668: case 0:
1669: ERR_clear_error();
1670: if (-1 != (ret = SSL_shutdown(con->ssl))) break;
1671:
1672: /* fall through */
1673: default:
1674:
1675: switch ((ssl_r = SSL_get_error(con->ssl, ret))) {
1676: case SSL_ERROR_WANT_WRITE:
1677: case SSL_ERROR_WANT_READ:
1678: break;
1679: case SSL_ERROR_SYSCALL:
1680: /* perhaps we have error waiting in our error-queue */
1681: if (0 != (err = ERR_get_error())) {
1682: do {
1683: log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
1684: ssl_r, ret,
1685: ERR_error_string(err, NULL));
1686: } while((err = ERR_get_error()));
1687: } else if (errno != 0) { /* ssl bug (see lighttpd ticket #2213): sometimes errno == 0 */
1688: switch(errno) {
1689: case EPIPE:
1690: case ECONNRESET:
1691: break;
1692: default:
1693: log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
1694: ssl_r, ret, errno,
1695: strerror(errno));
1696: break;
1697: }
1698: }
1699:
1700: break;
1701: default:
1702: while((err = ERR_get_error())) {
1703: log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
1704: ssl_r, ret,
1705: ERR_error_string(err, NULL));
1706: }
1707:
1708: break;
1709: }
1710: }
1711: ERR_clear_error();
1712: }
1713: #endif
1714:
1715: switch(con->mode) {
1716: case DIRECT:
1717: #if 0
1718: log_error_write(srv, __FILE__, __LINE__, "sd",
1719: "emergency exit: direct",
1720: con->fd);
1721: #endif
1722: break;
1723: default:
1724: switch(r = plugins_call_handle_connection_close(srv, con)) {
1725: case HANDLER_GO_ON:
1726: case HANDLER_FINISHED:
1727: break;
1728: default:
1729: log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
1730: break;
1731: }
1732: break;
1733: }
1734:
1735: connection_reset(srv, con);
1736:
1737: /* close the connection */
1738: if ((0 == shutdown(con->fd, SHUT_WR))) {
1739: con->close_timeout_ts = srv->cur_ts;
1740: connection_set_state(srv, con, CON_STATE_CLOSE);
1741:
1742: if (srv->srvconf.log_state_handling) {
1743: log_error_write(srv, __FILE__, __LINE__, "sd",
1744: "shutdown for fd", con->fd);
1745: }
1746: } else {
1747: connection_close(srv, con);
1748: }
1749:
1750: con->keep_alive = 0;
1751:
1752: srv->con_closed++;
1753:
1754: break;
1755: default:
1756: log_error_write(srv, __FILE__, __LINE__, "sdd",
1757: "unknown state:", con->fd, con->state);
1758:
1759: break;
1760: }
1761:
1762: if (done == -1) {
1763: done = 0;
1764: } else if (ostate == con->state) {
1765: done = 1;
1766: }
1767: }
1768:
1769: if (srv->srvconf.log_state_handling) {
1770: log_error_write(srv, __FILE__, __LINE__, "sds",
1771: "state at exit:",
1772: con->fd,
1773: connection_get_state(con->state));
1774: }
1775:
1776: switch(con->state) {
1777: case CON_STATE_READ_POST:
1778: case CON_STATE_READ:
1779: case CON_STATE_CLOSE:
1780: fdevent_event_set(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
1781: break;
1782: case CON_STATE_WRITE:
1783: /* request write-fdevent only if we really need it
1784: * - if we have data to write
1785: * - if the socket is not writable yet
1786: */
1787: if (!chunkqueue_is_empty(con->write_queue) &&
1788: (con->is_writable == 0) &&
1789: (con->traffic_limit_reached == 0)) {
1790: fdevent_event_set(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
1791: } else {
1792: fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
1793: }
1794: break;
1795: default:
1796: fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
1797: break;
1798: }
1799:
1800: return 0;
1801: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>