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

📄 mod_isapi.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* 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;

⌨️ 快捷键说明

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