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

📄 mod_isapi.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
    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) {        isapi_unload(isa, 0);        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) {            isapi_unload(isa, 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 */};

⌨️ 快捷键说明

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