mod_asis.c revision 2fc50921b88defeb7127985dfe4b4130175e069e
0237f43ab925775250e266e479d0a337ff374a4btakashi/* ====================================================================
0237f43ab925775250e266e479d0a337ff374a4btakashi * The Apache Software License, Version 1.1
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd *
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * reserved.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * Redistribution and use in source and binary forms, with or without
0237f43ab925775250e266e479d0a337ff374a4btakashi * modification, are permitted provided that the following conditions
0237f43ab925775250e266e479d0a337ff374a4btakashi * are met:
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc *
0237f43ab925775250e266e479d0a337ff374a4btakashi * 1. Redistributions of source code must retain the above copyright
0237f43ab925775250e266e479d0a337ff374a4btakashi * notice, this list of conditions and the following disclaimer.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * 2. Redistributions in binary form must reproduce the above copyright
0237f43ab925775250e266e479d0a337ff374a4btakashi * notice, this list of conditions and the following disclaimer in
0237f43ab925775250e266e479d0a337ff374a4btakashi * the documentation and/or other materials provided with the
0237f43ab925775250e266e479d0a337ff374a4btakashi * distribution.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * 3. The end-user documentation included with the redistribution,
0237f43ab925775250e266e479d0a337ff374a4btakashi * if any, must include the following acknowledgment:
0237f43ab925775250e266e479d0a337ff374a4btakashi * "This product includes software developed by the
0237f43ab925775250e266e479d0a337ff374a4btakashi * Apache Software Foundation (http://www.apache.org/)."
0237f43ab925775250e266e479d0a337ff374a4btakashi * Alternately, this acknowledgment may appear in the software itself,
0237f43ab925775250e266e479d0a337ff374a4btakashi * if and wherever such third-party acknowledgments normally appear.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * 4. The names "Apache" and "Apache Software Foundation" must
0237f43ab925775250e266e479d0a337ff374a4btakashi * not be used to endorse or promote products derived from this
0237f43ab925775250e266e479d0a337ff374a4btakashi * software without prior written permission. For written
0237f43ab925775250e266e479d0a337ff374a4btakashi * permission, please contact apache@apache.org.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * 5. Products derived from this software may not be called "Apache",
0237f43ab925775250e266e479d0a337ff374a4btakashi * nor may "Apache" appear in their name, without prior written
0237f43ab925775250e266e479d0a337ff374a4btakashi * permission of the Apache Software Foundation.
0237f43ab925775250e266e479d0a337ff374a4btakashi *
0237f43ab925775250e266e479d0a337ff374a4btakashi * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0237f43ab925775250e266e479d0a337ff374a4btakashi * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0237f43ab925775250e266e479d0a337ff374a4btakashi * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
de5cbc413070dea83e2d897c4a00dc6a80291227trawick * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0237f43ab925775250e266e479d0a337ff374a4btakashi * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0237f43ab925775250e266e479d0a337ff374a4btakashi * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0237f43ab925775250e266e479d0a337ff374a4btakashi * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0237f43ab925775250e266e479d0a337ff374a4btakashi * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0237f43ab925775250e266e479d0a337ff374a4btakashi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0237f43ab925775250e266e479d0a337ff374a4btakashi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * SUCH DAMAGE.
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * ====================================================================
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick *
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * This software consists of voluntary contributions made by many
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * individuals on behalf of the Apache Software Foundation. For more
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * information on the Apache Software Foundation, please see
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * <http://www.apache.org/>.
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick *
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * Portions of this software are based upon public domain software
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * originally written at the National Center for Supercomputing Applications,
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick * University of Illinois, Urbana-Champaign.
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick */
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick#include "apr_strings.h"
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick#include "ap_config.h"
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick#include "httpd.h"
e0872ce93f9e1cfe48431781fc43cde555e985c3trawick#include "http_config.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "http_protocol.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "http_log.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "util_script.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "http_main.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "http_request.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
0237f43ab925775250e266e479d0a337ff374a4btakashi#include "mod_core.h"
0237f43ab925775250e266e479d0a337ff374a4btakashi
de5cbc413070dea83e2d897c4a00dc6a80291227trawick#define ASIS_MAGIC_TYPE "httpd/send-as-is"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
0237f43ab925775250e266e479d0a337ff374a4btakashistatic int asis_handler(request_rec *r)
0237f43ab925775250e266e479d0a337ff374a4btakashi{
de5cbc413070dea83e2d897c4a00dc6a80291227trawick conn_rec *c = r->connection;
de5cbc413070dea83e2d897c4a00dc6a80291227trawick apr_file_t *f = NULL;
0237f43ab925775250e266e479d0a337ff374a4btakashi apr_status_t rv;
0237f43ab925775250e266e479d0a337ff374a4btakashi const char *location;
0237f43ab925775250e266e479d0a337ff374a4btakashi
de5cbc413070dea83e2d897c4a00dc6a80291227trawick if(strcmp(r->handler,ASIS_MAGIC_TYPE) && strcmp(r->handler,"send-as-is"))
0237f43ab925775250e266e479d0a337ff374a4btakashi return DECLINED;
0237f43ab925775250e266e479d0a337ff374a4btakashi
0237f43ab925775250e266e479d0a337ff374a4btakashi r->allowed |= (AP_METHOD_BIT << M_GET);
de5cbc413070dea83e2d897c4a00dc6a80291227trawick if (r->method_number != M_GET)
de5cbc413070dea83e2d897c4a00dc6a80291227trawick return DECLINED;
de5cbc413070dea83e2d897c4a00dc6a80291227trawick if (r->finfo.filetype == 0) {
de5cbc413070dea83e2d897c4a00dc6a80291227trawick ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
e13b2a9a4ed05ff8a3532508693c5b44a381ffabtrawick "File does not exist: %s", r->filename);
e13b2a9a4ed05ff8a3532508693c5b44a381ffabtrawick return HTTP_NOT_FOUND;
de5cbc413070dea83e2d897c4a00dc6a80291227trawick }
de5cbc413070dea83e2d897c4a00dc6a80291227trawick
de5cbc413070dea83e2d897c4a00dc6a80291227trawick if ((rv = apr_file_open(&f, r->filename, APR_READ,
de5cbc413070dea83e2d897c4a00dc6a80291227trawick APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) {
de5cbc413070dea83e2d897c4a00dc6a80291227trawick ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
de5cbc413070dea83e2d897c4a00dc6a80291227trawick "file permissions deny server access: %s", r->filename);
de5cbc413070dea83e2d897c4a00dc6a80291227trawick return HTTP_FORBIDDEN;
0237f43ab925775250e266e479d0a337ff374a4btakashi }
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri ap_scan_script_header_err(r, f, NULL);
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri location = apr_table_get(r->headers_out, "Location");
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri if (location && location[0] == '/' &&
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri ((r->status == HTTP_OK) || ap_is_HTTP_REDIRECT(r->status))) {
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri apr_file_close(f);
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri
0237f43ab925775250e266e479d0a337ff374a4btakashi /* Internal redirect -- fake-up a pseudo-request */
0237f43ab925775250e266e479d0a337ff374a4btakashi r->status = HTTP_OK;
0237f43ab925775250e266e479d0a337ff374a4btakashi
0237f43ab925775250e266e479d0a337ff374a4btakashi /* This redirect needs to be a GET no matter what the original
0237f43ab925775250e266e479d0a337ff374a4btakashi * method was.
0237f43ab925775250e266e479d0a337ff374a4btakashi */
0237f43ab925775250e266e479d0a337ff374a4btakashi r->method = apr_pstrdup(r->pool, "GET");
0237f43ab925775250e266e479d0a337ff374a4btakashi r->method_number = M_GET;
0237f43ab925775250e266e479d0a337ff374a4btakashi
0237f43ab925775250e266e479d0a337ff374a4btakashi ap_internal_redirect_handler(location, r);
0237f43ab925775250e266e479d0a337ff374a4btakashi return OK;
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri }
de5cbc413070dea83e2d897c4a00dc6a80291227trawick
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (!r->header_only) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_bucket_brigade *bb;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_bucket *b;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_off_t pos = 0;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar rv = apr_file_seek(f, APR_CUR, &pos);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (rv != APR_SUCCESS) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "mod_asis: failed to find end-of-headers position "
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "for %s", r->filename);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_file_close(f);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar return HTTP_INTERNAL_SERVER_ERROR;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar bb = apr_brigade_create(r->pool, c->bucket_alloc);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar#if APR_HAS_LARGE_FILES
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (r->finfo.size - pos > AP_MAX_SENDFILE) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar /* APR_HAS_LARGE_FILES issue; must split into mutiple buckets,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar * no greater than MAX(apr_size_t), and more granular than that
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar * in case the brigade code/filters attempt to read it directly.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_off_t fsize = r->finfo.size - pos;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar b = apr_bucket_file_create(f, pos, AP_MAX_SENDFILE,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar r->pool, c->bucket_alloc);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar while (fsize > AP_MAX_SENDFILE) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar APR_BRIGADE_INSERT_TAIL(bb, b);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_bucket_copy(b, &b);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar b->start += AP_MAX_SENDFILE;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar fsize -= AP_MAX_SENDFILE;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar b->length = (apr_size_t)fsize; /* Resize just the last bucket */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar else
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar#endif
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar b = apr_bucket_file_create(f, pos, (apr_size_t) (r->finfo.size - pos),
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar r->pool, c->bucket_alloc);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar APR_BRIGADE_INSERT_TAIL(bb, b);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar b = apr_bucket_eos_create(c->bucket_alloc);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar APR_BRIGADE_INSERT_TAIL(bb, b);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar rv = ap_pass_brigade(r->output_filters, bb);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (rv != APR_SUCCESS) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "mod_asis: ap_pass_brigade failed for file %s", r->filename);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar return HTTP_INTERNAL_SERVER_ERROR;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar else {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_file_close(f);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar return OK;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar}
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coarstatic void register_hooks(apr_pool_t *p)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar{
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_hook_handler(asis_handler,NULL,NULL,APR_HOOK_MIDDLE);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar}
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coarmodule AP_MODULE_DECLARE_DATA asis_module =
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar{
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar STANDARD20_MODULE_STUFF,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar NULL, /* create per-directory config structure */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar NULL, /* merge per-directory config structures */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar NULL, /* create per-server config structure */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar NULL, /* merge per-server config structures */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar NULL, /* command apr_table_t */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar register_hooks /* register hooks */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar};
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar