file_buckets.c revision 251877
1251877Speter/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2251877Speter * 3251877Speter * Licensed under the Apache License, Version 2.0 (the "License"); 4251877Speter * you may not use this file except in compliance with the License. 5251877Speter * You may obtain a copy of the License at 6251877Speter * 7251877Speter * http://www.apache.org/licenses/LICENSE-2.0 8251877Speter * 9251877Speter * Unless required by applicable law or agreed to in writing, software 10251877Speter * distributed under the License is distributed on an "AS IS" BASIS, 11251877Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12251877Speter * See the License for the specific language governing permissions and 13251877Speter * limitations under the License. 14251877Speter */ 15251877Speter 16251877Speter#include <apr_pools.h> 17251877Speter 18251877Speter#include "serf.h" 19251877Speter#include "serf_bucket_util.h" 20251877Speter 21251877Spetertypedef struct { 22251877Speter apr_file_t *file; 23251877Speter 24251877Speter serf_databuf_t databuf; 25251877Speter 26251877Speter} file_context_t; 27251877Speter 28251877Speter 29251877Speterstatic apr_status_t file_reader(void *baton, apr_size_t bufsize, 30251877Speter char *buf, apr_size_t *len) 31251877Speter{ 32251877Speter file_context_t *ctx = baton; 33251877Speter 34251877Speter *len = bufsize; 35251877Speter return apr_file_read(ctx->file, buf, len); 36251877Speter} 37251877Speter 38251877Speterserf_bucket_t *serf_bucket_file_create( 39251877Speter apr_file_t *file, 40251877Speter serf_bucket_alloc_t *allocator) 41251877Speter{ 42251877Speter file_context_t *ctx; 43251877Speter#if APR_HAS_MMAP 44251877Speter apr_finfo_t finfo; 45251877Speter const char *file_path; 46251877Speter 47251877Speter /* See if we'd be better off mmap'ing this file instead. 48251877Speter * 49251877Speter * Note that there is a failure case here that we purposely fall through: 50251877Speter * if a file is buffered, apr_mmap will reject it. However, on older 51251877Speter * versions of APR, we have no way of knowing this - but apr_mmap_create 52251877Speter * will check for this and return APR_EBADF. 53251877Speter */ 54251877Speter apr_file_name_get(&file_path, file); 55251877Speter apr_stat(&finfo, file_path, APR_FINFO_SIZE, 56251877Speter serf_bucket_allocator_get_pool(allocator)); 57251877Speter if (APR_MMAP_CANDIDATE(finfo.size)) { 58251877Speter apr_status_t status; 59251877Speter apr_mmap_t *file_mmap; 60251877Speter status = apr_mmap_create(&file_mmap, file, 0, finfo.size, 61251877Speter APR_MMAP_READ, 62251877Speter serf_bucket_allocator_get_pool(allocator)); 63251877Speter 64251877Speter if (status == APR_SUCCESS) { 65251877Speter return serf_bucket_mmap_create(file_mmap, allocator); 66251877Speter } 67251877Speter } 68251877Speter#endif 69251877Speter 70251877Speter /* Oh, well. */ 71251877Speter ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx)); 72251877Speter ctx->file = file; 73251877Speter 74251877Speter serf_databuf_init(&ctx->databuf); 75251877Speter ctx->databuf.read = file_reader; 76251877Speter ctx->databuf.read_baton = ctx; 77251877Speter 78251877Speter return serf_bucket_create(&serf_bucket_type_file, allocator, ctx); 79251877Speter} 80251877Speter 81251877Speterstatic apr_status_t serf_file_read(serf_bucket_t *bucket, 82251877Speter apr_size_t requested, 83251877Speter const char **data, apr_size_t *len) 84251877Speter{ 85251877Speter file_context_t *ctx = bucket->data; 86251877Speter 87251877Speter return serf_databuf_read(&ctx->databuf, requested, data, len); 88251877Speter} 89251877Speter 90251877Speterstatic apr_status_t serf_file_readline(serf_bucket_t *bucket, 91251877Speter int acceptable, int *found, 92251877Speter const char **data, apr_size_t *len) 93251877Speter{ 94251877Speter file_context_t *ctx = bucket->data; 95251877Speter 96251877Speter return serf_databuf_readline(&ctx->databuf, acceptable, found, data, len); 97251877Speter} 98251877Speter 99251877Speterstatic apr_status_t serf_file_peek(serf_bucket_t *bucket, 100251877Speter const char **data, 101251877Speter apr_size_t *len) 102251877Speter{ 103251877Speter file_context_t *ctx = bucket->data; 104251877Speter 105251877Speter return serf_databuf_peek(&ctx->databuf, data, len); 106251877Speter} 107251877Speter 108251877Speterconst serf_bucket_type_t serf_bucket_type_file = { 109251877Speter "FILE", 110251877Speter serf_file_read, 111251877Speter serf_file_readline, 112251877Speter serf_default_read_iovec, 113251877Speter serf_default_read_for_sendfile, 114251877Speter serf_default_read_bucket, 115251877Speter serf_file_peek, 116251877Speter serf_default_destroy_and_data, 117251877Speter}; 118