]> granicus.if.org Git - apache/blob - server/core_filters.c
enabled building gen_test_char for running on build when cross-compiling;
[apache] / server / core_filters.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file  core_filters.c
19  * @brief Core input/output network filters.
20  */
21
22 #include "apr.h"
23 #include "apr_strings.h"
24 #include "apr_lib.h"
25 #include "apr_fnmatch.h"
26 #include "apr_hash.h"
27 #include "apr_thread_proc.h"    /* for RLIMIT stuff */
28 #include "apr_hooks.h"
29
30 #define APR_WANT_IOVEC
31 #define APR_WANT_STRFUNC
32 #define APR_WANT_MEMFUNC
33 #include "apr_want.h"
34
35 #include "ap_config.h"
36 #include "httpd.h"
37 #include "http_config.h"
38 #include "http_core.h"
39 #include "http_protocol.h" /* For index_of_response().  Grump. */
40 #include "http_request.h"
41 #include "http_vhost.h"
42 #include "http_main.h"     /* For the default_handler below... */
43 #include "http_log.h"
44 #include "util_md5.h"
45 #include "http_connection.h"
46 #include "apr_buckets.h"
47 #include "util_filter.h"
48 #include "util_ebcdic.h"
49 #include "mpm_common.h"
50 #include "scoreboard.h"
51 #include "mod_core.h"
52 #include "mod_proxy.h"
53 #include "ap_listen.h"
54
55 #include "mod_so.h" /* for ap_find_loaded_module_symbol */
56
57 #define AP_MIN_SENDFILE_BYTES           (256)
58
59 /**
60  * Remove all zero length buckets from the brigade.
61  */
62 #define BRIGADE_NORMALIZE(b) \
63 do { \
64     apr_bucket *e = APR_BRIGADE_FIRST(b); \
65     do {  \
66         if (e->length == 0 && !APR_BUCKET_IS_METADATA(e)) { \
67             apr_bucket *d; \
68             d = APR_BUCKET_NEXT(e); \
69             apr_bucket_delete(e); \
70             e = d; \
71         } \
72         else { \
73             e = APR_BUCKET_NEXT(e); \
74         } \
75     } while (!APR_BRIGADE_EMPTY(b) && (e != APR_BRIGADE_SENTINEL(b))); \
76 } while (0)
77
78
79 /**
80  * Split the contents of a brigade after bucket 'e' to an existing brigade
81  *
82  * XXXX: Should this function be added to APR-Util?
83  */
84 static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a,
85                          apr_bucket *e)
86 {
87     apr_bucket *f;
88
89     if (e != APR_BRIGADE_SENTINEL(b)) {
90         f = APR_RING_LAST(&b->list);
91         APR_RING_UNSPLICE(e, f, link);
92         APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
93     }
94
95     APR_BRIGADE_CHECK_CONSISTENCY(a);
96     APR_BRIGADE_CHECK_CONSISTENCY(b);
97 }
98
99 int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
100                          ap_input_mode_t mode, apr_read_type_e block,
101                          apr_off_t readbytes)
102 {
103     apr_bucket *e;
104     apr_status_t rv;
105     core_net_rec *net = f->ctx;
106     core_ctx_t *ctx = net->in_ctx;
107     const char *str;
108     apr_size_t len;
109
110     if (mode == AP_MODE_INIT) {
111         /*
112          * this mode is for filters that might need to 'initialize'
113          * a connection before reading request data from a client.
114          * NNTP over SSL for example needs to handshake before the
115          * server sends the welcome message.
116          * such filters would have changed the mode before this point
117          * is reached.  however, protocol modules such as NNTP should
118          * not need to know anything about SSL.  given the example, if
119          * SSL is not in the filter chain, AP_MODE_INIT is a noop.
120          */
121         return APR_SUCCESS;
122     }
123
124     if (!ctx)
125     {
126         ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
127         ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
128         ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc);
129         /* seed the brigade with the client socket. */
130         e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
131         APR_BRIGADE_INSERT_TAIL(ctx->b, e);
132         net->in_ctx = ctx;
133     }
134     else if (APR_BRIGADE_EMPTY(ctx->b)) {
135         return APR_EOF;
136     }
137
138     /* ### This is bad. */
139     BRIGADE_NORMALIZE(ctx->b);
140
141     /* check for empty brigade again *AFTER* BRIGADE_NORMALIZE()
142      * If we have lost our socket bucket (see above), we are EOF.
143      *
144      * Ideally, this should be returning SUCCESS with EOS bucket, but
145      * some higher-up APIs (spec. read_request_line via ap_rgetline)
146      * want an error code. */
147     if (APR_BRIGADE_EMPTY(ctx->b)) {
148         return APR_EOF;
149     }
150
151     if (mode == AP_MODE_GETLINE) {
152         /* we are reading a single LF line, e.g. the HTTP headers */
153         rv = apr_brigade_split_line(b, ctx->b, block, HUGE_STRING_LEN);
154         /* We should treat EAGAIN here the same as we do for EOF (brigade is
155          * empty).  We do this by returning whatever we have read.  This may
156          * or may not be bogus, but is consistent (for now) with EOF logic.
157          */
158         if (APR_STATUS_IS_EAGAIN(rv)) {
159             rv = APR_SUCCESS;
160         }
161         return rv;
162     }
163
164     /* ### AP_MODE_PEEK is a horrific name for this mode because we also
165      * eat any CRLFs that we see.  That's not the obvious intention of
166      * this mode.  Determine whether anyone actually uses this or not. */
167     if (mode == AP_MODE_EATCRLF) {
168         apr_bucket *e;
169         const char *c;
170
171         /* The purpose of this loop is to ignore any CRLF (or LF) at the end
172          * of a request.  Many browsers send extra lines at the end of POST
173          * requests.  We use the PEEK method to determine if there is more
174          * data on the socket, so that we know if we should delay sending the
175          * end of one request until we have served the second request in a
176          * pipelined situation.  We don't want to actually delay sending a
177          * response if the server finds a CRLF (or LF), becuause that doesn't
178          * mean that there is another request, just a blank line.
179          */
180         while (1) {
181             if (APR_BRIGADE_EMPTY(ctx->b))
182                 return APR_EOF;
183
184             e = APR_BRIGADE_FIRST(ctx->b);
185
186             rv = apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);
187
188             if (rv != APR_SUCCESS)
189                 return rv;
190
191             c = str;
192             while (c < str + len) {
193                 if (*c == APR_ASCII_LF)
194                     c++;
195                 else if (*c == APR_ASCII_CR && *(c + 1) == APR_ASCII_LF)
196                     c += 2;
197                 else
198                     return APR_SUCCESS;
199             }
200
201             /* If we reach here, we were a bucket just full of CRLFs, so
202              * just toss the bucket. */
203             /* FIXME: Is this the right thing to do in the core? */
204             apr_bucket_delete(e);
205         }
206         return APR_SUCCESS;
207     }
208
209     /* If mode is EXHAUSTIVE, we want to just read everything until the end
210      * of the brigade, which in this case means the end of the socket.
211      * To do this, we attach the brigade that has currently been setaside to
212      * the brigade that was passed down, and send that brigade back.
213      *
214      * NOTE:  This is VERY dangerous to use, and should only be done with
215      * extreme caution.  FWLIW, this would be needed by an MPM like Perchild;
216      * such an MPM can easily request the socket and all data that has been
217      * read, which means that it can pass it to the correct child process.
218      */
219     if (mode == AP_MODE_EXHAUSTIVE) {
220         apr_bucket *e;
221
222         /* Tack on any buckets that were set aside. */
223         APR_BRIGADE_CONCAT(b, ctx->b);
224
225         /* Since we've just added all potential buckets (which will most
226          * likely simply be the socket bucket) we know this is the end,
227          * so tack on an EOS too. */
228         /* We have read until the brigade was empty, so we know that we
229          * must be EOS. */
230         e = apr_bucket_eos_create(f->c->bucket_alloc);
231         APR_BRIGADE_INSERT_TAIL(b, e);
232         return APR_SUCCESS;
233     }
234
235     /* read up to the amount they specified. */
236     if (mode == AP_MODE_READBYTES || mode == AP_MODE_SPECULATIVE) {
237         apr_bucket *e;
238
239         AP_DEBUG_ASSERT(readbytes > 0);
240
241         e = APR_BRIGADE_FIRST(ctx->b);
242         rv = apr_bucket_read(e, &str, &len, block);
243
244         if (APR_STATUS_IS_EAGAIN(rv)) {
245             return APR_SUCCESS;
246         }
247         else if (rv != APR_SUCCESS) {
248             return rv;
249         }
250         else if (block == APR_BLOCK_READ && len == 0) {
251             /* We wanted to read some bytes in blocking mode.  We read
252              * 0 bytes.  Hence, we now assume we are EOS.
253              *
254              * When we are in normal mode, return an EOS bucket to the
255              * caller.
256              * When we are in speculative mode, leave ctx->b empty, so
257              * that the next call returns an EOS bucket.
258              */
259             apr_bucket_delete(e);
260
261             if (mode == AP_MODE_READBYTES) {
262                 e = apr_bucket_eos_create(f->c->bucket_alloc);
263                 APR_BRIGADE_INSERT_TAIL(b, e);
264             }
265             return APR_SUCCESS;
266         }
267
268         /* Have we read as much data as we wanted (be greedy)? */
269         if (len < readbytes) {
270             apr_size_t bucket_len;
271
272             rv = APR_SUCCESS;
273             /* We already registered the data in e in len */
274             e = APR_BUCKET_NEXT(e);
275             while ((len < readbytes) && (rv == APR_SUCCESS)
276                    && (e != APR_BRIGADE_SENTINEL(ctx->b))) {
277                 /* Check for the availability of buckets with known length */
278                 if (e->length != -1) {
279                     len += e->length;
280                     e = APR_BUCKET_NEXT(e);
281                 }
282                 else {
283                     /*
284                      * Read from bucket, but non blocking. If there isn't any
285                      * more data, well than this is fine as well, we will
286                      * not wait for more since we already got some and we are
287                      * only checking if there isn't more.
288                      */
289                     rv = apr_bucket_read(e, &str, &bucket_len,
290                                          APR_NONBLOCK_READ);
291                     if (rv == APR_SUCCESS) {
292                         len += bucket_len;
293                         e = APR_BUCKET_NEXT(e);
294                     }
295                 }
296             }
297         }
298
299         /* We can only return at most what we read. */
300         if (len < readbytes) {
301             readbytes = len;
302         }
303
304         rv = apr_brigade_partition(ctx->b, readbytes, &e);
305         if (rv != APR_SUCCESS) {
306             return rv;
307         }
308
309         /* Must do move before CONCAT */
310         brigade_move(ctx->b, ctx->tmpbb, e);
311
312         if (mode == AP_MODE_READBYTES) {
313             APR_BRIGADE_CONCAT(b, ctx->b);
314         }
315         else if (mode == AP_MODE_SPECULATIVE) {
316             apr_bucket *copy_bucket;
317
318             for (e = APR_BRIGADE_FIRST(ctx->b);
319                  e != APR_BRIGADE_SENTINEL(ctx->b);
320                  e = APR_BUCKET_NEXT(e))
321             {
322                 rv = apr_bucket_copy(e, &copy_bucket);
323                 if (rv != APR_SUCCESS) {
324                     return rv;
325                 }
326                 APR_BRIGADE_INSERT_TAIL(b, copy_bucket);
327             }
328         }
329
330         /* Take what was originally there and place it back on ctx->b */
331         APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb);
332     }
333     return APR_SUCCESS;
334 }
335
336 static void setaside_remaining_output(ap_filter_t *f,
337                                       core_output_filter_ctx_t *ctx,
338                                       apr_bucket_brigade *bb,
339                                       int make_a_copy, conn_rec *c);
340
341 static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
342                                              apr_bucket_brigade *bb,
343                                              apr_size_t *bytes_written,
344                                              conn_rec *c);
345
346 static void remove_empty_buckets(apr_bucket_brigade *bb);
347
348 static apr_status_t send_brigade_blocking(apr_socket_t *s,
349                                           apr_bucket_brigade *bb,
350                                           apr_size_t *bytes_written,
351                                           conn_rec *c);
352
353 static apr_status_t writev_nonblocking(apr_socket_t *s,
354                                        struct iovec *vec, apr_size_t nvec,
355                                        apr_bucket_brigade *bb,
356                                        apr_size_t *cumulative_bytes_written,
357                                        conn_rec *c);
358
359 #if APR_HAS_SENDFILE
360 static apr_status_t sendfile_nonblocking(apr_socket_t *s,
361                                          apr_bucket *bucket,
362                                          apr_size_t *cumulative_bytes_written,
363                                          conn_rec *c);
364 #endif
365
366 #define THRESHOLD_MIN_WRITE 4096
367 #define THRESHOLD_MAX_BUFFER 65536
368
369 /* Optional function coming from mod_logio, used for logging of output
370  * traffic
371  */
372 extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *ap__logio_add_bytes_out;
373
374 apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
375 {
376     conn_rec *c = f->c;
377     core_net_rec *net = f->ctx;
378     core_output_filter_ctx_t *ctx = net->out_ctx;
379     apr_bucket_brigade *bb;
380     apr_bucket *bucket, *next;
381     apr_size_t bytes_in_brigade, non_file_bytes_in_brigade;
382
383     /* Fail quickly if the connection has already been aborted. */
384     if (c->aborted) {
385         if (new_bb != NULL) {
386             apr_brigade_cleanup(new_bb);
387         }
388         return APR_ECONNABORTED;
389     }
390
391     if (ctx == NULL) {
392         apr_status_t rv;
393         ctx = apr_pcalloc(c->pool, sizeof(*ctx));
394         net->out_ctx = (core_output_filter_ctx_t *)ctx;
395         rv = apr_socket_opt_set(net->client_socket, APR_SO_NONBLOCK, 1);
396         if (rv != APR_SUCCESS) {
397             return rv;
398         }
399     }
400
401     if (new_bb != NULL) {
402         for (bucket = APR_BRIGADE_FIRST(new_bb); bucket != APR_BRIGADE_SENTINEL(new_bb); bucket = APR_BUCKET_NEXT(bucket)) {
403             if (bucket->length > 0) {
404                 ctx->bytes_in += bucket->length;
405             }
406         }
407     }
408
409     if ((ctx->buffered_bb != NULL) &&
410         !APR_BRIGADE_EMPTY(ctx->buffered_bb)) {
411         bb = ctx->buffered_bb;
412         ctx->buffered_bb = NULL;
413         if (new_bb != NULL) {
414             APR_BRIGADE_CONCAT(bb, new_bb);
415         }
416         c->data_in_output_filters = 0;
417     }
418     else if (new_bb != NULL) {
419         bb = new_bb;
420     }
421     else {
422         return APR_SUCCESS;
423     }
424
425     /* Scan through the brigade and decide whether to attempt a write,
426      * based on the following rules:
427      *
428      *  1) The new_bb is null: Do a nonblocking write of as much as
429      *     possible: do a nonblocking write of as much data as possible,
430      *     then save the rest in ctx->buffered_bb.  (If new_bb == NULL,
431      *     it probably means that the MPM is doing asynchronous write
432      *     completion and has just determined that this connection
433      *     is writable.)
434      *
435      *  2) The brigade contains a flush bucket: Do a blocking write
436      *     of everything up that point.
437      *
438      *  3) The request is in CONN_STATE_HANDLER state, and the brigade
439      *     contains at least THRESHOLD_MAX_BUFFER bytes in non-file
440      *     buckets: Do blocking writes until the amount of data in the
441      *     buffer is less than THRESHOLD_MAX_BUFFER.  (The point of this
442      *     rule is to provide flow control, in case a handler is
443      *     streaming out lots of data faster than the data can be
444      *     sent to the client.)
445      *
446      *  4) The brigade contains at least THRESHOLD_MIN_WRITE
447      *     bytes: Do a nonblocking write of as much data as possible,
448      *     then save the rest in ctx->buffered_bb.
449      */
450
451     if (new_bb == NULL) {
452         apr_status_t rv = send_brigade_nonblocking(net->client_socket, bb,
453                                                    &(ctx->bytes_written), c);
454         if (APR_STATUS_IS_EAGAIN(rv)) {
455             rv = APR_SUCCESS;
456         }
457         else if (rv != APR_SUCCESS) {
458             /* The client has aborted the connection */
459             c->aborted = 1;
460         }
461         setaside_remaining_output(f, ctx, bb, 0, c);
462         return rv;
463     }
464
465     bytes_in_brigade = 0;
466     non_file_bytes_in_brigade = 0;
467     for (bucket = APR_BRIGADE_FIRST(bb); bucket != APR_BRIGADE_SENTINEL(bb);
468          bucket = next) {
469         next = APR_BUCKET_NEXT(bucket);
470         if (APR_BUCKET_IS_FLUSH(bucket)) {
471             apr_bucket_brigade *remainder = apr_brigade_split(bb, next);
472             apr_status_t rv = send_brigade_blocking(net->client_socket, bb,
473                                                     &(ctx->bytes_written), c);
474             if (rv != APR_SUCCESS) {
475                 /* The client has aborted the connection */
476                 c->aborted = 1;
477                 return rv;
478             }
479             bb = remainder;
480             next = APR_BRIGADE_FIRST(bb);
481             bytes_in_brigade = 0;
482             non_file_bytes_in_brigade = 0;
483         }
484         else if (!APR_BUCKET_IS_METADATA(bucket)) {
485             if (bucket->length < 0) {
486                 const char *data;
487                 apr_size_t length;
488                 /* XXX support nonblocking read here? */
489                 apr_status_t rv =
490                     apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
491                 if (rv != APR_SUCCESS) {
492                     return rv;
493                 }
494                 /* reading may have split the bucket, so recompute next: */
495                 next = APR_BUCKET_NEXT(bucket);
496             }
497             bytes_in_brigade += bucket->length;
498             if (!APR_BUCKET_IS_FILE(bucket)) {
499                 non_file_bytes_in_brigade += bucket->length;
500             }
501         }
502     }
503
504     if (non_file_bytes_in_brigade >= THRESHOLD_MAX_BUFFER) {
505         /* ### Writing the entire brigade may be excessive; we really just
506          * ### need to send enough data to be under THRESHOLD_MAX_BUFFER.
507          */
508         apr_status_t rv = send_brigade_blocking(net->client_socket, bb,
509                                                 &(ctx->bytes_written), c);
510         if (rv != APR_SUCCESS) {
511             /* The client has aborted the connection */
512             c->aborted = 1;
513             return rv;
514         }
515     }
516     else if (bytes_in_brigade >= THRESHOLD_MIN_WRITE) {
517         apr_status_t rv = send_brigade_nonblocking(net->client_socket, bb,
518                                                    &(ctx->bytes_written), c);
519         if ((rv != APR_SUCCESS) && (!APR_STATUS_IS_EAGAIN(rv))) {
520             /* The client has aborted the connection */
521             c->aborted = 1;
522             return rv;
523         }
524     }
525
526     setaside_remaining_output(f, ctx, bb, 1, c);
527     return APR_SUCCESS;
528 }
529
530 static void setaside_remaining_output(ap_filter_t *f,
531                                       core_output_filter_ctx_t *ctx,
532                                       apr_bucket_brigade *bb,
533                                       int make_a_copy, conn_rec *c)
534 {
535     if (bb == NULL) {
536         return;
537     }
538     remove_empty_buckets(bb);
539     if (!APR_BRIGADE_EMPTY(bb)) {
540         c->data_in_output_filters = 1;
541         if (make_a_copy) {
542             /* XXX should this use a separate deferred write pool, like
543              * the original ap_core_output_filter?
544              */
545             ap_save_brigade(f, &(ctx->buffered_bb), &bb, c->pool);
546             apr_brigade_destroy(bb);
547         }
548         else {
549             ctx->buffered_bb = bb;
550         }
551     }
552     else {
553         apr_brigade_destroy(bb);
554     }
555 }
556
557 #ifndef APR_MAX_IOVEC_SIZE
558 #define MAX_IOVEC_TO_WRITE 16
559 #else
560 #if APR_MAX_IOVEC_SIZE > 16
561 #define MAX_IOVEC_TO_WRITE 16
562 #else
563 #define MAX_IOVEC_TO_WRITE APR_MAX_IOVEC_SIZE
564 #endif
565 #endif
566
567 static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
568                                              apr_bucket_brigade *bb,
569                                              apr_size_t *bytes_written,
570                                              conn_rec *c)
571 {
572     apr_bucket *bucket, *next;
573     apr_status_t rv;
574     struct iovec vec[MAX_IOVEC_TO_WRITE];
575     apr_size_t nvec = 0;
576
577     remove_empty_buckets(bb);
578
579     for (bucket = APR_BRIGADE_FIRST(bb);
580          bucket != APR_BRIGADE_SENTINEL(bb);
581          bucket = next) {
582         int did_sendfile = 0;
583         next = APR_BUCKET_NEXT(bucket);
584 #if APR_HAS_SENDFILE
585         if (APR_BUCKET_IS_FILE(bucket)) {
586             apr_bucket_file *file_bucket = (apr_bucket_file *)(bucket->data);
587             apr_file_t *fd = file_bucket->fd;
588             /* Use sendfile to send this file unless:
589              *   - the platform doesn't support sendfile,
590              *   - the file is too small for sendfile to be useful, or
591              *   - sendfile is disabled in the httpd config via "EnableSendfile off"
592              */
593
594             if ((apr_file_flags_get(fd) & APR_SENDFILE_ENABLED) &&
595                 (bucket->length >= AP_MIN_SENDFILE_BYTES)) {
596                 did_sendfile = 1;
597                 if (nvec > 0) {
598                     (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1);
599                     rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
600                     nvec = 0;
601                     if (rv != APR_SUCCESS) {
602                         (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
603                         return rv;
604                     }
605                 }
606                 rv = sendfile_nonblocking(s, bucket, bytes_written, c);
607                 if (nvec > 0) {
608                     (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
609                 }
610                 if (rv != APR_SUCCESS) {
611                     return rv;
612                 }
613                 break;
614             }
615         }
616 #endif /* APR_HAS_SENDFILE */
617         if (!did_sendfile && !APR_BUCKET_IS_METADATA(bucket)) {
618             const char *data;
619             apr_size_t length;
620             rv = apr_bucket_read(bucket, &data, &length, APR_BLOCK_READ);
621             if (rv != APR_SUCCESS) {
622                 return rv;
623             }
624             /* reading may have split the bucket, so recompute next: */
625             next = APR_BUCKET_NEXT(bucket);
626             vec[nvec].iov_base = (char *)data;
627             vec[nvec].iov_len = length;
628             nvec++;
629             if (nvec == MAX_IOVEC_TO_WRITE) {
630                 rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
631                 nvec = 0;
632                 if (rv != APR_SUCCESS) {
633                     return rv;
634                 }
635                 break;
636             }
637         }
638     }
639
640     if (nvec > 0) {
641         rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
642         if (rv != APR_SUCCESS) {
643             return rv;
644         }
645     }
646
647     remove_empty_buckets(bb);
648
649     return APR_SUCCESS;
650 }
651
652 static void remove_empty_buckets(apr_bucket_brigade *bb)
653 {
654     apr_bucket *bucket;
655     while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) &&
656            (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) {
657         APR_BUCKET_REMOVE(bucket);
658         apr_bucket_destroy(bucket);
659     }
660 }
661
662 static apr_status_t send_brigade_blocking(apr_socket_t *s,
663                                           apr_bucket_brigade *bb,
664                                           apr_size_t *bytes_written,
665                                           conn_rec *c)
666 {
667     apr_status_t rv;
668
669     rv = APR_SUCCESS;
670     while (!APR_BRIGADE_EMPTY(bb)) {
671         rv = send_brigade_nonblocking(s, bb, bytes_written, c);
672         if (rv != APR_SUCCESS) {
673             if (APR_STATUS_IS_EAGAIN(rv)) {
674                 /* Wait until we can send more data */
675                 apr_int32_t nsds;
676                 apr_interval_time_t timeout;
677                 apr_pollfd_t pollset;
678
679                 pollset.p = c->pool;
680                 pollset.desc_type = APR_POLL_SOCKET;
681                 pollset.reqevents = APR_POLLOUT;
682                 pollset.desc.s = s;
683                 apr_socket_timeout_get(s, &timeout);
684                 rv = apr_poll(&pollset, 1, &nsds, timeout);
685                 if (rv != APR_SUCCESS) {
686                     break;
687                 }
688             }
689             else {
690                 break;
691             }
692         }
693     }
694     return rv;
695 }
696
697 static apr_status_t writev_nonblocking(apr_socket_t *s,
698                                        struct iovec *vec, apr_size_t nvec,
699                                        apr_bucket_brigade *bb,
700                                        apr_size_t *cumulative_bytes_written,
701                                        conn_rec *c)
702 {
703     apr_status_t rv = APR_SUCCESS, arv;
704     apr_size_t bytes_written = 0, bytes_to_write = 0;
705     apr_size_t i, offset;
706     apr_interval_time_t old_timeout;
707
708     arv = apr_socket_timeout_get(s, &old_timeout);
709     if (arv != APR_SUCCESS) {
710         return arv;
711     }
712     arv = apr_socket_timeout_set(s, 0);
713     if (arv != APR_SUCCESS) {
714         return arv;
715     }
716
717     for (i = 0; i < nvec; i++) {
718         bytes_to_write += vec[i].iov_len;
719     }
720     offset = 0;
721     while (bytes_written < bytes_to_write) {
722         apr_size_t n = 0;
723         rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
724         if (n > 0) {
725             bytes_written += n;
726             for (i = offset; i < nvec; ) {
727                 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
728                 if (APR_BUCKET_IS_METADATA(bucket)) {
729                     APR_BUCKET_REMOVE(bucket);
730                     apr_bucket_destroy(bucket);
731                 }
732                 else if (n >= vec[i].iov_len) {
733                     APR_BUCKET_REMOVE(bucket);
734                     apr_bucket_destroy(bucket);
735                     offset++;
736                     n -= vec[i++].iov_len;
737                 }
738                 else {
739                     apr_bucket_split(bucket, n);
740                     APR_BUCKET_REMOVE(bucket);
741                     apr_bucket_destroy(bucket);
742                     vec[i].iov_len -= n;
743                     vec[i].iov_base = (char *) vec[i].iov_base + n;
744                     break;
745                 }
746             }
747         }
748         if (rv != APR_SUCCESS) {
749             break;
750         }
751     }
752     if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {
753         ap__logio_add_bytes_out(c, bytes_written);
754     }
755     *cumulative_bytes_written += bytes_written;
756
757     arv = apr_socket_timeout_set(s, old_timeout);
758     if ((arv != APR_SUCCESS) && (rv == APR_SUCCESS)) {
759         return arv;
760     }
761     else {
762         return rv;
763     }
764 }
765
766 #if APR_HAS_SENDFILE
767
768 static apr_status_t sendfile_nonblocking(apr_socket_t *s,
769                                          apr_bucket *bucket,
770                                          apr_size_t *cumulative_bytes_written,
771                                          conn_rec *c)
772 {
773     apr_status_t rv = APR_SUCCESS;
774     apr_bucket_file *file_bucket;
775     apr_file_t *fd;
776     apr_size_t file_length;
777     apr_off_t file_offset;
778     apr_size_t bytes_written = 0;
779
780     if (!APR_BUCKET_IS_FILE(bucket)) {
781         ap_log_error(APLOG_MARK, APLOG_ERR, rv, c->base_server,
782                      "core_filter: sendfile_nonblocking: "
783                      "this should never happen");
784         return APR_EGENERAL;
785     }
786     file_bucket = (apr_bucket_file *)(bucket->data);
787     fd = file_bucket->fd;
788     file_length = bucket->length;
789     file_offset = bucket->start;
790
791     if (bytes_written < file_length) {
792         apr_size_t n = file_length - bytes_written;
793         apr_status_t arv;
794         apr_interval_time_t old_timeout;
795
796         arv = apr_socket_timeout_get(s, &old_timeout);
797         if (arv != APR_SUCCESS) {
798             return arv;
799         }
800         arv = apr_socket_timeout_set(s, 0);
801         if (arv != APR_SUCCESS) {
802             return arv;
803         }
804         rv = apr_socket_sendfile(s, fd, NULL, &file_offset, &n, 0);
805         if (rv == APR_SUCCESS) {
806             bytes_written += n;
807             file_offset += n;
808         }
809         arv = apr_socket_timeout_set(s, old_timeout);
810         if ((arv != APR_SUCCESS) && (rv == APR_SUCCESS)) {
811             rv = arv;
812         }
813     }
814     if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {
815         ap__logio_add_bytes_out(c, bytes_written);
816     }
817     *cumulative_bytes_written += bytes_written;
818     if ((bytes_written < file_length) && (bytes_written > 0)) {
819         apr_bucket_split(bucket, bytes_written);
820         APR_BUCKET_REMOVE(bucket);
821         apr_bucket_destroy(bucket);
822     }
823     else if (bytes_written == file_length) {
824         APR_BUCKET_REMOVE(bucket);
825         apr_bucket_destroy(bucket);
826     }
827     return rv;
828 }
829
830 #endif