mod_isapi.c revision e0fe4de2016336428729a620ac0034cd1198ad7a
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz/* ====================================================================
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz * The Apache Software License, Version 1.1
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * reserved.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 2. Redistributions in binary form must reproduce the above copyright
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * notice, this list of conditions and the following disclaimer in
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * the documentation and/or other materials provided with the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * distribution.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 3. The end-user documentation included with the redistribution,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * if any, must include the following acknowledgment:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * "This product includes software developed by the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Apache Software Foundation (http://www.apache.org/)."
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Alternately, this acknowledgment may appear in the software itself,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * if and wherever such third-party acknowledgments normally appear.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 4. The names "Apache" and "Apache Software Foundation" must
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * not be used to endorse or promote products derived from this
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * software without prior written permission. For written
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * permission, please contact apache@apache.org.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 5. Products derived from this software may not be called "Apache",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * nor may "Apache" appear in their name, without prior written
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * permission of the Apache Software Foundation.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2d71630471d1c23f0137309e3c3957c633ecbfd6rbb * SUCH DAMAGE.
ab5581cc78e9d865b0a6ab1404c53347b3276968rbb * ====================================================================
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This software consists of voluntary contributions made by many
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * individuals on behalf of the Apache Software Foundation. For more
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick * information on the Apache Software Foundation, please see
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Portions of this software are based upon public domain software
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * originally written at the National Center for Supercomputing Applications,
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe * University of Illinois, Urbana-Champaign.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * mod_isapi.c - Internet Server Application (ISA) module for Apache
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * by Alexei Kosut <akosut@apache.org>, significant overhauls and
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * redesign by William Rowe <wrowe@covalent.net>, and hints from many
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * other developer/users who have hit on specific flaws.
066877f1a045103acfdd376d48cdd473c33f409bdougm * This module implements the ISAPI Handler architecture, allowing
db3fa7db7c7910f2f23c3e3ffe0cf9f41a1899b9trawick * Apache to load Internet Server Applications (ISAPI extensions),
066877f1a045103acfdd376d48cdd473c33f409bdougm * similar to the support in IIS, Zope, O'Reilly's WebSite and others.
066877f1a045103acfdd376d48cdd473c33f409bdougm * It is a complete implementation of the ISAPI 2.0 specification,
066877f1a045103acfdd376d48cdd473c33f409bdougm * except for "Microsoft extensions" to the API which provide
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * asynchronous I/O. It is further extended to include additional
d0ba3b97557d47323bd055fb4002ed7692f703b9jerenkrantz * "Microsoft extentions" through IIS 5.0, with some deficiencies
43c3e6a4b559b76b750c245ee95e2782c15b4296jim * where one-to-one mappings don't exist.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Refer to /manual/mod/mod_isapi.html for additional details on
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * configuration and use, but check this source for specific support
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * of the API,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* Retry frequency for a failed-to-load isapi .dll */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/**********************************************************
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ISAPI Module Configuration
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding **********************************************************/
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* Our isapi per-dir config structure */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct isapi_dir_conf {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingapr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r,
e8f95a682820a599fe41b22977010636be5c2717jimstatic void *create_isapi_dir_config(apr_pool_t *p, char *dummy)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf));
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void *merge_isapi_dir_configs(apr_pool_t *p, void *base_, void *add_)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir->read_ahead_buflen = (add->read_ahead_buflen == ISAPI_UNDEF)
43c3e6a4b559b76b750c245ee95e2782c15b4296jim dir->log_unsupported = (add->log_unsupported == ISAPI_UNDEF)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir->log_to_errlog = (add->log_to_errlog == ISAPI_UNDEF)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir->log_to_query = (add->log_to_query == ISAPI_UNDEF)
066877f1a045103acfdd376d48cdd473c33f409bdougmstatic const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy,
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb const char *filename)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* ### Just an observation ... it would be terribly cool to be
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * able to use this per-dir, relative to the directory block being
if (!fspec) {
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
{NULL}
static struct isapi_global_conf {
} loaded;
struct isapi_loaded {
const char *filename;
return APR_SUCCESS;
if (force) {
return APR_EGENERAL;
return APR_SUCCESS;
if (rv)
return rv;
if (rv)
return rv;
if (rv)
return rv;
SetLastError(0);
return rv;
return APR_SUCCESS;
const char *key;
return rv;
if (*isa) {
if (!gainlock) {
return rv;
!= APR_SUCCESS) {
return rv;
return rv;
!= APR_SUCCESS) {
return rv;
return rv;
return rv;
typedef struct isapi_cid {
request_rec *r;
int headers_sent;
void *completion_arg;
} isapi_cid;
char *variable_name,
void *buf_data,
const char *result;
if (result) {
void *buf_data,
apr_bucket *b;
void *buf_data,
int res;
if (res < 0) {
return (res >= 0);
const char *stat,
const char *head,
int termarg;
char *termch;
statlen = 0;
if (stat) {
if (!head_present)
if (!termch)
return ate;
void *buf_data,
switch (HSE_code) {
case HSE_REQ_SEND_URL:
if (r->remaining > 0) {
if (buf_data)
if (data_type)
(char*) data_type,
if (ate < 0) {
apr_bucket *b;
case HSE_REQ_MAP_URL_TO_PATH:
r, NULL);
case HSE_REQ_GET_SSPI_INFO:
case HSE_APPEND_LOG_PARAMETER:
if (r->args)
(char*) buf_data);
case HSE_REQ_IO_COMPLETION:
case HSE_REQ_TRANSMIT_FILE:
apr_bucket *b;
!= APR_SUCCESS) {
if (ate < 0)
case HSE_REQ_IS_KEEP_CONN:
int res;
r->filename);
if (res >= 0) {
return (res >= 0);
case HSE_REQ_ABORTIVE_CLOSE:
if (ate < 0) {
apr_bucket *b;
c->bucket_alloc);
apr_table_t *e;
const char *val;
int res;
return DECLINED;
e = r->subprocess_env;
return HTTP_FORBIDDEN;
return HTTP_NOT_FOUND;
return HTTP_FORBIDDEN;
return HTTP_NOT_FOUND;
!= APR_SUCCESS) {
return HTTP_INTERNAL_SERVER_ERROR;
ap_add_cgi_vars(r);
cid->r = r;
if (res) {
return res;
if (ap_should_client_block(r)) {
if (r->remaining) {
read = 0;
if (res < 0) {
return HTTP_INTERNAL_SERVER_ERROR;
if (res == 0)
switch(rv) {
case HSE_STATUS_SUCCESS:
case HSE_STATUS_PENDING:
r->pool);
r->filename);
case HSE_STATUS_ERROR:
return APR_EGENERAL;
return APR_EGENERAL;
return rv;
return OK;