From 29212e8c6b88d35a1d093486853a08a09d58aa07 Mon Sep 17 00:00:00 2001 From: Cliff Woolley Date: Wed, 27 Jun 2001 20:18:09 +0000 Subject: [PATCH] *) Account for the new pool parameter to apr_bucket_file_create() and apr_bucket_file_make(). *) Simplify mod_file_cache's sendfile_handler by taking advantage the new ability of file buckets to handle files opened in XTHREAD mode. [Also inlined some of the brigade construction stuff in mod_file_cache's handlers to save a palloc() or two.] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89438 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 ++- modules/arch/win32/mod_isapi.c | 2 +- modules/cache/mod_file_cache.c | 59 ++++++++++----------------- modules/experimental/mod_disk_cache.c | 2 +- server/core.c | 2 +- server/protocol.c | 2 +- 6 files changed, 29 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index 8b3ae483b9..53d90fa827 100644 --- a/CHANGES +++ b/CHANGES @@ -1,10 +1,13 @@ Changes with Apache 2.0.19-dev + *) mod_file_cache is now more robust to filtering and serves requests + slightly more efficiently. [Cliff Woolley] + *) Fix problem handling FLUSH bucket in the chunked encoding filter. Module was calling ap_rwrite() followed by ap_rflush() but the served content was not being displayed in the browser. Inspection of the output stream revealed that the first data chunk was - missing the trailing CRLF required by the RFC. + missing the trailing CRLF required by the RFC. [Bill Stoddard] *) apxs no longer generates ap_send_http_header() in the example handler diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c index 2912187f69..e8c49e987a 100644 --- a/modules/arch/win32/mod_isapi.c +++ b/modules/arch/win32/mod_isapi.c @@ -944,7 +944,7 @@ BOOL WINAPI ServerSupportFunction(HCONN hConn, DWORD dwHSERequest, } b = apr_bucket_file_create(fd, (apr_off_t)tf->Offset, - (apr_size_t)tf->BytesToWrite); + (apr_size_t)tf->BytesToWrite, r->pool); APR_BRIGADE_INSERT_TAIL(bb, b); if (tf->pTail && (apr_size_t)tf->TailLength) { diff --git a/modules/cache/mod_file_cache.c b/modules/cache/mod_file_cache.c index df4966595d..1839ea2053 100644 --- a/modules/cache/mod_file_cache.c +++ b/modules/cache/mod_file_cache.c @@ -115,6 +115,7 @@ #include "apr_mmap.h" #include "apr_strings.h" #include "apr_hash.h" +#include "apr_buckets.h" #define APR_WANT_STRFUNC #include "apr_want.h" @@ -206,7 +207,8 @@ static void cache_the_file(cmd_parms *cmd, const char *filename, int mmap) return; } - rc = apr_file_open(&fd, fspec, APR_READ | APR_XTHREAD, APR_OS_DEFAULT, cmd->pool); + rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD, + APR_OS_DEFAULT, cmd->pool); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, "mod_file_cache: unable to open(%s, O_RDONLY), skipping", fspec); @@ -318,7 +320,16 @@ static int file_cache_xlat(request_rec *r) static int mmap_handler(request_rec *r, a_file *file) { #if APR_HAS_MMAP - ap_send_mmap (file->mm, r, 0, file->finfo.size); + apr_bucket *b; + apr_bucket_brigade *bb = apr_brigade_create(r->pool); + + b = apr_bucket_mmap_create(file->mm, 0, file->finfo.size); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) + return HTTP_INTERNAL_SERVER_ERROR; #endif return OK; } @@ -326,44 +337,16 @@ static int mmap_handler(request_rec *r, a_file *file) static int sendfile_handler(request_rec *r, a_file *file) { #if APR_HAS_SENDFILE - apr_size_t nbytes; - apr_status_t rv = APR_EINIT; - apr_file_t *rfile; - apr_os_file_t fd; - - /* A cached file handle (more importantly, its file pointer) is - * shared by all threads in the process. The file pointer will - * be corrupted if multiple threads attempt to read from the - * cached file handle. The sendfile API does not rely on the position - * of the file pointer instead taking explicit file offset and - * length arguments. - * - * We should call ap_send_fd with a cached file handle IFF - * we are CERTAIN the file will be served with apr_sendfile(). - * The presense of an AP_FTYPE_FILTER in the filter chain nearly - * guarantees that apr_sendfile will NOT be used to send the file. - * Furthermore, AP_FTYPE_CONTENT filters will be at the beginning - * of the chain, so it should suffice to just check the first - * filter in the chain. If the first filter is not a content filter, - * assume apr_sendfile() will be used to send the content. - */ - if (r->output_filters && r->output_filters->frec) { - if (r->output_filters->frec->ftype == AP_FTYPE_CONTENT) - return DECLINED; - } + apr_bucket *b; + apr_bucket_brigade *bb = apr_brigade_create(r->pool); - /* Create an apr_file_t anchored out of the request pool to use - * on the call to ap_send_fd(). The cached apr_file_t is allocated - * out of pconf (a life of the server pool) and sending it down - * the filter chain could cause memory leaks. - */ - apr_os_file_get(&fd, file->file); - apr_os_file_put(&rfile, &fd, r->pool); - rv = ap_send_fd(rfile, r, 0, file->finfo.size, &nbytes); - if (rv != APR_SUCCESS) { - /* ap_send_fd will log the error */ + b = apr_bucket_file_create(file->file, 0, file->finfo.size, r->pool); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; - } #endif return OK; } diff --git a/modules/experimental/mod_disk_cache.c b/modules/experimental/mod_disk_cache.c index cbd28bf04a..8b5b60cf22 100644 --- a/modules/experimental/mod_disk_cache.c +++ b/modules/experimental/mod_disk_cache.c @@ -98,7 +98,7 @@ static int disk_serve(request_rec *r) } } - e = apr_bucket_file_create(fd, offset, r->finfo.size); + e = apr_bucket_file_create(fd, offset, r->finfo.size, r->pool); APR_BRIGADE_INSERT_HEAD(bb, e); e = apr_bucket_eos_create(); diff --git a/server/core.c b/server/core.c index af35e4339f..1aedb3c8e8 100644 --- a/server/core.c +++ b/server/core.c @@ -2996,7 +2996,7 @@ static int default_handler(request_rec *r) } bb = apr_brigade_create(r->pool); - e = apr_bucket_file_create(fd, 0, r->finfo.size); + e = apr_bucket_file_create(fd, 0, r->finfo.size, r->pool); APR_BRIGADE_INSERT_HEAD(bb, e); e = apr_bucket_eos_create(); diff --git a/server/protocol.c b/server/protocol.c index 09d40c0242..31c60d97b5 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -938,7 +938,7 @@ AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t of apr_status_t rv; bb = apr_brigade_create(r->pool); - b = apr_bucket_file_create(fd, offset, len); + b = apr_bucket_file_create(fd, offset, len, r->pool); APR_BRIGADE_INSERT_TAIL(bb, b); rv = ap_pass_brigade(r->output_filters, bb); -- 2.50.1