~ubuntu-branches/ubuntu/saucy/lighttpd/saucy

« back to all changes in this revision

Viewing changes to .pc/silence-errors.diff/src/connections.c

  • Committer: Package Import Robot
  • Author(s): Lorenzo De Liso
  • Date: 2012-12-06 17:54:59 UTC
  • mfrom: (6.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20121206175459-aq6vz5xa9fa202jw
Tags: 1.4.31-3ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: libgamin-dev rather than libfam-dev to fix startup warning.
  - debian/index.html: s/Debian/Ubuntu/g branding on the default page.
  - Added a UFW profile set:
    + debian/lighttpd.dirs: added etc/ufw/applications.d
    + debian/rules: install the ufw profile.
    + debian/control: Suggests on ufw.
  - Add lighttpd-dev package:
    + debian/control: Added lighttpd-dev package; Build-depends on
      automake, libtool
    + debian/lighttpd-dev.install: Added.
  - debian/rules: Add override_dh_installinit to set "defaults 91 09" to not
    start before apache2 but in the same runlevel with the same priority.
  - debian/patches/build-dev-package.patch: Updated
  - debian/lighttpd.conf: Comment 'use-ipv6.pl' by default, which causes
    failure to bind port in ipv4
* debian/index.html: corrected BTS Ubuntu link for lighttpd

Show diffs side-by-side

added added

removed removed

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