⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_isapi.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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> * * This module implements Microsoft's ISAPI, allowing Apache (when running * under Windows) to load Internet Server Applications (ISAPI extensions). * It implements all of the ISAPI 2.0 specification, except for the  * "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI * extensions that use only synchronous I/O and are compatible with the * ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should * function as well). * * To load, simply place the ISA in a location in the document tree. * Then add an "AddHandler isapi-isa dll" into your config file. * You should now be able to load ISAPI DLLs just be reffering to their * URLs. Make sure the ExecCGI option is active in the directory * the ISA is in. */#ifdef WIN32/* A lousy hack to include ap_check_cmd_context(): */#define CORE_PRIVATE #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 <stdlib.h>/* We use the exact same header file as the original */#include <HttpExt.h>/* Seems IIS does not enforce the requirement for \r\n termination on HSE_REQ_SEND_RESPONSE_HEADER,   define this to conform */#define RELAX_HEADER_RULE#if !defined(HSE_REQ_SEND_RESPONSE_HEADER_EX) \ || !defined(HSE_REQ_MAP_URL_TO_PATH_EX)#pragma message("WARNING: This build of Apache is missing the recent changes")#pragma message("in the Microsoft Win32 Platform SDK; some mod_isapi features")#pragma message("will be disabled.  To obtain the latest Platform SDK files,")#pragma message("please refer to:")#pragma message("http://msdn.microsoft.com/downloads/sdks/platform/platform.asp")#endifmodule isapi_module;static DWORD ReadAheadBuffer = 49152;static int LogNotSupported = -1;static int AppendLogToErrors = 0;static int AppendLogToQuery = 0;/* Our "Connection ID" structure */typedef struct {    LPEXTENSION_CONTROL_BLOCK ecb;    request_rec *r;    int status;} isapi_cid;/* Declare the ISAPI functions */BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,                               LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer);BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,                         DWORD dwReserved);BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize);BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,                                   LPVOID lpvBuffer, LPDWORD lpdwSize,                                   LPDWORD lpdwDataType);/*    The optimiser blows it totally here. What happens is that autos are addressed relative to the    stack pointer, which, of course, moves around. The optimiser seems to lose track of it somewhere    between setting isapi_entry and calling through it. We work around the problem by forcing it to    use frame pointers.*/#pragma optimize("y",off)int isapi_handler (request_rec *r) {    LPEXTENSION_CONTROL_BLOCK ecb =        ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));    HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));    HINSTANCE isapi_handle;    BOOL (*isapi_version)(HSE_VERSION_INFO *); /* entry point 1 */    DWORD (*isapi_entry)(LPEXTENSION_CONTROL_BLOCK); /* entry point 2 */    BOOL (*isapi_term)(DWORD); /* optional entry point 3 */    isapi_cid *cid = ap_pcalloc(r->pool, sizeof(isapi_cid));    table *e = r->subprocess_env;    DWORD read;    char *p;    int retval;    int res;    /* Use similar restrictions as CGIs */    if (!(ap_allow_options(r) & OPT_EXECCGI))        return FORBIDDEN;    if (r->finfo.st_mode == 0)        return NOT_FOUND;    if (S_ISDIR(r->finfo.st_mode))        return FORBIDDEN;    if (!(isapi_handle = ap_os_dso_load(r->filename))) {        ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,                      "ISAPI Could not load DLL: %s", r->filename);        return SERVER_ERROR;    }    if (!(isapi_version =          (void *)(ap_os_dso_sym(isapi_handle, "GetExtensionVersion")))) {        ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,                      "DLL could not load GetExtensionVersion(): %s",                       r->filename);        ap_os_dso_unload(isapi_handle);        return SERVER_ERROR;    }    if (!(isapi_entry =          (void *)(ap_os_dso_sym(isapi_handle, "HttpExtensionProc")))) {        ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,                      "DLL could not load HttpExtensionProc(): %s",                       r->filename);        ap_os_dso_unload(isapi_handle);        return SERVER_ERROR;    }    isapi_term = (void *)(ap_os_dso_sym(isapi_handle, "TerminateExtension"));    /* Run GetExtensionVersion() */    if (!(*isapi_version)(pVer)) {        ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,                      "ISAPI GetExtensionVersion() failed: %s", r->filename);        ap_os_dso_unload(isapi_handle);        return SERVER_ERROR;    }    /* Set up variables.  There are a couple of special cases for ISAPI.     * XXX: These were taken verbatim from GetServerVariable, and should     * be reviewed carefully.     */    ap_add_common_vars(r);    ap_add_cgi_vars(r);    ap_table_setn(r->subprocess_env, "UNMAPPED_REMOTE_USER", "REMOTE_USER");    ap_table_setn(r->subprocess_env, "SERVER_PORT_SECURE", "0");    ap_table_setn(r->subprocess_env, "URL", r->uri);    /* Set up connection ID */    ecb->ConnID = (HCONN)cid;    cid->ecb = ecb;    cid->r = r;    cid->status = 0;    ecb->cbSize = sizeof(struct _EXTENSION_CONTROL_BLOCK);    ecb->dwVersion = MAKELONG(0, 2);    ecb->dwHttpStatusCode = 0;    strcpy(ecb->lpszLogData, "");    ecb->lpszMethod = ap_pstrdup(r->pool, r->method);    ecb->lpszQueryString = ap_pstrdup(r->pool, ap_table_get(e, "QUERY_STRING"));    ecb->lpszPathInfo = ap_pstrdup(r->pool, ap_table_get(e, "PATH_INFO"));    ecb->lpszPathTranslated = ap_pstrdup(r->pool, ap_table_get(e, "PATH_TRANSLATED"));    ecb->lpszContentType = ap_pstrdup(r->pool, ap_table_get(e, "CONTENT_TYPE"));    /* Set up client input */    if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {        if (isapi_term) (*isapi_term)( 2 /* HSE_TERM_MUST_UNLOAD */);        ap_os_dso_unload(isapi_handle);        return retval;    }    if (ap_should_client_block(r)) {        /* Time to start reading the appropriate amount of data,         * and allow the administrator to tweak the number         * TODO: add the httpd.conf option for ReadAheadBuffer.         */        if (r->remaining) {            ecb->cbTotalBytes = r->remaining;            if (ecb->cbTotalBytes > ReadAheadBuffer)                ecb->cbAvailable = ReadAheadBuffer;            else                ecb->cbAvailable = ecb->cbTotalBytes;        }        else        {            ecb->cbTotalBytes = 0xffffffff;            ecb->cbAvailable = ReadAheadBuffer;        }        ecb->lpbData = ap_pcalloc(r->pool, ecb->cbAvailable + 1);        p = ecb->lpbData;        read = 0;        while (read < ecb->cbAvailable &&               ((res = ap_get_client_block(r, ecb->lpbData + read,                                           ecb->cbAvailable - read)) > 0)) {            read += res;        }        if (res < 0) {            if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);            ap_os_dso_unload(isapi_handle);            return SERVER_ERROR;        }        /* Although its not to spec, IIS seems to null-terminate         * its lpdData string. So we will too.         *         * XXX: This must be an issue... backing out the null         * from the count of bytes.         */        if (res == 0)            ecb->cbAvailable = ecb->cbTotalBytes = read;        else            ecb->cbAvailable = read;        ecb->lpbData[read] = '\0';    }    else {        ecb->cbTotalBytes = 0;        ecb->cbAvailable = 0;        ecb->lpbData = NULL;    }    /* Set up the callbacks */    ecb->GetServerVariable = &GetServerVariable;    ecb->WriteClient = &WriteClient;    ecb->ReadClient = &ReadClient;    ecb->ServerSupportFunction = &ServerSupportFunction;    /* All right... try and load the sucker */    retval = (*isapi_entry)(ecb);    /* Set the status (for logging) */    if (ecb->dwHttpStatusCode)        r->status = ecb->dwHttpStatusCode;    /* Check for a log message - and log it */    if (ecb->lpszLogData && strcmp(ecb->lpszLogData, ""))        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,                      "ISAPI: %s: %s", ecb->lpszLogData, r->filename);    /* Soak up any remaining input */    if (r->remaining > 0) {        char argsbuffer[HUGE_STRING_LEN];        while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0);    }    /* All done with the DLL... get rid of it */    if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);    ap_os_dso_unload(isapi_handle);    switch(retval) {    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 ISA's "advice".         */        if (cid->status) /* We have a special status to return */            return cid->status;        return OK;    case HSE_STATUS_PENDING:   /* We don't support this */        if (LogNotSupported)            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r,                         "ISAPI asynchronous I/O not supported: %s",                          r->filename);    case HSE_STATUS_ERROR:    default:        return SERVER_ERROR;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -