📄 mod_isapi.c
字号:
{ request_rec *r = ((isapi_cid *)ConnID)->r; apr_bucket_brigade *bb; apr_bucket *b; if (dwReserved == HSE_IO_SYNC) ; /* XXX: Fake it */ bb = apr_brigade_create(r->pool); b = apr_bucket_transient_create(Buffer, (apr_size_t)lpwdwBytes); APR_BRIGADE_INSERT_TAIL(bb, b); b = apr_bucket_eos_create(); APR_BRIGADE_INSERT_TAIL(bb, b); ap_pass_brigade(r->output_filters, bb); return TRUE;}BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize){ request_rec *r = ((isapi_cid *)ConnID)->r; DWORD read = 0; int res; if (r->remaining < (long) *lpdwSize) *lpdwSize = r->remaining; while (read < *lpdwSize && ((res = ap_get_client_block(r, (char*)lpvBuffer + read, *lpdwSize - read)) > 0)) { if (res < 0) { *lpdwSize = 0; if (!apr_get_os_error()) SetLastError(TODO_ERROR); /* XXX: Find the right error code */ return FALSE; } read += res; } *lpdwSize = read; return TRUE;}static apr_off_t SendResponseHeaderEx(isapi_cid *cid, const char *stat, const char *head, apr_size_t statlen, apr_size_t headlen){ int termarg; char *termch; if (!stat || statlen == 0 || !*stat) { stat = "Status: 200 OK"; } else { char *newstat; newstat = apr_palloc(cid->r->pool, statlen + 9); strcpy(newstat, "Status: "); apr_cpystrn(newstat + 8, stat, statlen + 1); stat = newstat; } if (!head || headlen == 0 || !*head) { head = "\r\n"; } else { if (head[headlen]) { /* Whoops... not NULL terminated */ head = apr_pstrndup(cid->r->pool, head, headlen); } } /* Parse them out, or die trying */ cid->r->status= ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, stat, head, NULL); cid->ecb->dwHttpStatusCode = cid->r->status; if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR) return -1; /* Headers will actually go when they are good and ready */ /* Any data left is sent directly by the caller, all we * give back is the size of the headers we consumed */ if (termch && (termarg == 1) && headlen > (termch - head)) { return termch - head; } return 0;}/* XXX: Is there is still an O(n^2) attack possible here? Please detail. */BOOL WINAPI ServerSupportFunction(HCONN hConn, DWORD dwHSERequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType){ isapi_cid *cid = (isapi_cid *)hConn; request_rec *r = cid->r; request_rec *subreq; switch (dwHSERequest) { case 1: /* 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", lpvBuffer); cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; return TRUE; case 2: /* 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! */ (char*)lpvBuffer = apr_pstrdup(r->pool, (char*)lpvBuffer); ap_internal_redirect((char*)lpvBuffer, r); return TRUE; case 3: /* HSE_REQ_SEND_RESPONSE_HEADER */ { /* Parse them out, or die trying */ apr_size_t statlen = 0, headlen = 0; int ate; if (lpvBuffer) statlen = strlen((char*) lpvBuffer); if (lpdwDataType) headlen = strlen((char*) lpdwDataType); ate = SendResponseHeaderEx(cid, (char*) lpvBuffer, (char*) lpdwDataType, statlen, headlen); if (ate < 0) { SetLastError(TODO_ERROR); return FALSE; } else if (ate < headlen) { apr_bucket_brigade *bb; apr_bucket *b; bb = apr_brigade_create(cid->r->pool); b = apr_bucket_transient_create((char*) lpdwDataType + ate, headlen - ate); APR_BRIGADE_INSERT_TAIL(bb, b); b = apr_bucket_eos_create(); APR_BRIGADE_INSERT_TAIL(bb, b); ap_pass_brigade(cid->r->output_filters, bb); } return TRUE; } case 4: /* HSE_REQ_DONE_WITH_SESSION */ /* Signal to resume the thread completing this request */ if (cid->complete) SetEvent(cid->complete); return TRUE; case 1001: /* HSE_REQ_MAP_URL_TO_PATH */ { /* Map a URL to a filename */ char *file = (char *)lpvBuffer; DWORD len; subreq = ap_sub_req_lookup_uri(apr_pstrndup(r->pool, file, *lpdwSize), r, NULL); len = apr_cpystrn(file, subreq->filename, *lpdwSize) - file; /* IIS puts a trailing slash on directories, Apache doesn't */ if (subreq->finfo.filetype == APR_DIR) { if (len < *lpdwSize - 1) { file[len++] = '\\'; file[len] = '\0'; } } *lpdwSize = len; return TRUE; } case 1002: /* HSE_REQ_GET_SSPI_INFO */ if (cid->sconf->LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r, "ISAPI ServerSupportFunction HSE_REQ_GET_SSPI_INFO " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1003: /* HSE_APPEND_LOG_PARAMETER */ /* Log lpvBuffer, of lpdwSize bytes, in the URI Query (cs-uri-query) field */ apr_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer); if (cid->sconf->AppendLogToQuery) { if (r->args) r->args = apr_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL); else r->args = apr_pstrdup(r->pool, (char*) lpvBuffer); } if (cid->sconf->AppendLogToErrors) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r, "ISAPI %s: %s", cid->r->filename, (char*) lpvBuffer); return TRUE; case 1005: /* 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 lpvBuffer may be set to NULL. */ if (!cid->isa->fakeasync) { if (cid->sconf->LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r, "ISAPI ServerSupportFunction HSE_REQ_IO_COMPLETION " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } cid->completion = (PFN_HSE_IO_COMPLETION) lpvBuffer; cid->completion_arg = (PVOID) lpdwDataType; return TRUE; case 1006: /* HSE_REQ_TRANSMIT_FILE */ { HSE_TF_INFO *tf = (HSE_TF_INFO*)lpvBuffer; apr_status_t rv; apr_bucket_brigade *bb; apr_bucket *b; apr_file_t *fd; if (!cid->isa->fakeasync && (tf->dwFlags & HSE_IO_ASYNC)) { if (cid->sconf->LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r, "ISAPI ServerSupportFunction HSE_REQ_TRANSMIT_FILE " "as HSE_IO_ASYNC is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if ((rv = apr_os_file_put(&fd, tf->hFile, r->pool)) != APR_SUCCESS) { return FALSE; } /* apr_dupfile_oshandle (&fd, tf->hFile, r->pool); */ bb = apr_brigade_create(r->pool); if (tf->dwFlags & HSE_IO_SEND_HEADERS) { /* 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). */ apr_off_t ate = SendResponseHeaderEx(cid, tf->pszStatusCode, (char*)tf->pHead, strlen(tf->pszStatusCode), (apr_size_t)tf->HeadLength); if (ate < 0) { apr_brigade_destroy(bb); SetLastError(TODO_ERROR); return FALSE; } if (ate < (apr_size_t)tf->HeadLength) { b = apr_bucket_transient_create((char*)tf->pHead + ate, (apr_size_t)tf->HeadLength - ate); APR_BRIGADE_INSERT_TAIL(bb, b); } } else if (tf->pHead && tf->HeadLength) { b = apr_bucket_transient_create((char*)tf->pHead, (apr_size_t)tf->HeadLength); APR_BRIGADE_INSERT_TAIL(bb, b); } b = apr_bucket_file_create(fd, (apr_off_t)tf->Offset, (apr_size_t)tf->BytesToWrite); APR_BRIGADE_INSERT_TAIL(bb, b); if (tf->pTail && (apr_size_t)tf->TailLength) { b = apr_bucket_transient_create((char*)tf->pTail, (apr_size_t)tf->TailLength); APR_BRIGADE_INSERT_TAIL(bb, b); } b = apr_bucket_eos_create(); APR_BRIGADE_INSERT_TAIL(bb, b); ap_pass_brigade(r->output_filters, bb); /* we do nothing with (tf->dwFlags & HSE_DISCONNECT_AFTER_SEND) */ if (tf->dwFlags & HSE_IO_ASYNC) { /* XXX: Fake async response, * use tf->pfnHseIO, or if NULL, then use cid->fnIOComplete * pass pContect to the HseIO callback. */ } return TRUE; } case 1007: /* HSE_REQ_REFRESH_ISAPI_ACL */ if (cid->sconf->LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r, "ISAPI ServerSupportFunction " "HSE_REQ_REFRESH_ISAPI_ACL " "is not supported: %s", r->filename);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -