Annotation of embedaddon/lighttpd/src/connections.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 1037: force_assert(c->mem->used);
1.1 misho 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);
1.1.1.2 ! misho 1070: fd_close_on_exec(dst_c->file.fd);
1.1 misho 1071: }
1072: } else {
1073: /* the chunk is too large now, close it */
1074: dst_c = dst_cq->last;
1075:
1076: if (dst_c->file.fd != -1) {
1077: close(dst_c->file.fd);
1078: dst_c->file.fd = -1;
1079: }
1080: dst_c = chunkqueue_get_append_tempfile(dst_cq);
1081: }
1082: } else {
1083: dst_c = chunkqueue_get_append_tempfile(dst_cq);
1084: }
1085:
1086: /* we have a chunk, let's write to it */
1087:
1088: if (dst_c->file.fd == -1) {
1089: /* we don't have file to write to,
1090: * EACCES might be one reason.
1091: *
1092: * Instead of sending 500 we send 413 and say the request is too large
1093: * */
1094:
1095: log_error_write(srv, __FILE__, __LINE__, "sbs",
1096: "denying upload as opening to temp-file for upload failed:",
1097: dst_c->file.name, strerror(errno));
1098:
1099: con->http_status = 413; /* Request-Entity too large */
1100: con->keep_alive = 0;
1101: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1102:
1103: break;
1104: }
1105:
1106: if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
1107: /* write failed for some reason ... disk full ? */
1108: log_error_write(srv, __FILE__, __LINE__, "sbs",
1109: "denying upload as writing to file failed:",
1110: dst_c->file.name, strerror(errno));
1111:
1112: con->http_status = 413; /* Request-Entity too large */
1113: con->keep_alive = 0;
1114: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1115:
1116: close(dst_c->file.fd);
1117: dst_c->file.fd = -1;
1118:
1119: break;
1120: }
1121:
1122: dst_c->file.length += toRead;
1123:
1124: if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
1125: /* we read everything, close the chunk */
1126: close(dst_c->file.fd);
1127: dst_c->file.fd = -1;
1128: }
1129: } else {
1130: buffer *b;
1131:
1132: if (dst_cq->last &&
1133: dst_cq->last->type == MEM_CHUNK) {
1134: b = dst_cq->last->mem;
1135: } else {
1136: b = chunkqueue_get_append_buffer(dst_cq);
1137: /* prepare buffer size for remaining POST data; is < 64kb */
1138: buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1);
1139: }
1140: buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
1141: }
1142:
1143: c->offset += toRead;
1144: dst_cq->bytes_in += toRead;
1145: }
1146:
1147: /* Content is ready */
1148: if (dst_cq->bytes_in == (off_t)con->request.content_length) {
1149: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1150: }
1151:
1152: break;
1153: default: break;
1154: }
1155:
1156: /* the connection got closed and we didn't got enough data to leave one of the READ states
1157: * the only way is to leave here */
1158: if (is_closed && ostate == con->state) {
1159: connection_set_state(srv, con, CON_STATE_ERROR);
1160: }
1161:
1162: chunkqueue_remove_finished_chunks(cq);
1163:
1164: return 0;
1165: }
1166:
1167: static handler_t connection_handle_fdevent(server *srv, void *context, int revents) {
1168: connection *con = context;
1169:
1170: joblist_append(srv, con);
1171:
1172: if (con->srv_socket->is_ssl) {
1173: /* ssl may read and write for both reads and writes */
1174: if (revents & (FDEVENT_IN | FDEVENT_OUT)) {
1175: con->is_readable = 1;
1176: con->is_writable = 1;
1177: }
1178: } else {
1179: if (revents & FDEVENT_IN) {
1180: con->is_readable = 1;
1181: }
1182: if (revents & FDEVENT_OUT) {
1183: con->is_writable = 1;
1184: /* we don't need the event twice */
1185: }
1186: }
1187:
1188:
1189: if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) {
1190: /* looks like an error */
1191:
1192: /* FIXME: revents = 0x19 still means that we should read from the queue */
1193: if (revents & FDEVENT_HUP) {
1194: if (con->state == CON_STATE_CLOSE) {
1195: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1196: } else {
1197: /* sigio reports the wrong event here
1198: *
1199: * there was no HUP at all
1200: */
1201: #ifdef USE_LINUX_SIGIO
1202: if (srv->ev->in_sigio == 1) {
1203: log_error_write(srv, __FILE__, __LINE__, "sd",
1204: "connection closed: poll() -> HUP", con->fd);
1205: } else {
1206: connection_set_state(srv, con, CON_STATE_ERROR);
1207: }
1208: #else
1209: connection_set_state(srv, con, CON_STATE_ERROR);
1210: #endif
1211:
1212: }
1213: } else if (revents & FDEVENT_ERR) {
1214: /* error, connection reset, whatever... we don't want to spam the logfile */
1215: #if 0
1216: log_error_write(srv, __FILE__, __LINE__, "sd",
1217: "connection closed: poll() -> ERR", con->fd);
1218: #endif
1219: connection_set_state(srv, con, CON_STATE_ERROR);
1220: } else {
1221: log_error_write(srv, __FILE__, __LINE__, "sd",
1222: "connection closed: poll() -> ???", revents);
1223: }
1224: }
1225:
1226: if (con->state == CON_STATE_READ ||
1227: con->state == CON_STATE_READ_POST) {
1228: connection_handle_read_state(srv, con);
1229: }
1230:
1231: if (con->state == CON_STATE_WRITE &&
1232: !chunkqueue_is_empty(con->write_queue) &&
1233: con->is_writable) {
1234:
1235: if (-1 == connection_handle_write(srv, con)) {
1236: connection_set_state(srv, con, CON_STATE_ERROR);
1237:
1238: log_error_write(srv, __FILE__, __LINE__, "ds",
1239: con->fd,
1240: "handle write failed.");
1241: }
1242: }
1243:
1244: if (con->state == CON_STATE_CLOSE) {
1245: /* flush the read buffers */
1246: int len;
1247: char buf[1024];
1248:
1249: len = read(con->fd, buf, sizeof(buf));
1250: if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
1251: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1252: }
1253: }
1254:
1255: return HANDLER_FINISHED;
1256: }
1257:
1258:
1259: connection *connection_accept(server *srv, server_socket *srv_socket) {
1260: /* accept everything */
1261:
1262: /* search an empty place */
1263: int cnt;
1264: sock_addr cnt_addr;
1265: socklen_t cnt_len;
1266: /* accept it and register the fd */
1267:
1268: /**
1269: * check if we can still open a new connections
1270: *
1271: * see #1216
1272: */
1273:
1274: if (srv->conns->used >= srv->max_conns) {
1275: return NULL;
1276: }
1277:
1278: cnt_len = sizeof(cnt_addr);
1279:
1280: if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
1281: switch (errno) {
1282: case EAGAIN:
1283: #if EWOULDBLOCK != EAGAIN
1284: case EWOULDBLOCK:
1285: #endif
1286: case EINTR:
1287: /* we were stopped _before_ we had a connection */
1288: case ECONNABORTED: /* this is a FreeBSD thingy */
1289: /* we were stopped _after_ we had a connection */
1290: break;
1291: case EMFILE:
1292: /* out of fds */
1293: break;
1294: default:
1295: log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
1296: }
1297: return NULL;
1298: } else {
1299: connection *con;
1300:
1301: srv->cur_fds++;
1302:
1303: /* ok, we have the connection, register it */
1304: #if 0
1305: log_error_write(srv, __FILE__, __LINE__, "sd",
1306: "appected()", cnt);
1307: #endif
1308: srv->con_opened++;
1309:
1310: con = connections_get_new_connection(srv);
1311:
1312: con->fd = cnt;
1313: con->fde_ndx = -1;
1314: #if 0
1315: gettimeofday(&(con->start_tv), NULL);
1316: #endif
1317: fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
1318:
1319: connection_set_state(srv, con, CON_STATE_REQUEST_START);
1320:
1321: con->connection_start = srv->cur_ts;
1322: con->dst_addr = cnt_addr;
1323: buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
1324: con->srv_socket = srv_socket;
1325:
1326: if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
1327: log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
1328: return NULL;
1329: }
1330: #ifdef USE_OPENSSL
1331: /* connect FD to SSL */
1332: if (srv_socket->is_ssl) {
1333: if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
1334: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1335: ERR_error_string(ERR_get_error(), NULL));
1336:
1337: return NULL;
1338: }
1339:
1340: con->renegotiations = 0;
1341: SSL_set_app_data(con->ssl, con);
1342: SSL_set_accept_state(con->ssl);
1343:
1344: if (1 != (SSL_set_fd(con->ssl, cnt))) {
1345: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1346: ERR_error_string(ERR_get_error(), NULL));
1347: return NULL;
1348: }
1349: }
1350: #endif
1351: return con;
1352: }
1353: }
1354:
1355:
1356: int connection_state_machine(server *srv, connection *con) {
1357: int done = 0, r;
1358: #ifdef USE_OPENSSL
1359: server_socket *srv_sock = con->srv_socket;
1360: #endif
1361:
1362: if (srv->srvconf.log_state_handling) {
1363: log_error_write(srv, __FILE__, __LINE__, "sds",
1364: "state at start",
1365: con->fd,
1366: connection_get_state(con->state));
1367: }
1368:
1369: while (done == 0) {
1370: size_t ostate = con->state;
1371:
1372: switch (con->state) {
1373: case CON_STATE_REQUEST_START: /* transient */
1374: if (srv->srvconf.log_state_handling) {
1375: log_error_write(srv, __FILE__, __LINE__, "sds",
1376: "state for fd", con->fd, connection_get_state(con->state));
1377: }
1378:
1379: con->request_start = srv->cur_ts;
1380: con->read_idle_ts = srv->cur_ts;
1381:
1382: con->request_count++;
1383: con->loops_per_request = 0;
1384:
1385: connection_set_state(srv, con, CON_STATE_READ);
1386:
1387: break;
1388: case CON_STATE_REQUEST_END: /* transient */
1389: if (srv->srvconf.log_state_handling) {
1390: log_error_write(srv, __FILE__, __LINE__, "sds",
1391: "state for fd", con->fd, connection_get_state(con->state));
1392: }
1393:
1394: buffer_reset(con->uri.authority);
1395: buffer_reset(con->uri.path);
1396: buffer_reset(con->uri.query);
1397: buffer_reset(con->request.orig_uri);
1398:
1399: if (http_request_parse(srv, con)) {
1400: /* we have to read some data from the POST request */
1401:
1402: connection_set_state(srv, con, CON_STATE_READ_POST);
1403:
1404: break;
1405: }
1406:
1407: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1408:
1409: break;
1410: case CON_STATE_HANDLE_REQUEST:
1411: /*
1412: * the request is parsed
1413: *
1414: * decided what to do with the request
1415: * -
1416: *
1417: *
1418: */
1419:
1420: if (srv->srvconf.log_state_handling) {
1421: log_error_write(srv, __FILE__, __LINE__, "sds",
1422: "state for fd", con->fd, connection_get_state(con->state));
1423: }
1424:
1425: switch (r = http_response_prepare(srv, con)) {
1426: case HANDLER_FINISHED:
1427: if (con->mode == DIRECT) {
1428: if (con->http_status == 404 ||
1429: con->http_status == 403) {
1430: /* 404 error-handler */
1431:
1432: if (con->in_error_handler == 0 &&
1433: (!buffer_is_empty(con->conf.error_handler) ||
1434: !buffer_is_empty(con->error_handler))) {
1435: /* call error-handler */
1436:
1437: con->error_handler_saved_status = con->http_status;
1438: con->http_status = 0;
1439:
1440: if (buffer_is_empty(con->error_handler)) {
1441: buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
1442: } else {
1443: buffer_copy_string_buffer(con->request.uri, con->error_handler);
1444: }
1445: buffer_reset(con->physical.path);
1446:
1447: con->in_error_handler = 1;
1448:
1449: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1450:
1451: done = -1;
1452: break;
1453: } else if (con->in_error_handler) {
1454: /* error-handler is a 404 */
1455:
1456: con->http_status = con->error_handler_saved_status;
1457: }
1458: } else if (con->in_error_handler) {
1459: /* error-handler is back and has generated content */
1460: /* if Status: was set, take it otherwise use 200 */
1461: }
1462: }
1463: if (con->http_status == 0) con->http_status = 200;
1464:
1465: /* we have something to send, go on */
1466: connection_set_state(srv, con, CON_STATE_RESPONSE_START);
1467: break;
1468: case HANDLER_WAIT_FOR_FD:
1469: srv->want_fds++;
1470:
1471: fdwaitqueue_append(srv, con);
1472:
1473: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1474:
1475: break;
1476: case HANDLER_COMEBACK:
1477: done = -1;
1.1.1.2 ! misho 1478: /* fallthrough */
1.1 misho 1479: case HANDLER_WAIT_FOR_EVENT:
1480: /* come back here */
1481: connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1482:
1483: break;
1484: case HANDLER_ERROR:
1485: /* something went wrong */
1486: connection_set_state(srv, con, CON_STATE_ERROR);
1487: break;
1488: default:
1489: log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
1490: break;
1491: }
1492:
1493: break;
1494: case CON_STATE_RESPONSE_START:
1495: /*
1496: * the decision is done
1497: * - create the HTTP-Response-Header
1498: *
1499: */
1500:
1501: if (srv->srvconf.log_state_handling) {
1502: log_error_write(srv, __FILE__, __LINE__, "sds",
1503: "state for fd", con->fd, connection_get_state(con->state));
1504: }
1505:
1506: if (-1 == connection_handle_write_prepare(srv, con)) {
1507: connection_set_state(srv, con, CON_STATE_ERROR);
1508:
1509: break;
1510: }
1511:
1512: connection_set_state(srv, con, CON_STATE_WRITE);
1513: break;
1514: case CON_STATE_RESPONSE_END: /* transient */
1515: /* log the request */
1516:
1517: if (srv->srvconf.log_state_handling) {
1518: log_error_write(srv, __FILE__, __LINE__, "sds",
1519: "state for fd", con->fd, connection_get_state(con->state));
1520: }
1521:
1522: plugins_call_handle_request_done(srv, con);
1523:
1524: srv->con_written++;
1525:
1526: if (con->keep_alive) {
1527: connection_set_state(srv, con, CON_STATE_REQUEST_START);
1528:
1529: #if 0
1530: con->request_start = srv->cur_ts;
1531: con->read_idle_ts = srv->cur_ts;
1532: #endif
1533: } else {
1534: switch(r = plugins_call_handle_connection_close(srv, con)) {
1535: case HANDLER_GO_ON:
1536: case HANDLER_FINISHED:
1537: break;
1538: default:
1539: log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
1540: break;
1541: }
1542:
1543: #ifdef USE_OPENSSL
1544: if (srv_sock->is_ssl) {
1545: switch (SSL_shutdown(con->ssl)) {
1546: case 1:
1547: /* done */
1548: break;
1549: case 0:
1550: /* wait for fd-event
1551: *
1552: * FIXME: wait for fdevent and call SSL_shutdown again
1553: *
1554: */
1555:
1556: break;
1557: default:
1558: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
1559: ERR_error_string(ERR_get_error(), NULL));
1560: }
1561: }
1562: #endif
1563: if ((0 == shutdown(con->fd, SHUT_WR))) {
1564: con->close_timeout_ts = srv->cur_ts;
1565: connection_set_state(srv, con, CON_STATE_CLOSE);
1566: } else {
1567: connection_close(srv, con);
1568: }
1569:
1570: srv->con_closed++;
1571: }
1572:
1573: connection_reset(srv, con);
1574:
1575: break;
1576: case CON_STATE_CONNECT:
1577: if (srv->srvconf.log_state_handling) {
1578: log_error_write(srv, __FILE__, __LINE__, "sds",
1579: "state for fd", con->fd, connection_get_state(con->state));
1580: }
1581:
1582: chunkqueue_reset(con->read_queue);
1583:
1584: con->request_count = 0;
1585:
1586: break;
1587: case CON_STATE_CLOSE:
1588: if (srv->srvconf.log_state_handling) {
1589: log_error_write(srv, __FILE__, __LINE__, "sds",
1590: "state for fd", con->fd, connection_get_state(con->state));
1591: }
1592:
1593: /* we have to do the linger_on_close stuff regardless
1594: * of con->keep_alive; even non-keepalive sockets may
1595: * still have unread data, and closing before reading
1596: * it will make the client not see all our output.
1597: */
1598: {
1599: int len;
1600: char buf[1024];
1601:
1602: len = read(con->fd, buf, sizeof(buf));
1603: if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
1604: con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
1605: }
1606: }
1607:
1608: if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
1609: connection_close(srv, con);
1610:
1611: if (srv->srvconf.log_state_handling) {
1612: log_error_write(srv, __FILE__, __LINE__, "sd",
1613: "connection closed for fd", con->fd);
1614: }
1615: }
1616:
1617: break;
1618: case CON_STATE_READ_POST:
1619: case CON_STATE_READ:
1620: if (srv->srvconf.log_state_handling) {
1621: log_error_write(srv, __FILE__, __LINE__, "sds",
1622: "state for fd", con->fd, connection_get_state(con->state));
1623: }
1624:
1625: connection_handle_read_state(srv, con);
1626: break;
1627: case CON_STATE_WRITE:
1628: if (srv->srvconf.log_state_handling) {
1629: log_error_write(srv, __FILE__, __LINE__, "sds",
1630: "state for fd", con->fd, connection_get_state(con->state));
1631: }
1632:
1633: /* only try to write if we have something in the queue */
1634: if (!chunkqueue_is_empty(con->write_queue)) {
1635: #if 0
1636: log_error_write(srv, __FILE__, __LINE__, "dsd",
1637: con->fd,
1638: "packets to write:",
1639: con->write_queue->used);
1640: #endif
1641: }
1642: if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) {
1643: if (-1 == connection_handle_write(srv, con)) {
1644: log_error_write(srv, __FILE__, __LINE__, "ds",
1645: con->fd,
1646: "handle write failed.");
1647: connection_set_state(srv, con, CON_STATE_ERROR);
1648: }
1649: }
1650:
1651: break;
1652: case CON_STATE_ERROR: /* transient */
1653:
1654: /* even if the connection was drop we still have to write it to the access log */
1655: if (con->http_status) {
1656: plugins_call_handle_request_done(srv, con);
1657: }
1658: #ifdef USE_OPENSSL
1659: if (srv_sock->is_ssl) {
1660: int ret, ssl_r;
1661: unsigned long err;
1662: ERR_clear_error();
1663: switch ((ret = SSL_shutdown(con->ssl))) {
1664: case 1:
1665: /* ok */
1666: break;
1667: case 0:
1668: ERR_clear_error();
1669: if (-1 != (ret = SSL_shutdown(con->ssl))) break;
1670:
1671: /* fall through */
1672: default:
1673:
1674: switch ((ssl_r = SSL_get_error(con->ssl, ret))) {
1675: case SSL_ERROR_WANT_WRITE:
1676: case SSL_ERROR_WANT_READ:
1677: break;
1678: case SSL_ERROR_SYSCALL:
1679: /* perhaps we have error waiting in our error-queue */
1680: if (0 != (err = ERR_get_error())) {
1681: do {
1682: log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
1683: ssl_r, ret,
1684: ERR_error_string(err, NULL));
1685: } while((err = ERR_get_error()));
1686: } else if (errno != 0) { /* ssl bug (see lighttpd ticket #2213): sometimes errno == 0 */
1687: switch(errno) {
1688: case EPIPE:
1689: case ECONNRESET:
1690: break;
1691: default:
1692: log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
1693: ssl_r, ret, errno,
1694: strerror(errno));
1695: break;
1696: }
1697: }
1698:
1699: break;
1700: default:
1701: while((err = ERR_get_error())) {
1702: log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
1703: ssl_r, ret,
1704: ERR_error_string(err, NULL));
1705: }
1706:
1707: break;
1708: }
1709: }
1710: ERR_clear_error();
1711: }
1712: #endif
1713:
1714: switch(con->mode) {
1715: case DIRECT:
1716: #if 0
1717: log_error_write(srv, __FILE__, __LINE__, "sd",
1718: "emergency exit: direct",
1719: con->fd);
1720: #endif
1721: break;
1722: default:
1723: switch(r = plugins_call_handle_connection_close(srv, con)) {
1724: case HANDLER_GO_ON:
1725: case HANDLER_FINISHED:
1726: break;
1727: default:
1728: log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
1729: break;
1730: }
1731: break;
1732: }
1733:
1734: connection_reset(srv, con);
1735:
1736: /* close the connection */
1737: if ((0 == shutdown(con->fd, SHUT_WR))) {
1738: con->close_timeout_ts = srv->cur_ts;
1739: connection_set_state(srv, con, CON_STATE_CLOSE);
1740:
1741: if (srv->srvconf.log_state_handling) {
1742: log_error_write(srv, __FILE__, __LINE__, "sd",
1743: "shutdown for fd", con->fd);
1744: }
1745: } else {
1746: connection_close(srv, con);
1747: }
1748:
1749: con->keep_alive = 0;
1750:
1751: srv->con_closed++;
1752:
1753: break;
1754: default:
1755: log_error_write(srv, __FILE__, __LINE__, "sdd",
1756: "unknown state:", con->fd, con->state);
1757:
1758: break;
1759: }
1760:
1761: if (done == -1) {
1762: done = 0;
1763: } else if (ostate == con->state) {
1764: done = 1;
1765: }
1766: }
1767:
1768: if (srv->srvconf.log_state_handling) {
1769: log_error_write(srv, __FILE__, __LINE__, "sds",
1770: "state at exit:",
1771: con->fd,
1772: connection_get_state(con->state));
1773: }
1774:
1775: switch(con->state) {
1776: case CON_STATE_READ_POST:
1777: case CON_STATE_READ:
1778: case CON_STATE_CLOSE:
1779: fdevent_event_set(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
1780: break;
1781: case CON_STATE_WRITE:
1782: /* request write-fdevent only if we really need it
1783: * - if we have data to write
1784: * - if the socket is not writable yet
1785: */
1786: if (!chunkqueue_is_empty(con->write_queue) &&
1787: (con->is_writable == 0) &&
1788: (con->traffic_limit_reached == 0)) {
1789: fdevent_event_set(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
1790: } else {
1791: fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
1792: }
1793: break;
1794: default:
1795: fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
1796: break;
1797: }
1798:
1799: return 0;
1800: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>