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>