diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/modules/arch/win32')
9 files changed, 0 insertions, 2741 deletions
diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/.deps b/rubbos/app/httpd-2.0.64/modules/arch/win32/.deps deleted file mode 100644 index e69de29b..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/.deps +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile b/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile deleted file mode 100644 index 7886ef35..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -top_srcdir = /bottlenecks/rubbos/app/httpd-2.0.64 -top_builddir = /bottlenecks/rubbos/app/httpd-2.0.64 -srcdir = /bottlenecks/rubbos/app/httpd-2.0.64/modules/arch/win32 -builddir = /bottlenecks/rubbos/app/httpd-2.0.64/modules/arch/win32 -VPATH = /bottlenecks/rubbos/app/httpd-2.0.64/modules/arch/win32 -# a modules Makefile has no explicit targets -- they will be defined by -# whatever modules are enabled. just grab special.mk to deal with this. -include $(top_srcdir)/build/special.mk diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile.in b/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile.in deleted file mode 100644 index 7c5c149d..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/Makefile.in +++ /dev/null @@ -1,3 +0,0 @@ -# a modules Makefile has no explicit targets -- they will be defined by -# whatever modules are enabled. just grab special.mk to deal with this. -include $(top_srcdir)/build/special.mk diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/config.m4 b/rubbos/app/httpd-2.0.64/modules/arch/win32/config.m4 deleted file mode 100644 index 25f7a850..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/config.m4 +++ /dev/null @@ -1,11 +0,0 @@ -dnl modules enabled in this directory by default - -dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) - -APACHE_MODPATH_INIT(arch/win32) - -APACHE_MODULE(isapi, isapi extension support, , , no) - -APR_ADDTO(LT_LDFLAGS,-export-dynamic) - -APACHE_MODPATH_FINISH diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.c b/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.c deleted file mode 100644 index 859d5670..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.c +++ /dev/null @@ -1,1760 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * mod_isapi.c - Internet Server Application (ISA) module for Apache - * by Alexei Kosut <akosut apache.org>, significant overhauls and - * redesign by William Rowe <wrowe covalent.net>, and hints from many - * other developer/users who have hit on specific flaws. - * - * This module implements the ISAPI Handler architecture, allowing - * Apache to load Internet Server Applications (ISAPI extensions), - * similar to the support in IIS, Zope, O'Reilly's WebSite and others. - * - * It is a complete implementation of the ISAPI 2.0 specification, - * except for "Microsoft extensions" to the API which provide - * asynchronous I/O. It is further extended to include additional - * "Microsoft extentions" through IIS 5.0, with some deficiencies - * where one-to-one mappings don't exist. - * - * Refer to /manual/mod/mod_isapi.html for additional details on - * configuration and use, but check this source for specific support - * of the API, - */ - -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_log.h" -#include "util_script.h" -#include "mod_core.h" -#include "apr_lib.h" -#include "apr_strings.h" -#include "apr_portable.h" -#include "apr_buckets.h" -#include "apr_thread_mutex.h" -#include "apr_thread_rwlock.h" -#include "apr_hash.h" -#include "mod_isapi.h" - -/* Retry frequency for a failed-to-load isapi .dll */ -#define ISAPI_RETRY apr_time_from_sec(30) - -/********************************************************** - * - * ISAPI Module Configuration - * - **********************************************************/ - -module AP_MODULE_DECLARE_DATA isapi_module; - -#define ISAPI_UNDEF -1 - -/* Our isapi per-dir config structure */ -typedef struct isapi_dir_conf { - int read_ahead_buflen; - int log_unsupported; - int log_to_errlog; - int log_to_query; - int fake_async; -} isapi_dir_conf; - -typedef struct isapi_loaded isapi_loaded; - -apr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r, - const char *fpath, isapi_loaded** isa); - -static void *create_isapi_dir_config(apr_pool_t *p, char *dummy) -{ - isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf)); - - dir->read_ahead_buflen = ISAPI_UNDEF; - dir->log_unsupported = ISAPI_UNDEF; - dir->log_to_errlog = ISAPI_UNDEF; - dir->log_to_query = ISAPI_UNDEF; - dir->fake_async = ISAPI_UNDEF; - - return dir; -} - -static void *merge_isapi_dir_configs(apr_pool_t *p, void *base_, void *add_) -{ - isapi_dir_conf *base = (isapi_dir_conf *) base_; - isapi_dir_conf *add = (isapi_dir_conf *) add_; - isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf)); - - dir->read_ahead_buflen = (add->read_ahead_buflen == ISAPI_UNDEF) - ? base->read_ahead_buflen - : add->read_ahead_buflen; - dir->log_unsupported = (add->log_unsupported == ISAPI_UNDEF) - ? base->log_unsupported - : add->log_unsupported; - dir->log_to_errlog = (add->log_to_errlog == ISAPI_UNDEF) - ? base->log_to_errlog - : add->log_to_errlog; - dir->log_to_query = (add->log_to_query == ISAPI_UNDEF) - ? base->log_to_query - : add->log_to_query; - dir->fake_async = (add->fake_async == ISAPI_UNDEF) - ? base->fake_async - : add->fake_async; - - return dir; -} - -static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, - const char *filename) -{ - isapi_loaded *isa; - apr_finfo_t tmp; - apr_status_t rv; - char *fspec; - - /* ### Just an observation ... it would be terribly cool to be - * able to use this per-dir, relative to the directory block being - * defined. The hash result remains global, but shorthand of - * <Directory "c:/webapps/isapi"> - * ISAPICacheFile myapp.dll anotherapp.dll thirdapp.dll - * </Directory> - * would be very convienent. - */ - fspec = ap_server_root_relative(cmd->pool, filename); - if (!fspec) { - ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, - "ISAPI: invalid module path, skipping %s", filename); - return NULL; - } - if ((rv = apr_stat(&tmp, fspec, APR_FINFO_TYPE, - cmd->temp_pool)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, - "ISAPI: unable to stat, skipping %s", fspec); - return NULL; - } - if (tmp.filetype != APR_REG) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, - "ISAPI: not a regular file, skipping %s", fspec); - return NULL; - } - - /* Load the extention as cached (with null request_rec) */ - rv = isapi_lookup(cmd->pool, cmd->server, NULL, fspec, &isa); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, - "ISAPI: unable to cache, skipping %s", fspec); - return NULL; - } - - return NULL; -} - -static const command_rec isapi_cmds[] = { - AP_INIT_TAKE1("ISAPIReadAheadBuffer", ap_set_int_slot, - (void *)APR_OFFSETOF(isapi_dir_conf, read_ahead_buflen), - OR_FILEINFO, "Maximum client request body to initially pass to the" - " ISAPI handler (default: 49152)"), - AP_INIT_FLAG("ISAPILogNotSupported", ap_set_flag_slot, - (void *)APR_OFFSETOF(isapi_dir_conf, log_unsupported), - OR_FILEINFO, "Log requests not supported by the ISAPI server" - " on or off (default: off)"), - AP_INIT_FLAG("ISAPIAppendLogToErrors", ap_set_flag_slot, - (void *)APR_OFFSETOF(isapi_dir_conf, log_to_errlog), - OR_FILEINFO, "Send all Append Log requests to the error log" - " on or off (default: off)"), - AP_INIT_FLAG("ISAPIAppendLogToQuery", ap_set_flag_slot, - (void *)APR_OFFSETOF(isapi_dir_conf, log_to_query), - OR_FILEINFO, "Append Log requests are concatinated to the query args" - " on or off (default: on)"), - AP_INIT_FLAG("ISAPIFakeAsync", ap_set_flag_slot, - (void *)APR_OFFSETOF(isapi_dir_conf, fake_async), - OR_FILEINFO, "Fake Asynchronous support for isapi callbacks" - " on or off [Experimental] (default: off)"), - AP_INIT_ITERATE("ISAPICacheFile", isapi_cmd_cachefile, NULL, - RSRC_CONF, "Cache the specified ISAPI extension in-process"), - {NULL} -}; - -/********************************************************** - * - * ISAPI Module Cache handling section - * - **********************************************************/ - -/* Our isapi global config values */ -static struct isapi_global_conf { - apr_pool_t *pool; - apr_thread_mutex_t *lock; - apr_hash_t *hash; -} loaded; - -/* Our loaded isapi module description structure */ -struct isapi_loaded { - const char *filename; - apr_thread_rwlock_t *in_progress; - apr_status_t last_load_rv; - apr_time_t last_load_time; - apr_dso_handle_t *handle; - HSE_VERSION_INFO *isapi_version; - apr_uint32_t report_version; - apr_uint32_t timeout; - PFN_GETEXTENSIONVERSION GetExtensionVersion; - PFN_HTTPEXTENSIONPROC HttpExtensionProc; - PFN_TERMINATEEXTENSION TerminateExtension; -}; - -static apr_status_t isapi_unload(isapi_loaded *isa, int force) -{ - /* All done with the DLL... get rid of it... - * - * If optionally cached, and we weren't asked to force the unload, - * pass HSE_TERM_ADVISORY_UNLOAD, and if it returns 1, unload, - * otherwise, leave it alone (it didn't choose to cooperate.) - */ - if (!isa->handle) { - return APR_SUCCESS; - } - if (isa->TerminateExtension) { - if (force) { - (*isa->TerminateExtension)(HSE_TERM_MUST_UNLOAD); - } - else if (!(*isa->TerminateExtension)(HSE_TERM_ADVISORY_UNLOAD)) { - return APR_EGENERAL; - } - } - apr_dso_unload(isa->handle); - isa->handle = NULL; - return APR_SUCCESS; -} - -static apr_status_t cleanup_isapi(void *isa_) -{ - isapi_loaded* isa = (isapi_loaded*) isa_; - - /* We must force the module to unload, we are about - * to lose the isapi structure's allocation entirely. - */ - return isapi_unload(isa, 1); -} - -static apr_status_t isapi_load(apr_pool_t *p, server_rec *s, isapi_loaded *isa) -{ - apr_status_t rv; - - isa->isapi_version = apr_pcalloc(p, sizeof(HSE_VERSION_INFO)); - - /* TODO: These aught to become overrideable, so that we - * assure a given isapi can be fooled into behaving well. - * - * The tricky bit, they aren't really a per-dir sort of - * config, they will always be constant across every - * reference to the .dll no matter what context (vhost, - * location, etc) they apply to. - */ - isa->report_version = 0x500; /* Revision 5.0 */ - isa->timeout = 300 * 1000000; /* microsecs, not used */ - - rv = apr_dso_load(&isa->handle, isa->filename, p); - if (rv) - { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "ISAPI: failed to load %s", isa->filename); - isa->handle = NULL; - return rv; - } - - rv = apr_dso_sym((void**)&isa->GetExtensionVersion, isa->handle, - "GetExtensionVersion"); - if (rv) - { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "ISAPI: missing GetExtensionVersion() in %s", - isa->filename); - apr_dso_unload(isa->handle); - isa->handle = NULL; - return rv; - } - - rv = apr_dso_sym((void**)&isa->HttpExtensionProc, isa->handle, - "HttpExtensionProc"); - if (rv) - { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "ISAPI: missing HttpExtensionProc() in %s", - isa->filename); - apr_dso_unload(isa->handle); - isa->handle = NULL; - return rv; - } - - /* TerminateExtension() is an optional interface */ - rv = apr_dso_sym((void**)&isa->TerminateExtension, isa->handle, - "TerminateExtension"); - apr_set_os_error(0); - - /* Run GetExtensionVersion() */ - if (!(isa->GetExtensionVersion)(isa->isapi_version)) { - apr_status_t rv = apr_get_os_error(); - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "ISAPI: failed call to GetExtensionVersion() in %s", - isa->filename); - apr_dso_unload(isa->handle); - isa->handle = NULL; - return rv; - } - - apr_pool_cleanup_register(p, isa, cleanup_isapi, - apr_pool_cleanup_null); - - return APR_SUCCESS; -} - -apr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r, - const char *fpath, isapi_loaded** isa) -{ - apr_status_t rv; - const char *key; - - if ((rv = apr_thread_mutex_lock(loaded.lock)) != APR_SUCCESS) { - return rv; - } - - *isa = apr_hash_get(loaded.hash, fpath, APR_HASH_KEY_STRING); - - if (*isa) { - - /* If we find this lock exists, use a set-aside copy of gainlock - * to avoid race conditions on NULLing the in_progress variable - * when the load has completed. Release the global isapi hash - * lock so other requests can proceed, then rdlock for completion - * of loading our desired dll or wrlock if we would like to retry - * loading the dll (because last_load_rv failed and retry is up.) - */ - apr_thread_rwlock_t *gainlock = (*isa)->in_progress; - - /* gainlock is NULLed after the module loads successfully. - * This free-threaded module can be used without any locking. - */ - if (!gainlock) { - rv = (*isa)->last_load_rv; - apr_thread_mutex_unlock(loaded.lock); - return rv; - } - - - if ((*isa)->last_load_rv == APR_SUCCESS) { - apr_thread_mutex_unlock(loaded.lock); - if ((rv = apr_thread_rwlock_rdlock(gainlock)) - != APR_SUCCESS) { - return rv; - } - rv = (*isa)->last_load_rv; - apr_thread_rwlock_unlock(gainlock); - return rv; - } - - if (apr_time_now() > (*isa)->last_load_time + ISAPI_RETRY) { - - /* Remember last_load_time before releasing the global - * hash lock to avoid colliding with another thread - * that hit this exception at the same time as our - * retry attempt, since we unlock the global mutex - * before attempting a write lock for this module. - */ - apr_time_t check_time = (*isa)->last_load_time; - apr_thread_mutex_unlock(loaded.lock); - - if ((rv = apr_thread_rwlock_wrlock(gainlock)) - != APR_SUCCESS) { - return rv; - } - - /* If last_load_time is unchanged, we still own this - * retry, otherwise presume another thread provided - * our retry (for good or ill). Relock the global - * hash for updating last_load_ vars, so their update - * is always atomic to the global lock. - */ - if (check_time == (*isa)->last_load_time) { - - rv = isapi_load(loaded.pool, s, *isa); - - apr_thread_mutex_lock(loaded.lock); - (*isa)->last_load_rv = rv; - (*isa)->last_load_time = apr_time_now(); - apr_thread_mutex_unlock(loaded.lock); - } - else { - rv = (*isa)->last_load_rv; - } - apr_thread_rwlock_unlock(gainlock); - - return rv; - } - - /* We haven't hit timeup on retry, let's grab the last_rv - * within the hash mutex before unlocking. - */ - rv = (*isa)->last_load_rv; - apr_thread_mutex_unlock(loaded.lock); - - return rv; - } - - /* If the module was not found, it's time to create a hash key entry - * before releasing the hash lock to avoid multiple threads from - * loading the same module. - */ - key = apr_pstrdup(loaded.pool, fpath); - *isa = apr_pcalloc(loaded.pool, sizeof(isapi_loaded)); - (*isa)->filename = key; - if (r) { - /* A mutex that exists only long enough to attempt to - * load this isapi dll, the release this module to all - * other takers that came along during the one-time - * load process. Short lifetime for this lock would - * be great, however, using r->pool is nasty if those - * blocked on the lock haven't all unlocked before we - * attempt to destroy. A nastier race condition than - * I want to deal with at this moment... - */ - apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool); - apr_thread_rwlock_wrlock((*isa)->in_progress); - } - - apr_hash_set(loaded.hash, key, APR_HASH_KEY_STRING, *isa); - - /* Now attempt to load the isapi on our own time, - * allow other isapi processing to resume. - */ - apr_thread_mutex_unlock(loaded.lock); - - rv = isapi_load(loaded.pool, s, *isa); - (*isa)->last_load_time = apr_time_now(); - (*isa)->last_load_rv = rv; - - if (r && (rv == APR_SUCCESS)) { - /* Let others who are blocked on this particular - * module resume their requests, for better or worse. - */ - apr_thread_rwlock_t *unlock = (*isa)->in_progress; - (*isa)->in_progress = NULL; - apr_thread_rwlock_unlock(unlock); - } - else if (!r && (rv != APR_SUCCESS)) { - /* We must leave a rwlock around for requests to retry - * loading this dll after timeup... since we were in - * the setup code we had avoided creating this lock. - */ - apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool); - } - - return (*isa)->last_load_rv; -} - -/********************************************************** - * - * ISAPI Module request callbacks section - * - **********************************************************/ - -/* Our "Connection ID" structure */ -struct isapi_cid { - EXTENSION_CONTROL_BLOCK *ecb; - isapi_dir_conf dconf; - isapi_loaded *isa; - request_rec *r; - int headers_set; - int response_sent; - PFN_HSE_IO_COMPLETION completion; - void *completion_arg; - apr_thread_mutex_t *completed; -}; - -int APR_THREAD_FUNC GetServerVariable (isapi_cid *cid, - char *variable_name, - void *buf_ptr, - apr_uint32_t *buf_size) -{ - request_rec *r = cid->r; - const char *result; - char *buf_data = (char*)buf_ptr; - apr_uint32_t len; - - if (!strcmp(variable_name, "ALL_HTTP")) - { - /* crlf delimited, colon split, comma separated and - * null terminated list of HTTP_ vars - */ - const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); - const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; - int i; - - for (len = 0, i = 0; i < arr->nelts; i++) { - if (!strncmp(elts[i].key, "HTTP_", 5)) { - len += strlen(elts[i].key) + strlen(elts[i].val) + 3; - } - } - - if (*buf_size < len + 1) { - *buf_size = len + 1; - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER)); - return 0; - } - - for (i = 0; i < arr->nelts; i++) { - if (!strncmp(elts[i].key, "HTTP_", 5)) { - strcpy(buf_data, elts[i].key); - buf_data += strlen(elts[i].key); - *(buf_data++) = ':'; - strcpy(buf_data, elts[i].val); - buf_data += strlen(elts[i].val); - *(buf_data++) = '\r'; - *(buf_data++) = '\n'; - } - } - - *(buf_data++) = '\0'; - *buf_size = len + 1; - return 1; - } - - if (!strcmp(variable_name, "ALL_RAW")) - { - /* crlf delimited, colon split, comma separated and - * null terminated list of the raw request header - */ - const apr_array_header_t *arr = apr_table_elts(r->headers_in); - const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; - int i; - - for (len = 0, i = 0; i < arr->nelts; i++) { - len += strlen(elts[i].key) + strlen(elts[i].val) + 4; - } - - if (*buf_size < len + 1) { - *buf_size = len + 1; - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER)); - return 0; - } - - for (i = 0; i < arr->nelts; i++) { - strcpy(buf_data, elts[i].key); - buf_data += strlen(elts[i].key); - *(buf_data++) = ':'; - *(buf_data++) = ' '; - strcpy(buf_data, elts[i].val); - buf_data += strlen(elts[i].val); - *(buf_data++) = '\r'; - *(buf_data++) = '\n'; - } - *(buf_data++) = '\0'; - *buf_size = len + 1; - return 1; - } - - /* Not a special case */ - result = apr_table_get(r->subprocess_env, variable_name); - - if (result) { - len = strlen(result); - if (*buf_size < len + 1) { - *buf_size = len + 1; - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INSUFFICIENT_BUFFER)); - return 0; - } - strcpy(buf_data, result); - *buf_size = len + 1; - return 1; - } - - /* Not Found */ - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_INDEX)); - return 0; -} - -int APR_THREAD_FUNC ReadClient(isapi_cid *cid, - void *buf_data, - apr_uint32_t *buf_size) -{ - request_rec *r = cid->r; - apr_uint32_t read = 0; - int res; - - if (r->remaining < *buf_size) { - *buf_size = (apr_size_t)r->remaining; - } - - while (read < *buf_size && - ((res = ap_get_client_block(r, (char*)buf_data + read, - *buf_size - read)) > 0)) { - read += res; - } - - *buf_size = read; - if (res < 0) { - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_READ_FAULT)); - } - return (res >= 0); -} - -/* Common code invoked for both HSE_REQ_SEND_RESPONSE_HEADER and - * the newer HSE_REQ_SEND_RESPONSE_HEADER_EX ServerSupportFunction(s) - * as well as other functions that write responses and presume that - * the support functions above are optional. - * - * Other callers trying to split headers and body bytes should pass - * head/headlen alone (leaving stat/statlen NULL/0), so that they - * get a proper count of bytes consumed. The argument passed to stat - * isn't counted as the head bytes are. - */ -static apr_ssize_t send_response_header(isapi_cid *cid, - const char *stat, - const char *head, - apr_size_t statlen, - apr_size_t headlen) -{ - int head_present = 1; - int termarg; - int res; - int old_status; - const char *termch; - apr_size_t ate = 0; - - if (!head || headlen == 0 || !*head) { - head = stat; - stat = NULL; - headlen = statlen; - statlen = 0; - head_present = 0; /* Don't eat the header */ - } - - if (!stat || statlen == 0 || !*stat) { - if (head && headlen && *head && ((stat = memchr(head, '\r', headlen)) - || (stat = memchr(head, '\n', headlen)) - || (stat = memchr(head, '\0', headlen)) - || (stat = head + headlen))) { - statlen = stat - head; - if (memchr(head, ':', statlen)) { - stat = "Status: 200 OK"; - statlen = strlen(stat); - } - else { - const char *flip = head; - head = stat; - stat = flip; - headlen -= statlen; - ate += statlen; - if (*head == '\r' && headlen) - ++head, --headlen, ++ate; - if (*head == '\n' && headlen) - ++head, --headlen, ++ate; - } - } - } - - if (stat && (statlen > 0) && *stat) { - char *newstat; - if (!apr_isdigit(*stat)) { - const char *stattok = stat; - int toklen = statlen; - while (toklen && *stattok && !apr_isspace(*stattok)) { - ++stattok; --toklen; - } - while (toklen && apr_isspace(*stattok)) { - ++stattok; --toklen; - } - /* Now decide if we follow the xxx message - * or the http/x.x xxx message format - */ - if (toklen && apr_isdigit(*stattok)) { - statlen = toklen; - stat = stattok; - } - } - newstat = apr_palloc(cid->r->pool, statlen + 9); - strcpy(newstat, "Status: "); - apr_cpystrn(newstat + 8, stat, statlen + 1); - stat = newstat; - statlen += 8; - } - - if (!head || headlen == 0 || !*head) { - head = "\r\n"; - headlen = 2; - } - else - { - if (head[headlen - 1] && head[headlen]) { - /* Whoops... not NULL terminated */ - head = apr_pstrndup(cid->r->pool, head, headlen); - } - } - - /* Seems IIS does not enforce the requirement for \r\n termination - * on HSE_REQ_SEND_RESPONSE_HEADER, but we won't panic... - * ap_scan_script_header_err_strs handles this aspect for us. - * - * Parse them out, or die trying - */ - old_status = cid->r->status; - - if (stat) { - res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, - stat, head, NULL); - } - else { - res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, - head, NULL); - } - - /* Set our status. */ - if (res) { - /* This is an immediate error result from the parser - */ - cid->r->status = res; - cid->r->status_line = ap_get_status_line(cid->r->status); - cid->ecb->dwHttpStatusCode = cid->r->status; - } - else if (cid->r->status) { - /* We have a status in r->status, so let's just use it. - * This is likely to be the Status: parsed above, and - * may also be a delayed error result from the parser. - * If it was filled in, status_line should also have - * been filled in. - */ - cid->ecb->dwHttpStatusCode = cid->r->status; - } - else if (cid->ecb->dwHttpStatusCode - && cid->ecb->dwHttpStatusCode != HTTP_OK) { - /* Now we fall back on dwHttpStatusCode if it appears - * ap_scan_script_header fell back on the default code. - * Any other results set dwHttpStatusCode to the decoded - * status value. - */ - cid->r->status = cid->ecb->dwHttpStatusCode; - cid->r->status_line = ap_get_status_line(cid->r->status); - } - else if (old_status) { - /* Well... either there is no dwHttpStatusCode or it's HTTP_OK. - * In any case, we don't have a good status to return yet... - * Perhaps the one we came in with will be better. Let's use it, - * if we were given one (note this is a pendantic case, it would - * normally be covered above unless the scan script code unset - * the r->status). Should there be a check here as to whether - * we are setting a valid response code? - */ - cid->r->status = old_status; - cid->r->status_line = ap_get_status_line(cid->r->status); - cid->ecb->dwHttpStatusCode = cid->r->status; - } - else { - /* None of dwHttpStatusCode, the parser's r->status nor the - * old value of r->status were helpful, and nothing was decoded - * from Status: string passed to us. Let's just say HTTP_OK - * and get the data out, this was the isapi dev's oversight. - */ - cid->r->status = HTTP_OK; - cid->r->status_line = ap_get_status_line(cid->r->status); - cid->ecb->dwHttpStatusCode = cid->r->status; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, cid->r, - "ISAPI: Could not determine HTTP response code; using %d", - cid->r->status); - } - - if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR) { - return -1; - } - - /* If only Status was passed, we consumed nothing - */ - if (!head_present) - return 0; - - cid->headers_set = 1; - - /* If all went well, tell the caller we consumed the headers complete - */ - if (!termch) - return(ate + headlen); - - /* Any data left must be sent directly by the caller, all we - * give back is the size of the headers we consumed (which only - * happens if the parser got to the head arg, which varies based - * on whether we passed stat+head to scan, or only head. - */ - if (termch && (termarg == (stat ? 1 : 0)) - && head_present && head + headlen > termch) { - return ate + termch - head; - } - return ate; -} - -int APR_THREAD_FUNC WriteClient(isapi_cid *cid, - void *buf_ptr, - apr_uint32_t *size_arg, - apr_uint32_t flags) -{ - request_rec *r = cid->r; - conn_rec *c = r->connection; - apr_uint32_t buf_size = *size_arg; - char *buf_data = (char*)buf_ptr; - apr_bucket_brigade *bb; - apr_bucket *b; - apr_status_t rv = APR_SUCCESS; - - if (!cid->headers_set) { - /* It appears that the foxisapi module and other clients - * presume that WriteClient("headers\n\nbody") will work. - * Parse them out, or die trying. - */ - apr_ssize_t ate; - ate = send_response_header(cid, NULL, buf_data, 0, buf_size); - if (ate < 0) { - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - - buf_data += ate; - buf_size -= ate; - } - - if (buf_size) { - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_transient_create(buf_data, buf_size, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - rv = ap_pass_brigade(r->output_filters, bb); - cid->response_sent = 1; - if (rv != APR_SUCCESS) - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, - "ISAPI: WriteClient ap_pass_brigade " - "failed: %s", r->filename); - } - - if ((flags & HSE_IO_ASYNC) && cid->completion) { - if (rv == APR_SUCCESS) { - cid->completion(cid->ecb, cid->completion_arg, - *size_arg, ERROR_SUCCESS); - } - else { - cid->completion(cid->ecb, cid->completion_arg, - *size_arg, ERROR_WRITE_FAULT); - } - } - return (rv == APR_SUCCESS); -} - -/* A "safe" maximum bucket size, 1Gb */ -#define MAX_BUCKET_SIZE (0x40000000) - -apr_bucket *brigade_insert_file(apr_bucket_brigade *bb, - apr_file_t *f, - apr_off_t start, - apr_off_t length, - apr_pool_t *p) -{ - apr_bucket *e; - - if (sizeof(apr_off_t) == sizeof(apr_size_t) || length < MAX_BUCKET_SIZE) { - e = apr_bucket_file_create(f, start, (apr_size_t)length, p, - bb->bucket_alloc); - } - else { - /* Several buckets are needed. */ - e = apr_bucket_file_create(f, start, MAX_BUCKET_SIZE, p, - bb->bucket_alloc); - - while (length > MAX_BUCKET_SIZE) { - apr_bucket *ce; - apr_bucket_copy(e, &ce); - APR_BRIGADE_INSERT_TAIL(bb, ce); - e->start += MAX_BUCKET_SIZE; - length -= MAX_BUCKET_SIZE; - } - e->length = (apr_size_t)length; /* Resize just the last bucket */ - } - - APR_BRIGADE_INSERT_TAIL(bb, e); - return e; -} - -int APR_THREAD_FUNC ServerSupportFunction(isapi_cid *cid, - apr_uint32_t HSE_code, - void *buf_ptr, - apr_uint32_t *buf_size, - apr_uint32_t *data_type) -{ - request_rec *r = cid->r; - conn_rec *c = r->connection; - char *buf_data = (char*)buf_ptr; - request_rec *subreq; - apr_status_t rv; - - switch (HSE_code) { - case HSE_REQ_SEND_URL_REDIRECT_RESP: - /* Set the status to be returned when the HttpExtensionProc() - * is done. - * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP - * and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK. - * They most definately are not, even in their own samples. - */ - apr_table_set (r->headers_out, "Location", buf_data); - cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; - cid->r->status_line = ap_get_status_line(cid->r->status); - cid->headers_set = 1; - return 1; - - case HSE_REQ_SEND_URL: - /* Soak up remaining input */ - if (r->remaining > 0) { - char argsbuffer[HUGE_STRING_LEN]; - while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN)); - } - - /* Reset the method to GET */ - r->method = apr_pstrdup(r->pool, "GET"); - r->method_number = M_GET; - - /* Don't let anyone think there's still data */ - apr_table_unset(r->headers_in, "Content-Length"); - - /* AV fault per PR3598 - redirected path is lost! */ - buf_data = apr_pstrdup(r->pool, (char*)buf_data); - ap_internal_redirect(buf_data, r); - return 1; - - case HSE_REQ_SEND_RESPONSE_HEADER: - { - /* Parse them out, or die trying */ - apr_size_t statlen = 0, headlen = 0; - apr_ssize_t ate; - if (buf_data) - statlen = strlen((char*) buf_data); - if (data_type) - headlen = strlen((char*) data_type); - ate = send_response_header(cid, (char*) buf_data, - (char*) data_type, - statlen, headlen); - if (ate < 0) { - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - else if ((apr_size_t)ate < headlen) { - apr_bucket_brigade *bb; - apr_bucket *b; - bb = apr_brigade_create(cid->r->pool, c->bucket_alloc); - b = apr_bucket_transient_create((char*) data_type + ate, - headlen - ate, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - rv = ap_pass_brigade(cid->r->output_filters, bb); - cid->response_sent = 1; - if (rv != APR_SUCCESS) - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, - "ISAPI: ServerSupport function " - "HSE_REQ_SEND_RESPONSE_HEADER " - "ap_pass_brigade failed: %s", r->filename); - return (rv == APR_SUCCESS); - } - /* Deliberately hold off sending 'just the headers' to begin to - * accumulate the body and speed up the overall response, or at - * least wait for the end the session. - */ - return 1; - } - - case HSE_REQ_DONE_WITH_SESSION: - /* Signal to resume the thread completing this request, - * leave it to the pool cleanup to dispose of our mutex. - */ - if (cid->completed) { - (void)apr_thread_mutex_unlock(cid->completed); - return 1; - } - else if (cid->dconf.log_unsupported) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_DONE_WITH_SESSION is not supported: %s", - r->filename); - } - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_MAP_URL_TO_PATH: - { - /* Map a URL to a filename */ - char *file = (char *)buf_data; - apr_uint32_t len; - subreq = ap_sub_req_lookup_uri( - apr_pstrndup(cid->r->pool, file, *buf_size), r, NULL); - - if (!subreq->filename) { - ap_destroy_sub_req(subreq); - return 0; - } - - len = (apr_uint32_t)strlen(r->filename); - - if ((subreq->finfo.filetype == APR_DIR) - && (!subreq->path_info) - && (file[len - 1] != '/')) - file = apr_pstrcat(cid->r->pool, subreq->filename, "/", NULL); - else - file = apr_pstrcat(cid->r->pool, subreq->filename, - subreq->path_info, NULL); - - ap_destroy_sub_req(subreq); - -#ifdef WIN32 - /* We need to make this a real Windows path name */ - apr_filepath_merge(&file, "", file, APR_FILEPATH_NATIVE, r->pool); -#endif - - *buf_size = apr_cpystrn(buf_data, file, *buf_size) - buf_data; - - return 1; - } - - case HSE_REQ_GET_SSPI_INFO: - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction HSE_REQ_GET_SSPI_INFO " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_APPEND_LOG_PARAMETER: - /* Log buf_data, of buf_size bytes, in the URI Query (cs-uri-query) field - */ - apr_table_set(r->notes, "isapi-parameter", (char*) buf_data); - if (cid->dconf.log_to_query) { - if (r->args) - r->args = apr_pstrcat(r->pool, r->args, (char*) buf_data, NULL); - else - r->args = apr_pstrdup(r->pool, (char*) buf_data); - } - if (cid->dconf.log_to_errlog) - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "ISAPI: %s: %s", cid->r->filename, - (char*) buf_data); - return 1; - - case HSE_REQ_IO_COMPLETION: - /* Emulates a completion port... Record callback address and - * user defined arg, we will call this after any async request - * (e.g. transmitfile) as if the request executed async. - * Per MS docs... HSE_REQ_IO_COMPLETION replaces any prior call - * to HSE_REQ_IO_COMPLETION, and buf_data may be set to NULL. - */ - if (cid->dconf.fake_async) { - cid->completion = (PFN_HSE_IO_COMPLETION) buf_data; - cid->completion_arg = (void *) data_type; - return 1; - } - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction HSE_REQ_IO_COMPLETION " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_TRANSMIT_FILE: - { - /* we do nothing with (tf->dwFlags & HSE_DISCONNECT_AFTER_SEND) - */ - HSE_TF_INFO *tf = (HSE_TF_INFO*)buf_data; - apr_uint32_t sent = 0; - apr_ssize_t ate = 0; - apr_bucket_brigade *bb; - apr_bucket *b; - apr_file_t *fd; - apr_off_t fsize; - - if (!cid->dconf.fake_async && (tf->dwFlags & HSE_IO_ASYNC)) { - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction HSE_REQ_TRANSMIT_FILE " - "as HSE_IO_ASYNC is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - - /* Presume the handle was opened with the CORRECT semantics - * for TransmitFile - */ - if ((rv = apr_os_file_put(&fd, &tf->hFile, - APR_READ | APR_XTHREAD, r->pool)) - != APR_SUCCESS) { - return 0; - } - if (tf->BytesToWrite) { - fsize = tf->BytesToWrite; - } - else { - apr_finfo_t fi; - if (apr_file_info_get(&fi, APR_FINFO_SIZE, fd) != APR_SUCCESS) { - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - fsize = fi.size - tf->Offset; - } - - /* apr_dupfile_oshandle (&fd, tf->hFile, r->pool); */ - bb = apr_brigade_create(r->pool, c->bucket_alloc); - - /* According to MS: if calling HSE_REQ_TRANSMIT_FILE with the - * HSE_IO_SEND_HEADERS flag, then you can't otherwise call any - * HSE_SEND_RESPONSE_HEADERS* fn, but if you don't use the flag, - * you must have done so. They document that the pHead headers - * option is valid only for HSE_IO_SEND_HEADERS - we are a bit - * more flexible and assume with the flag, pHead are the - * response headers, and without, pHead simply contains text - * (handled after this case). - */ - if ((tf->dwFlags & HSE_IO_SEND_HEADERS) && tf->pszStatusCode) { - ate = send_response_header(cid, tf->pszStatusCode, - (char*)tf->pHead, - strlen(tf->pszStatusCode), - tf->HeadLength); - } - else if (!cid->headers_set && tf->pHead && tf->HeadLength - && *(char*)tf->pHead) { - ate = send_response_header(cid, NULL, (char*)tf->pHead, - 0, tf->HeadLength); - if (ate < 0) - { - apr_brigade_destroy(bb); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - } - - if (tf->pHead && (apr_size_t)ate < tf->HeadLength) { - b = apr_bucket_transient_create((char*)tf->pHead + ate, - tf->HeadLength - ate, - c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - sent = tf->HeadLength; - } - - sent += (apr_uint32_t)fsize; - brigade_insert_file(bb, fd, tf->Offset, fsize, r->pool); - - if (tf->pTail && tf->TailLength) { - sent += tf->TailLength; - b = apr_bucket_transient_create((char*)tf->pTail, - tf->TailLength, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - } - - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - rv = ap_pass_brigade(r->output_filters, bb); - cid->response_sent = 1; - if (rv != APR_SUCCESS) - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, - "ISAPI: ServerSupport function " - "HSE_REQ_TRANSMIT_FILE " - "ap_pass_brigade failed: %s", r->filename); - - /* Use tf->pfnHseIO + tf->pContext, or if NULL, then use cid->fnIOComplete - * pass pContect to the HseIO callback. - */ - if (tf->dwFlags & HSE_IO_ASYNC) { - if (tf->pfnHseIO) { - if (rv == APR_SUCCESS) { - tf->pfnHseIO(cid->ecb, tf->pContext, - ERROR_SUCCESS, sent); - } - else { - tf->pfnHseIO(cid->ecb, tf->pContext, - ERROR_WRITE_FAULT, sent); - } - } - else if (cid->completion) { - if (rv == APR_SUCCESS) { - cid->completion(cid->ecb, cid->completion_arg, - sent, ERROR_SUCCESS); - } - else { - cid->completion(cid->ecb, cid->completion_arg, - sent, ERROR_WRITE_FAULT); - } - } - } - return (rv == APR_SUCCESS); - } - - case HSE_REQ_REFRESH_ISAPI_ACL: - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_REFRESH_ISAPI_ACL " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_IS_KEEP_CONN: - *((int *)buf_data) = (r->connection->keepalive == AP_CONN_KEEPALIVE); - return 1; - - case HSE_REQ_ASYNC_READ_CLIENT: - { - apr_uint32_t read = 0; - int res; - if (!cid->dconf.fake_async) { - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: asynchronous I/O not supported: %s", - r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - - if (r->remaining < *buf_size) { - *buf_size = (apr_size_t)r->remaining; - } - - while (read < *buf_size && - ((res = ap_get_client_block(r, (char*)buf_data + read, - *buf_size - read)) > 0)) { - read += res; - } - - if ((*data_type & HSE_IO_ASYNC) && cid->completion) { - /* XXX: Many authors issue their next HSE_REQ_ASYNC_READ_CLIENT - * within the completion logic. An example is MS's own PSDK - * sample web/iis/extensions/io/ASyncRead. This potentially - * leads to stack exhaustion. To refactor, the notification - * logic needs to move to isapi_handler() - differentiating - * the cid->completed event with a new flag to indicate - * an async-notice versus the async request completed. - */ - if (res >= 0) { - cid->completion(cid->ecb, cid->completion_arg, - read, ERROR_SUCCESS); - } - else { - cid->completion(cid->ecb, cid->completion_arg, - read, ERROR_READ_FAULT); - } - } - return (res >= 0); - } - - case HSE_REQ_GET_IMPERSONATION_TOKEN: /* Added in ISAPI 4.0 */ - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_GET_IMPERSONATION_TOKEN " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_MAP_URL_TO_PATH_EX: - { - /* Map a URL to a filename */ - HSE_URL_MAPEX_INFO *info = (HSE_URL_MAPEX_INFO*)data_type; - char* test_uri = apr_pstrndup(r->pool, (char *)buf_data, *buf_size); - - subreq = ap_sub_req_lookup_uri(test_uri, r, NULL); - info->cchMatchingURL = strlen(test_uri); - info->cchMatchingPath = apr_cpystrn(info->lpszPath, subreq->filename, - sizeof(info->lpszPath)) - info->lpszPath; - - /* Mapping started with assuming both strings matched. - * Now roll on the path_info as a mismatch and handle - * terminating slashes for directory matches. - */ - if (subreq->path_info && *subreq->path_info) { - apr_cpystrn(info->lpszPath + info->cchMatchingPath, - subreq->path_info, - sizeof(info->lpszPath) - info->cchMatchingPath); - info->cchMatchingURL -= strlen(subreq->path_info); - if (subreq->finfo.filetype == APR_DIR - && info->cchMatchingPath < sizeof(info->lpszPath) - 1) { - /* roll forward over path_info's first slash */ - ++info->cchMatchingPath; - ++info->cchMatchingURL; - } - } - else if (subreq->finfo.filetype == APR_DIR - && info->cchMatchingPath < sizeof(info->lpszPath) - 1) { - /* Add a trailing slash for directory */ - info->lpszPath[info->cchMatchingPath++] = '/'; - info->lpszPath[info->cchMatchingPath] = '\0'; - } - - /* If the matched isn't a file, roll match back to the prior slash */ - if (subreq->finfo.filetype == APR_NOFILE) { - while (info->cchMatchingPath && info->cchMatchingURL) { - if (info->lpszPath[info->cchMatchingPath - 1] == '/') - break; - --info->cchMatchingPath; - --info->cchMatchingURL; - } - } - - /* Paths returned with back slashes */ - for (test_uri = info->lpszPath; *test_uri; ++test_uri) - if (*test_uri == '/') - *test_uri = '\\'; - - /* is a combination of: - * HSE_URL_FLAGS_READ 0x001 Allow read - * HSE_URL_FLAGS_WRITE 0x002 Allow write - * HSE_URL_FLAGS_EXECUTE 0x004 Allow execute - * HSE_URL_FLAGS_SSL 0x008 Require SSL - * HSE_URL_FLAGS_DONT_CACHE 0x010 Don't cache (VRoot only) - * HSE_URL_FLAGS_NEGO_CERT 0x020 Allow client SSL cert - * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert - * HSE_URL_FLAGS_MAP_CERT 0x080 Map client SSL cert to account - * HSE_URL_FLAGS_SSL128 0x100 Require 128-bit SSL cert - * HSE_URL_FLAGS_SCRIPT 0x200 Allow script execution - * - * XxX: As everywhere, EXEC flags could use some work... - * and this could go further with more flags, as desired. - */ - info->dwFlags = (subreq->finfo.protection & APR_UREAD ? 0x001 : 0) - | (subreq->finfo.protection & APR_UWRITE ? 0x002 : 0) - | (subreq->finfo.protection & APR_UEXECUTE ? 0x204 : 0); - return 1; - } - - case HSE_REQ_ABORTIVE_CLOSE: - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE" - " is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_GET_CERT_INFO_EX: /* Added in ISAPI 4.0 */ - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_GET_CERT_INFO_EX " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_SEND_RESPONSE_HEADER_EX: /* Added in ISAPI 4.0 */ - { - HSE_SEND_HEADER_EX_INFO *shi = (HSE_SEND_HEADER_EX_INFO*)buf_data; - - /* Ignore shi->fKeepConn - we don't want the advise - */ - apr_ssize_t ate = send_response_header(cid, shi->pszStatus, - shi->pszHeader, - shi->cchStatus, - shi->cchHeader); - if (ate < 0) { - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } - else if ((apr_size_t)ate < shi->cchHeader) { - apr_bucket_brigade *bb; - apr_bucket *b; - bb = apr_brigade_create(cid->r->pool, c->bucket_alloc); - b = apr_bucket_transient_create(shi->pszHeader + ate, - shi->cchHeader - ate, - c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - b = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - rv = ap_pass_brigade(cid->r->output_filters, bb); - cid->response_sent = 1; - if (rv != APR_SUCCESS) - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, - "ISAPI: ServerSupport function " - "HSE_REQ_SEND_RESPONSE_HEADER_EX " - "ap_pass_brigade failed: %s", r->filename); - return (rv == APR_SUCCESS); - } - /* Deliberately hold off sending 'just the headers' to begin to - * accumulate the body and speed up the overall response, or at - * least wait for the end the session. - */ - return 1; - } - - case HSE_REQ_CLOSE_CONNECTION: /* Added after ISAPI 4.0 */ - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_CLOSE_CONNECTION " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - case HSE_REQ_IS_CONNECTED: /* Added after ISAPI 4.0 */ - /* Returns True if client is connected c.f. MSKB Q188346 - * assuming the identical return mechanism as HSE_REQ_IS_KEEP_CONN - */ - *((int *)buf_data) = (r->connection->aborted == 0); - return 1; - - case HSE_REQ_EXTENSION_TRIGGER: /* Added after ISAPI 4.0 */ - /* Undocumented - defined by the Microsoft Jan '00 Platform SDK - */ - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction " - "HSE_REQ_EXTENSION_TRIGGER " - "is not supported: %s", r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - - default: - if (cid->dconf.log_unsupported) - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: ServerSupportFunction (%d) not supported: " - "%s", HSE_code, r->filename); - apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER)); - return 0; - } -} - -/********************************************************** - * - * ISAPI Module request invocation section - * - **********************************************************/ - -apr_status_t isapi_handler (request_rec *r) -{ - isapi_dir_conf *dconf; - apr_table_t *e; - apr_status_t rv; - isapi_loaded *isa; - isapi_cid *cid; - const char *val; - apr_uint32_t read; - int res; - - if(strcmp(r->handler, "isapi-isa") - && strcmp(r->handler, "isapi-handler")) { - /* Hang on to the isapi-isa for compatibility with older docs - * (wtf did '-isa' mean in the first place?) but introduce - * a newer and clearer "isapi-handler" name. - */ - return DECLINED; - } - dconf = ap_get_module_config(r->per_dir_config, &isapi_module); - e = r->subprocess_env; - - /* Use similar restrictions as CGIs - * - * If this fails, it's pointless to load the isapi dll. - */ - if (!(ap_allow_options(r) & OPT_EXECCGI)) { - return HTTP_FORBIDDEN; - } - if (r->finfo.filetype == APR_NOFILE) { - return HTTP_NOT_FOUND; - } - if (r->finfo.filetype != APR_REG) { - return HTTP_FORBIDDEN; - } - if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) && - r->path_info && *r->path_info) { - /* default to accept */ - return HTTP_NOT_FOUND; - } - - if (isapi_lookup(r->pool, r->server, r, r->filename, &isa) - != APR_SUCCESS) { - return HTTP_INTERNAL_SERVER_ERROR; - } - /* Set up variables */ - ap_add_common_vars(r); - ap_add_cgi_vars(r); - apr_table_setn(e, "UNMAPPED_REMOTE_USER", "REMOTE_USER"); - if ((val = apr_table_get(e, "HTTPS")) && (strcmp(val, "on") == 0)) - apr_table_setn(e, "SERVER_PORT_SECURE", "1"); - else - apr_table_setn(e, "SERVER_PORT_SECURE", "0"); - apr_table_setn(e, "URL", r->uri); - - /* Set up connection structure and ecb, - * NULL or zero out most fields. - */ - cid = apr_pcalloc(r->pool, sizeof(isapi_cid)); - - /* Fixup defaults for dconf */ - cid->dconf.read_ahead_buflen = (dconf->read_ahead_buflen == ISAPI_UNDEF) - ? 49152 : dconf->read_ahead_buflen; - cid->dconf.log_unsupported = (dconf->log_unsupported == ISAPI_UNDEF) - ? 0 : dconf->log_unsupported; - cid->dconf.log_to_errlog = (dconf->log_to_errlog == ISAPI_UNDEF) - ? 0 : dconf->log_to_errlog; - cid->dconf.log_to_query = (dconf->log_to_query == ISAPI_UNDEF) - ? 1 : dconf->log_to_query; - cid->dconf.fake_async = (dconf->fake_async == ISAPI_UNDEF) - ? 0 : dconf->fake_async; - - cid->ecb = apr_pcalloc(r->pool, sizeof(EXTENSION_CONTROL_BLOCK)); - cid->ecb->ConnID = cid; - cid->isa = isa; - cid->r = r; - r->status = 0; - - cid->ecb->cbSize = sizeof(EXTENSION_CONTROL_BLOCK); - cid->ecb->dwVersion = isa->report_version; - cid->ecb->dwHttpStatusCode = 0; - strcpy(cid->ecb->lpszLogData, ""); - /* TODO: are copies really needed here? - */ - cid->ecb->lpszMethod = (char*) r->method; - cid->ecb->lpszQueryString = (char*) apr_table_get(e, "QUERY_STRING"); - cid->ecb->lpszPathInfo = (char*) apr_table_get(e, "PATH_INFO"); - cid->ecb->lpszPathTranslated = (char*) apr_table_get(e, "PATH_TRANSLATED"); - cid->ecb->lpszContentType = (char*) apr_table_get(e, "CONTENT_TYPE"); - - /* Set up the callbacks */ - cid->ecb->GetServerVariable = GetServerVariable; - cid->ecb->WriteClient = WriteClient; - cid->ecb->ReadClient = ReadClient; - cid->ecb->ServerSupportFunction = ServerSupportFunction; - - /* Set up client input */ - res = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR); - if (res) { - return res; - } - - if (ap_should_client_block(r)) { - /* Time to start reading the appropriate amount of data, - * and allow the administrator to tweak the number - */ - if (r->remaining) { - cid->ecb->cbTotalBytes = (apr_size_t)r->remaining; - if (cid->ecb->cbTotalBytes > (apr_uint32_t)cid->dconf.read_ahead_buflen) - cid->ecb->cbAvailable = cid->dconf.read_ahead_buflen; - else - cid->ecb->cbAvailable = cid->ecb->cbTotalBytes; - } - else - { - cid->ecb->cbTotalBytes = 0xffffffff; - cid->ecb->cbAvailable = cid->dconf.read_ahead_buflen; - } - - cid->ecb->lpbData = apr_pcalloc(r->pool, cid->ecb->cbAvailable + 1); - - read = 0; - while (read < cid->ecb->cbAvailable && - ((res = ap_get_client_block(r, (char*)cid->ecb->lpbData + read, - cid->ecb->cbAvailable - read)) > 0)) { - read += res; - } - - if (res < 0) { - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Although it's not to spec, IIS seems to null-terminate - * its lpdData string. So we will too. - */ - if (res == 0) - cid->ecb->cbAvailable = cid->ecb->cbTotalBytes = read; - else - cid->ecb->cbAvailable = read; - cid->ecb->lpbData[read] = '\0'; - } - else { - cid->ecb->cbTotalBytes = 0; - cid->ecb->cbAvailable = 0; - cid->ecb->lpbData = NULL; - } - - /* To emulate async behavior... - * - * We create a cid->completed mutex and lock on it so that the - * app can believe is it running async. - * - * This request completes upon a notification through - * ServerSupportFunction(HSE_REQ_DONE_WITH_SESSION), which - * unlocks this mutex. If the HttpExtensionProc() returns - * HSE_STATUS_PENDING, we will attempt to gain this lock again - * which may *only* happen once HSE_REQ_DONE_WITH_SESSION has - * unlocked the mutex. - */ - if (cid->dconf.fake_async) { - rv = apr_thread_mutex_create(&cid->completed, - APR_THREAD_MUTEX_UNNESTED, - r->pool); - if (cid->completed && (rv == APR_SUCCESS)) { - rv = apr_thread_mutex_lock(cid->completed); - } - - if (!cid->completed || (rv != APR_SUCCESS)) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: Failed to create completion mutex"); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - - /* All right... try and run the sucker */ - rv = (*isa->HttpExtensionProc)(cid->ecb); - - /* Check for a log message - and log it */ - if (cid->ecb->lpszLogData && *cid->ecb->lpszLogData) - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "ISAPI: %s: %s", r->filename, cid->ecb->lpszLogData); - - switch(rv) { - case 0: /* Strange, but MS isapi accepts this as success */ - case HSE_STATUS_SUCCESS: - case HSE_STATUS_SUCCESS_AND_KEEP_CONN: - /* Ignore the keepalive stuff; Apache handles it just fine without - * the ISAPI Handler's "advice". - * Per Microsoft: "In IIS versions 4.0 and later, the return - * values HSE_STATUS_SUCCESS and HSE_STATUS_SUCCESS_AND_KEEP_CONN - * are functionally identical: Keep-Alive connections are - * maintained, if supported by the client." - * ... so we were pat all this time - */ - break; - - case HSE_STATUS_PENDING: - /* emulating async behavior... - */ - if (cid->completed) { - /* The completion port was locked prior to invoking - * HttpExtensionProc(). Once we can regain the lock, - * when ServerSupportFunction(HSE_REQ_DONE_WITH_SESSION) - * is called by the extension to release the lock, - * we may finally destroy the request. - */ - (void)apr_thread_mutex_lock(cid->completed); - break; - } - else if (cid->dconf.log_unsupported) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "ISAPI: asynch I/O result HSE_STATUS_PENDING " - "from HttpExtensionProc() is not supported: %s", - r->filename); - r->status = HTTP_INTERNAL_SERVER_ERROR; - } - break; - - case HSE_STATUS_ERROR: - /* end response if we have yet to do so. - */ - ap_log_rerror(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), r, - "ISAPI: HSE_STATUS_ERROR result from " - "HttpExtensionProc(): %s", r->filename); - r->status = HTTP_INTERNAL_SERVER_ERROR; - break; - - default: - ap_log_rerror(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), r, - "ISAPI: unrecognized result code %d " - "from HttpExtensionProc(): %s ", - rv, r->filename); - r->status = HTTP_INTERNAL_SERVER_ERROR; - break; - } - - /* Flush the response now, including headers-only responses */ - if (cid->headers_set || cid->response_sent) { - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *b; - apr_status_t rv; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - rv = ap_pass_brigade(r->output_filters, bb); - cid->response_sent = 1; - - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, - "ISAPI: ap_pass_brigade failed to " - "complete the response: %s ", r->filename); - } - - return OK; /* NOT r->status, even if it has changed. */ - } - - /* As the client returned no error, and if we did not error out - * ourselves, trust dwHttpStatusCode to say something relevant. - */ - if (!ap_is_HTTP_SERVER_ERROR(r->status) && cid->ecb->dwHttpStatusCode) { - r->status = cid->ecb->dwHttpStatusCode; - } - - /* For all missing-response situations simply return the status, - * and let the core respond to the client. - */ - return r->status; -} - -/********************************************************** - * - * ISAPI Module Setup Hooks - * - **********************************************************/ - -static int isapi_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) -{ - apr_status_t rv; - - apr_pool_create_ex(&loaded.pool, pconf, NULL, NULL); - if (!loaded.pool) { - ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, NULL, - "ISAPI: could not create the isapi cache pool"); - return APR_EGENERAL; - } - - loaded.hash = apr_hash_make(loaded.pool); - if (!loaded.hash) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, - "ISAPI: Failed to create module cache"); - return APR_EGENERAL; - } - - rv = apr_thread_mutex_create(&loaded.lock, APR_THREAD_MUTEX_DEFAULT, - loaded.pool); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, rv, 0, NULL, - "ISAPI: Failed to create module cache lock"); - return rv; - } - return OK; -} - -static void isapi_hooks(apr_pool_t *cont) -{ - ap_hook_pre_config(isapi_pre_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_handler(isapi_handler, NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA isapi_module = { - STANDARD20_MODULE_STUFF, - create_isapi_dir_config, /* create per-dir config */ - merge_isapi_dir_configs, /* merge per-dir config */ - NULL, /* server config */ - NULL, /* merge server config */ - isapi_cmds, /* command apr_table_t */ - isapi_hooks /* register hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.dsp b/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.dsp deleted file mode 100644 index 08cbda21..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.dsp +++ /dev/null @@ -1,132 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_isapi" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_isapi - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_isapi.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_isapi.mak" CFG="mod_isapi - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_isapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_isapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_isapi - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_isapi_src" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:"Release/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so /opt:ref - -!ELSEIF "$(CFG)" == "mod_isapi - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_isapi_src" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so - -!ENDIF - -# Begin Target - -# Name "mod_isapi - Win32 Release" -# Name "mod_isapi - Win32 Debug" -# Begin Source File - -SOURCE=.\mod_isapi.c -# End Source File -# Begin Source File - -SOURCE=.\mod_isapi.h -# End Source File -# Begin Source File - -SOURCE=.\mod_isapi.rc -# End Source File -# Begin Source File - -SOURCE=..\..\..\build\win32\win32ver.awk - -!IF "$(CFG)" == "mod_isapi - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\..\build\win32\win32ver.awk - -".\mod_isapi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../../build/win32/win32ver.awk mod_isapi.so "isapi_module for Apache" ../../../include/ap_release.h > .\mod_isapi.rc - -# End Custom Build - -!ELSEIF "$(CFG)" == "mod_isapi - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\..\build\win32\win32ver.awk - -".\mod_isapi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../../build/win32/win32ver.awk mod_isapi.so "isapi_module for Apache" ../../../include/ap_release.h > .\mod_isapi.rc - -# End Custom Build - -!ENDIF - -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.h b/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.h deleted file mode 100644 index 33524bcb..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_isapi.h +++ /dev/null @@ -1,271 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file mod_isapi.h - * @brief ISAPI module extension to Apache - * - * @defgroup MOD_ISAPI mod_isapi - * @ingroup APACHE_MODS - * @{ - */ - -#ifndef MOD_ISAPI_H -#define MOD_ISAPI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* The Version Information storage passed to a module on startup - * via the GetExtensionVersion() entry point. - */ -typedef struct HSE_VERSION_INFO { - apr_uint32_t dwExtensionVersion; - char lpszExtensionDesc[256]; -} HSE_VERSION_INFO; - -/* The startup entry point that must be exported by every ISAPI handler - */ -int APR_THREAD_FUNC GetExtensionVersion(HSE_VERSION_INFO *ver_info); -typedef int (APR_THREAD_FUNC *PFN_GETEXTENSIONVERSION)(HSE_VERSION_INFO *ver_info); - -/* Our internal 'HCONN' representation, always opaque to the user. - */ -typedef struct isapi_cid isapi_cid; -typedef struct isapi_cid *HCONN; - -/* Prototypes of the essential functions exposed by mod_isapi - * for the module to communicate with Apache. - */ -typedef int (APR_THREAD_FUNC - *PFN_GETSERVERVARIABLE)(HCONN cid, - char *variable_name, - void *buf_data, - apr_uint32_t *buf_size); -typedef int (APR_THREAD_FUNC - *PFN_WRITECLIENT)(HCONN cid, - void *buf_data, - apr_uint32_t *buf_size, - apr_uint32_t flags); -typedef int (APR_THREAD_FUNC - *PFN_READCLIENT)(HCONN cid, - void *buf_data, - apr_uint32_t *buf_size); -typedef int (APR_THREAD_FUNC - *PFN_SERVERSUPPORTFUNCTION)(HCONN cid, - apr_uint32_t HSE_code, - void *buf_data, - apr_uint32_t *buf_size, - apr_uint32_t *flags); - -/* The ecb structure is passed on each invocation of the module - */ -typedef struct EXTENSION_CONTROL_BLOCK { - apr_uint32_t cbSize; - apr_uint32_t dwVersion; - HCONN ConnID; - apr_uint32_t dwHttpStatusCode; - char lpszLogData[80]; - char *lpszMethod; - char *lpszQueryString; - char *lpszPathInfo; - char *lpszPathTranslated; - apr_uint32_t cbTotalBytes; - apr_uint32_t cbAvailable; - unsigned char *lpbData; - char *lpszContentType; - - PFN_GETSERVERVARIABLE GetServerVariable; - PFN_WRITECLIENT WriteClient; - PFN_READCLIENT ReadClient; - PFN_SERVERSUPPORTFUNCTION ServerSupportFunction; -} EXTENSION_CONTROL_BLOCK; - -/* Status/Headers structure to pass to HSE_SEND_HEADER_EX, - * an MS extension to ServerSupportFunction - */ -typedef struct HSE_SEND_HEADER_EX_INFO { - const char * pszStatus; /* HTTP status text, such as "200 OK" */ - const char * pszHeader; /* HTTP header lines text, such as - * "Content-type: text/plain\r\n" - * "Content-Language: en\r\n" - * Note that (in spite of cchFoo lengths below) - * NULL characters will interfere in headers. - */ - apr_uint32_t cchStatus; /* length of pszStatus text */ - apr_uint32_t cchHeader; /* length of pszHeader text */ - int fKeepConn; /* Ignored: used to set keep-alive status, - * but Apache follows the client's negotiated - * HTTP contract to decide. - */ -} HSE_SEND_HEADER_EX_INFO; - -/* Our only 'supported' MS extended flag bit for TransmitFile, - * HSE_IO_SEND_HEADERS indicates that Status+Headers are present - * in the pszStatusCode member of the HSE_TF_INFO structure. - */ -#define HSE_IO_SEND_HEADERS 8 - -/* The remaining flags are MS extended flag bits that bear little - * relation to Apache; the rules that the Apache server obeys follow - * its own design and HTTP protocol filter rules. - * - * We do not support async, however, we fake it. If HSE_IO_SYNC is - * not passed, and a completion context was defined, we will invoke the - * completion function immediately following the transfer, and then - * return to the caller. If HSE_IO_SYNC is passed, there is no call - * neccessary to the completion context. - */ -#define HSE_IO_SYNC 1 -#define HSE_IO_ASYNC 2 -#define HSE_IO_DISCONNECT_AFTER_SEND 4 -#define HSE_IO_NODELAY 4096 - -/* The Completion function prototype. This callback may be fixed with - * the HSE_REQ_IO_COMPLETION ServerSupportFunction call, or overriden - * for the HSE_REQ_TRANSMIT_FILE call. - */ -typedef void (APR_THREAD_FUNC *PFN_HSE_IO_COMPLETION) - (EXTENSION_CONTROL_BLOCK *ecb, - void *ctxt, - apr_uint32_t cbIO, - apr_uint32_t dwError); - -/* TransmitFile structure to pass to HSE_REQ_TRANSMIT_FILE, an MS extension - */ -typedef struct HSE_TF_INFO { - PFN_HSE_IO_COMPLETION pfnHseIO; /* Overrides the default setting of - * HSE_REQ_IO_COMPLETION if not NULL - */ - void *pContext; - apr_os_file_t hFile; /* HANDLE/fd to transmit */ - const char *pszStatusCode; /* Ignored if HSE_IO_SEND_HEADERS is - * not set. Includes HTTP status text - * plus header text lines, such as - * "200 OK\r\n" - * "Content-type: text/plain\r\n" - */ - apr_uint32_t BytesToWrite; /* 0 is write-all */ - apr_uint32_t Offset; /* File Offset */ - void *pHead; /* Prefix with *pHead body text */ - apr_uint32_t HeadLength; /* Length of *pHead body text */ - void *pTail; /* Prefix with *pTail body text */ - apr_uint32_t TailLength; /* Length of *pTail body text */ - apr_uint32_t dwFlags; /* bit flags described above */ -} HSE_TF_INFO; - -typedef struct HSE_URL_MAPEX_INFO { - char lpszPath[260]; - apr_uint32_t dwFlags; - apr_uint32_t cchMatchingPath; - apr_uint32_t cchMatchingURL; - apr_uint32_t dwReserved1; - apr_uint32_t dwReserved2; -} HSE_URL_MAPEX_INFO; - -/* Original ISAPI ServerSupportFunction() HSE_code methods */ -#define HSE_REQ_SEND_URL_REDIRECT_RESP 1 -#define HSE_REQ_SEND_URL 2 -#define HSE_REQ_SEND_RESPONSE_HEADER 3 -#define HSE_REQ_DONE_WITH_SESSION 4 - -/* MS Extented methods to ISAPI ServerSupportFunction() HSE_code */ -#define HSE_REQ_MAP_URL_TO_PATH 1001 /* Emulated */ -#define HSE_REQ_GET_SSPI_INFO 1002 /* Not Supported */ -#define HSE_APPEND_LOG_PARAMETER 1003 /* Supported */ -#define HSE_REQ_IO_COMPLETION 1005 /* Emulated */ -#define HSE_REQ_TRANSMIT_FILE 1006 /* Async Emulated */ -#define HSE_REQ_REFRESH_ISAPI_ACL 1007 /* Not Supported */ -#define HSE_REQ_IS_KEEP_CONN 1008 /* Supported */ -#define HSE_REQ_ASYNC_READ_CLIENT 1010 /* Emulated */ -/* Added with ISAPI 4.0 */ -#define HSE_REQ_GET_IMPERSONATION_TOKEN 1011 /* Not Supported */ -#define HSE_REQ_MAP_URL_TO_PATH_EX 1012 /* Emulated */ -#define HSE_REQ_ABORTIVE_CLOSE 1014 /* Ignored */ -/* Added after ISAPI 4.0 in IIS 5.0 */ -#define HSE_REQ_GET_CERT_INFO_EX 1015 /* Not Supported */ -#define HSE_REQ_SEND_RESPONSE_HEADER_EX 1016 /* Supported (no nulls!) */ -#define HSE_REQ_CLOSE_CONNECTION 1017 /* Ignored */ -#define HSE_REQ_IS_CONNECTED 1018 /* Supported */ -#define HSE_REQ_EXTENSION_TRIGGER 1020 /* Not Supported */ - -/* The request entry point that must be exported by every ISAPI handler - */ -apr_uint32_t APR_THREAD_FUNC HttpExtensionProc(EXTENSION_CONTROL_BLOCK *ecb); -typedef apr_uint32_t (APR_THREAD_FUNC - *PFN_HTTPEXTENSIONPROC)(EXTENSION_CONTROL_BLOCK *ecb); - -/* Allowable return values from HttpExtensionProc (apparently 0 is also - * accepted by MS IIS, and we will respect it as Success.) - * If the HttpExtensionProc returns HSE_STATUS_PENDING, we will create - * a wait mutex and lock on it, until HSE_REQ_DONE_WITH_SESSION is called. - */ -#define HSE_STATUS_SUCCESS 1 -#define HSE_STATUS_SUCCESS_AND_KEEP_CONN 2 /* 1 vs 2 Ignored, we choose */ -#define HSE_STATUS_PENDING 3 /* Emulated (thread lock) */ -#define HSE_STATUS_ERROR 4 - -/* Anticipated error code for common faults within mod_isapi itself - */ -#ifndef ERROR_INSUFFICIENT_BUFFER -#define ERROR_INSUFFICIENT_BUFFER ENOBUFS -#endif -#ifndef ERROR_INVALID_INDEX -#define ERROR_INVALID_INDEX EINVAL -#endif -#ifndef ERROR_INVALID_PARAMETER -#define ERROR_INVALID_PARAMETER EINVAL -#endif -#ifndef ERROR_READ_FAULT -#define ERROR_READ_FAULT EIO -#endif -#ifndef ERROR_WRITE_FAULT -#define ERROR_WRITE_FAULT EIO -#endif -#ifndef ERROR_SUCCESS -#define ERROR_SUCCESS 0 -#endif - -/* Valid flags passed with TerminateExtension() - */ -#define HSE_TERM_MUST_UNLOAD 1 -#define HSE_TERM_ADVISORY_UNLOAD 2 - -/* The shutdown entry point óptionally exported by an ISAPI handler, passed - * HSE_TERM_MUST_UNLOAD or HSE_TERM_ADVISORY_UNLOAD. The module may return - * if passed HSE_TERM_ADVISORY_UNLOAD, and the module will remain loaded. - * If the module returns 1 to HSE_TERM_ADVISORY_UNLOAD it is immediately - * unloaded. If the module is passed HSE_TERM_MUST_UNLOAD, its return value - * is ignored. - */ -int APR_THREAD_FUNC TerminateExtension(apr_uint32_t flags); -typedef int (APR_THREAD_FUNC *PFN_TERMINATEEXTENSION)(apr_uint32_t flags); - -/* Module may return 0 if passed HSE_TERM_ADVISORY_UNLOAD, and the module - * will remain loaded, or 1 if it consents to being unloaded. If the module - * is passed HSE_TERM_MUST_UNLOAD, it's return value is ignored. - */ -#define HSE_TERM_MUST_UNLOAD 1 -#define HSE_TERM_ADVISORY_UNLOAD 2 - -#ifdef __cplusplus -} -#endif - -#endif /* !MOD_ISAPI_H */ -/** @} */ - diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_win32.c b/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_win32.c deleted file mode 100644 index 38b7b3b0..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/mod_win32.c +++ /dev/null @@ -1,553 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 - -#include "apr_strings.h" -#include "apr_portable.h" -#include "apr_buckets.h" -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_log.h" -#include "util_script.h" -#include "mod_core.h" -#include "mod_cgi.h" -#include "apr_lib.h" -#include "ap_regkey.h" - -extern OSVERSIONINFO osver; /* hiding in mpm_winnt.c */ -static int win_nt; - -/* - * CGI Script stuff for Win32... - */ -typedef enum { eFileTypeUNKNOWN, eFileTypeBIN, eFileTypeEXE16, eFileTypeEXE32, - eFileTypeSCRIPT } file_type_e; -typedef enum { INTERPRETER_SOURCE_UNSET, INTERPRETER_SOURCE_REGISTRY_STRICT, - INTERPRETER_SOURCE_REGISTRY, INTERPRETER_SOURCE_SHEBANG - } interpreter_source_e; -AP_DECLARE(file_type_e) ap_get_win32_interpreter(const request_rec *, - char **interpreter, - char **arguments); - -module AP_MODULE_DECLARE_DATA win32_module; - -typedef struct { - /* Where to find interpreter to run scripts */ - interpreter_source_e script_interpreter_source; -} win32_dir_conf; - -static void *create_win32_dir_config(apr_pool_t *p, char *dir) -{ - win32_dir_conf *conf; - conf = (win32_dir_conf*)apr_palloc(p, sizeof(win32_dir_conf)); - conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET; - return conf; -} - -static void *merge_win32_dir_configs(apr_pool_t *p, void *basev, void *addv) -{ - win32_dir_conf *new; - win32_dir_conf *base = (win32_dir_conf *) basev; - win32_dir_conf *add = (win32_dir_conf *) addv; - - new = (win32_dir_conf *) apr_pcalloc(p, sizeof(win32_dir_conf)); - new->script_interpreter_source = (add->script_interpreter_source - != INTERPRETER_SOURCE_UNSET) - ? add->script_interpreter_source - : base->script_interpreter_source; - return new; -} - -static const char *set_interpreter_source(cmd_parms *cmd, void *dv, - char *arg) -{ - win32_dir_conf *d = (win32_dir_conf *)dv; - if (!strcasecmp(arg, "registry")) { - d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY; - } - else if (!strcasecmp(arg, "registry-strict")) { - d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY_STRICT; - } - else if (!strcasecmp(arg, "script")) { - d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG; - } - else { - return apr_pstrcat(cmd->temp_pool, "ScriptInterpreterSource \"", arg, - "\" must be \"registry\", \"registry-strict\" or " - "\"script\"", NULL); - } - return NULL; -} - -/* XXX: prep_string should translate the string into unicode, - * such that it is compatible with whatever codepage the client - * will read characters 80-ff. For the moment, use the unicode - * values 0080-00ff. This isn't trivial, since the code page - * varies between msdos and Windows applications. - * For subsystem 2 [GUI] the default is the system Ansi CP. - * For subsystem 3 [CLI] the default is the system OEM CP. - */ -static void prep_string(const char ** str, apr_pool_t *p) -{ - const char *ch = *str; - char *ch2; - int widen = 0; - - if (!ch) { - return; - } - while (*ch) { - if (*(ch++) & 0x80) { - ++widen; - } - } - if (!widen) { - return; - } - widen += (ch - *str) + 1; - ch = *str; - *str = ch2 = apr_palloc(p, widen); - while (*ch) { - if (*ch & 0x80) { - /* sign extension won't hurt us here */ - *(ch2++) = 0xC0 | ((*ch >> 6) & 0x03); - *(ch2++) = 0x80 | (*(ch++) & 0x3f); - } - else { - *(ch2++) = *(ch++); - } - } - *(ch2++) = '\0'; -} - -/* Somewhat more exciting ... figure out where the registry has stashed the - * ExecCGI or Open command - it may be nested one level deep (or more???) - */ -static char* get_interpreter_from_win32_registry(apr_pool_t *p, - const char* ext, - int strict) -{ - apr_status_t rv; - ap_regkey_t *name_key = NULL; - ap_regkey_t *type_key; - ap_regkey_t *key; - char execcgi_path[] = "SHELL\\EXECCGI\\COMMAND"; - char execopen_path[] = "SHELL\\OPEN\\COMMAND"; - char *type_name; - char *buffer; - - if (!ext) { - return NULL; - } - /* - * Future optimization: - * When the registry is successfully searched, store the strings for - * interpreter and arguments in an ext hash to speed up subsequent look-ups - */ - - /* Open the key associated with the script filetype extension */ - rv = ap_regkey_open(&type_key, AP_REGKEY_CLASSES_ROOT, ext, APR_READ, p); - - if (rv != APR_SUCCESS) { - return NULL; - } - - /* Retrieve the name of the script filetype extension */ - rv = ap_regkey_value_get(&type_name, type_key, "", p); - - if (rv == APR_SUCCESS && type_name[0]) { - /* Open the key associated with the script filetype extension */ - rv = ap_regkey_open(&name_key, AP_REGKEY_CLASSES_ROOT, type_name, - APR_READ, p); - } - - /* Open the key for the script command path by: - * - * 1) the 'named' filetype key for ExecCGI/Command - * 2) the extension's type key for ExecCGI/Command - * - * and if the strict arg is false, then continue trying: - * - * 3) the 'named' filetype key for Open/Command - * 4) the extension's type key for Open/Command - */ - - if (name_key) { - if ((rv = ap_regkey_open(&key, name_key, execcgi_path, APR_READ, p)) - == APR_SUCCESS) { - rv = ap_regkey_value_get(&buffer, key, "", p); - ap_regkey_close(name_key); - } - } - - if (!name_key || (rv != APR_SUCCESS)) { - if ((rv = ap_regkey_open(&key, type_key, execcgi_path, APR_READ, p)) - == APR_SUCCESS) { - rv = ap_regkey_value_get(&buffer, key, "", p); - ap_regkey_close(type_key); - } - } - - if (!strict && name_key && (rv != APR_SUCCESS)) { - if ((rv = ap_regkey_open(&key, name_key, execopen_path, APR_READ, p)) - == APR_SUCCESS) { - rv = ap_regkey_value_get(&buffer, key, "", p); - ap_regkey_close(name_key); - } - } - - if (!strict && (rv != APR_SUCCESS)) { - if ((rv = ap_regkey_open(&key, type_key, execopen_path, APR_READ, p)) - == APR_SUCCESS) { - rv = ap_regkey_value_get(&buffer, key, "", p); - ap_regkey_close(type_key); - } - } - - if (name_key) { - ap_regkey_close(name_key); - } - - ap_regkey_close(type_key); - - if (rv != APR_SUCCESS || !buffer[0]) { - return NULL; - } - - return buffer; -} - - -static apr_array_header_t *split_argv(apr_pool_t *p, const char *interp, - const char *cgiprg, const char *cgiargs) -{ - apr_array_header_t *args = apr_array_make(p, 8, sizeof(char*)); - char *d = apr_palloc(p, strlen(interp)+1); - const char *ch = interp; - const char **arg; - int prgtaken = 0; - int argtaken = 0; - int inquo; - int sl; - - while (*ch) { - /* Skip on through Deep Space */ - if (apr_isspace(*ch)) { - ++ch; continue; - } - /* One Arg */ - if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '*')) { - const char *cgiarg = cgiargs; - argtaken = 1; - for (;;) { - char *w = ap_getword_nulls(p, &cgiarg, '+'); - if (!*w) { - break; - } - ap_unescape_url(w); - if (win_nt) { - prep_string(&w, p); - } - arg = (const char**)apr_array_push(args); - *arg = ap_escape_shell_cmd(p, w); - } - ch += 2; - continue; - } - if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '1')) { - /* Todo: Make short name!!! */ - prgtaken = 1; - arg = (const char**)apr_array_push(args); - if (*ch == '%') { - char *repl = apr_pstrdup(p, cgiprg); - *arg = repl; - while ((repl = strchr(repl, '/'))) { - *repl++ = '\\'; - } - } - else { - *arg = cgiprg; - } - ch += 2; - continue; - } - if ((*ch == '\"') && ((*(ch + 1) == '$') - || (*(ch + 1) == '%')) && (*(ch + 2) == '1') - && (*(ch + 3) == '\"')) { - prgtaken = 1; - arg = (const char**)apr_array_push(args); - if (*(ch + 1) == '%') { - char *repl = apr_pstrdup(p, cgiprg); - *arg = repl; - while ((repl = strchr(repl, '/'))) { - *repl++ = '\\'; - } - } - else { - *arg = cgiprg; - } - ch += 4; - continue; - } - arg = (const char**)apr_array_push(args); - *arg = d; - inquo = 0; - while (*ch) { - if (apr_isspace(*ch) && !inquo) { - ++ch; break; - } - /* Get 'em backslashes */ - for (sl = 0; *ch == '\\'; ++sl) { - *d++ = *ch++; - } - if (sl & 1) { - /* last unmatched '\' + '"' sequence is a '"' */ - if (*ch == '\"') { - *(d - 1) = *ch++; - } - continue; - } - if (*ch == '\"') { - /* '""' sequence within quotes is a '"' */ - if (*++ch == '\"' && inquo) { - *d++ = *ch++; continue; - } - /* Flip quote state */ - inquo = !inquo; - if (apr_isspace(*ch) && !inquo) { - ++ch; break; - } - /* All other '"'s are Munched */ - continue; - } - /* Anything else is, well, something else */ - *d++ = *ch++; - } - /* Term that arg, already pushed on args */ - *d++ = '\0'; - } - - if (!prgtaken) { - arg = (const char**)apr_array_push(args); - *arg = cgiprg; - } - - if (!argtaken) { - const char *cgiarg = cgiargs; - for (;;) { - char *w = ap_getword_nulls(p, &cgiarg, '+'); - if (!*w) { - break; - } - ap_unescape_url(w); - if (win_nt) { - prep_string(&w, p); - } - arg = (const char**)apr_array_push(args); - *arg = ap_escape_shell_cmd(p, w); - } - } - - arg = (const char**)apr_array_push(args); - *arg = NULL; - - return args; -} - - -static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv, - request_rec *r, apr_pool_t *p, - cgi_exec_info_t *e_info) -{ - const apr_array_header_t *elts_arr = apr_table_elts(r->subprocess_env); - const apr_table_entry_t *elts = (apr_table_entry_t *) elts_arr->elts; - const char *ext = NULL; - const char *interpreter = NULL; - win32_dir_conf *d; - apr_file_t *fh; - const char *args = ""; - int i; - - d = (win32_dir_conf *)ap_get_module_config(r->per_dir_config, - &win32_module); - - if (e_info->cmd_type) { - /* We have to consider that the client gets any QUERY_ARGS - * without any charset interpretation, use prep_string to - * create a string of the literal QUERY_ARGS bytes. - */ - *cmd = r->filename; - if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) { - args = r->args; - } - } - /* Handle the complete file name, we DON'T want to follow suexec, since - * an unrooted command is as predictable as shooting craps in Win32. - * Notice that unlike most mime extension parsing, we have to use the - * win32 parsing here, therefore the final extension is the only one - * we will consider. - */ - ext = strrchr(apr_filename_of_pathname(*cmd), '.'); - - /* If the file has an extension and it is not .com and not .exe and - * we've been instructed to search the registry, then do so. - * Let apr_proc_create do all of the .bat/.cmd dirty work. - */ - if (ext && (!strcasecmp(ext,".exe") || !strcasecmp(ext,".com") - || !strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) { - interpreter = ""; - } - if (!interpreter && ext - && (d->script_interpreter_source - == INTERPRETER_SOURCE_REGISTRY - || d->script_interpreter_source - == INTERPRETER_SOURCE_REGISTRY_STRICT)) { - /* Check the registry */ - int strict = (d->script_interpreter_source - == INTERPRETER_SOURCE_REGISTRY_STRICT); - interpreter = get_interpreter_from_win32_registry(r->pool, ext, - strict); - if (interpreter && e_info->cmd_type != APR_SHELLCMD) { - e_info->cmd_type = APR_PROGRAM_PATH; - } - else { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, - strict ? "No ExecCGI verb found for files of type '%s'." - : "No ExecCGI or Open verb found for files of type '%s'.", - ext); - } - } - if (!interpreter) { - apr_status_t rv; - char buffer[1024]; - apr_size_t bytes = sizeof(buffer); - int i; - - /* Need to peek into the file figure out what it really is... - * ### aught to go back and build a cache for this one of these days. - */ - if (((rv = apr_file_open(&fh, *cmd, APR_READ | APR_BUFFERED, - APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) - || ((rv = apr_file_read(fh, buffer, &bytes)) != APR_SUCCESS)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "Failed to read cgi file %s for testing", *cmd); - return rv; - } - apr_file_close(fh); - - /* Script or executable, that is the question... */ - if ((buffer[0] == '#') && (buffer[1] == '!')) { - /* Assuming file is a script since it starts with a shebang */ - for (i = 2; i < sizeof(buffer); i++) { - if ((buffer[i] == '\r') || (buffer[i] == '\n')) { - buffer[i] = '\0'; - break; - } - } - if (i < sizeof(buffer)) { - interpreter = buffer + 2; - while (apr_isspace(*interpreter)) { - ++interpreter; - } - if (e_info->cmd_type != APR_SHELLCMD) { - e_info->cmd_type = APR_PROGRAM_PATH; - } - } - } - else { - /* Not a script, is it an executable? */ - IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer; - if ((bytes >= sizeof(IMAGE_DOS_HEADER)) - && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) { - if (hdr->e_lfarlc < 0x40) { - /* Ought to invoke this 16 bit exe by a stub, (cmd /c?) */ - interpreter = ""; - } - else { - interpreter = ""; - } - } - } - } - if (!interpreter) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "%s is not executable; ensure interpreted scripts have " - "\"#!\" first line", *cmd); - return APR_EBADF; - } - - *argv = (const char **)(split_argv(p, interpreter, *cmd, - args)->elts); - *cmd = (*argv)[0]; - - e_info->detached = 1; - - /* XXX: Must fix r->subprocess_env to follow utf-8 conventions from - * the client's octets so that win32 apr_proc_create is happy. - * The -best- way is to determine if the .exe is unicode aware - * (using 0x0080-0x00ff) or is linked as a command or windows - * application (following the OEM or Ansi code page in effect.) - */ - for (i = 0; i < elts_arr->nelts; ++i) { - if (win_nt && elts[i].key && *elts[i].key - && (strncmp(elts[i].key, "HTTP_", 5) == 0 - || strncmp(elts[i].key, "SERVER_", 7) == 0 - || strncmp(elts[i].key, "REQUEST_", 8) == 0 - || strcmp(elts[i].key, "QUERY_STRING") == 0 - || strcmp(elts[i].key, "PATH_INFO") == 0 - || strcmp(elts[i].key, "PATH_TRANSLATED") == 0)) { - prep_string((const char**) &elts[i].val, r->pool); - } - } - return APR_SUCCESS; -} - -static int win32_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *ptemp) -{ - win_nt = (osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); - return OK; -} - -static void register_hooks(apr_pool_t *p) -{ - APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command); - ap_hook_pre_config(win32_pre_config, NULL, NULL, APR_HOOK_MIDDLE); -} - -static const command_rec win32_cmds[] = { -AP_INIT_TAKE1("ScriptInterpreterSource", set_interpreter_source, NULL, - OR_FILEINFO, - "Where to find interpreter to run Win32 scripts " - "(Registry or script shebang line)"), -{ NULL } -}; - -module AP_MODULE_DECLARE_DATA win32_module = { - STANDARD20_MODULE_STUFF, - create_win32_dir_config, /* create per-dir config */ - merge_win32_dir_configs, /* merge per-dir config */ - NULL, /* server config */ - NULL, /* merge server config */ - win32_cmds, /* command apr_table_t */ - register_hooks /* register hooks */ -}; - -#endif /* defined WIN32 */ diff --git a/rubbos/app/httpd-2.0.64/modules/arch/win32/modules.mk b/rubbos/app/httpd-2.0.64/modules/arch/win32/modules.mk deleted file mode 100644 index ceb52a1b..00000000 --- a/rubbos/app/httpd-2.0.64/modules/arch/win32/modules.mk +++ /dev/null @@ -1,3 +0,0 @@ -DISTCLEAN_TARGETS = modules.mk -static = -shared = |