mod_isapi.c revision b2c17021012bc4f7cd8e374c6bd72b926737320f
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/* Licensed to the Apache Software Foundation (ASF) under one or more
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * contributor license agreements. See the NOTICE file distributed with
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * this work for additional information regarding copyright ownership.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * The ASF licenses this file to You under the Apache License, Version 2.0
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * (the "License"); you may not use this file except in compliance with
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * the License. You may obtain a copy of the License at
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Unless required by applicable law or agreed to in writing, software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * distributed under the License is distributed on an "AS IS" BASIS,
2e545ce2450a9953665f701bb05350f0d3f26275nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * limitations under the License.
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * mod_isapi.c - Internet Server Application (ISA) module for Apache
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * by Alexei Kosut <akosut@apache.org>, significant overhauls and
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * redesign by William Rowe <wrowe@covalent.net>, and hints from many
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * other developer/users who have hit on specific flaws.
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * This module implements the ISAPI Handler architecture, allowing
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * Apache to load Internet Server Applications (ISAPI extensions),
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * similar to the support in IIS, Zope, O'Reilly's WebSite and others.
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd * It is a complete implementation of the ISAPI 2.0 specification,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * except for "Microsoft extensions" to the API which provide
fac8c35bfb158112226ab43ddf84d59daca5dc30nd * asynchronous I/O. It is further extended to include additional
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * "Microsoft extentions" through IIS 5.0, with some deficiencies
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * where one-to-one mappings don't exist.
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * Refer to /manual/mod/mod_isapi.html for additional details on
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * configuration and use, but check this source for specific support
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * of the API,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/* Retry frequency for a failed-to-load isapi .dll */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/**********************************************************
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * ISAPI Module Configuration
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess **********************************************************/
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess/* Our isapi per-dir config structure */
e655a84bbb62bb1c66993fda5e74b04feda14dc6kesstypedef struct isapi_dir_conf {
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessapr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessstatic void *create_isapi_dir_config(apr_pool_t *p, char *dummy)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf));
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessstatic void *merge_isapi_dir_configs(apr_pool_t *p, void *base_, void *add_)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf));
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess dir->read_ahead_buflen = (add->read_ahead_buflen == ISAPI_UNDEF)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess dir->log_unsupported = (add->log_unsupported == ISAPI_UNDEF)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess dir->log_to_errlog = (add->log_to_errlog == ISAPI_UNDEF)
e655a84bbb62bb1c66993fda5e74b04feda14dc6kessstatic const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy,
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess const char *filename)
1c8f2418892d98febb00a06b9a4f45f8bcfd80a3nd /* ### Just an observation ... it would be terribly cool to be
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess * able to use this per-dir, relative to the directory block being
fac8c35bfb158112226ab43ddf84d59daca5dc30nd * defined. The hash result remains global, but shorthand of
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * <Directory "c:/webapps/isapi">
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * ISAPICacheFile myapp.dll anotherapp.dll thirdapp.dll
727872d18412fc021f03969b8641810d8896820bhumbedooh * </Directory>
0d0ba3a410038e179b695446bb149cce6264e0abnd * would be very convienent.
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh fspec = ap_server_root_relative(cmd->pool, filename);
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, APLOGNO(02103)
0d0ba3a410038e179b695446bb149cce6264e0abnd ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, APLOGNO(02104)
0d0ba3a410038e179b695446bb149cce6264e0abnd ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(02105)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd /* Load the extention as cached (with null request_rec) */
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd rv = isapi_lookup(cmd->pool, cmd->server, NULL, fspec, &isa);
e655a84bbb62bb1c66993fda5e74b04feda14dc6kess ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, APLOGNO(02106)
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;
apr_set_os_error(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;
struct isapi_cid {
request_rec *r;
int headers_set;
int response_sent;
void *completion_arg;
char *variable_name,
void *buf_ptr,
const char *result;
if (result) {
void *buf_data,
int res = 0;
if (res < 0) {
return (res >= 0);
const char *stat,
const char *head,
int termarg;
int res;
int old_status;
const char *termch;
statlen = 0;
char *newstat;
if (stat) {
if (res) {
else if (old_status) {
if (!head_present)
if (!termch)
return ate;
void *buf_ptr,
apr_bucket *b;
if (ate < 0) {
if (buf_size) {
r->filename);
void *buf_ptr,
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;
r->filename);
case HSE_REQ_MAP_URL_TO_PATH:
#ifdef WIN32
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)
c->bucket_alloc);
case HSE_REQ_IS_KEEP_CONN:
int res = 0;
r->filename);
* sample web/iis/extensions/io/ASyncRead. This potentially
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;
r->status = 0;
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)
r->pool);
return HTTP_INTERNAL_SERVER_ERROR;
switch(rv) {
case HSE_STATUS_SUCCESS:
case HSE_STATUS_PENDING:
r->filename);
case HSE_STATUS_ERROR:
apr_bucket *b;
return r->status;
return APR_EGENERAL;
return APR_EGENERAL;
return rv;
return OK;