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