📄 mod_isapi.c
字号:
#pragma optimize("",on)BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) { request_rec *r = ((isapi_cid *)hConn)->r; const char *result; DWORD len; if (!strcmp(lpszVariableName, "ALL_HTTP")) { /* lf delimited, colon split, comma seperated and * null terminated list of HTTP_ vars */ char **env = (char**) ap_table_elts(r->subprocess_env)->elts; int nelts = 2 * ap_table_elts(r->subprocess_env)->nelts; int i; for (len = 0, i = 0; i < nelts; i += 2) if (!strncmp(env[i], "HTTP_", 5)) len += strlen(env[i]) + strlen(env[i + 1]) + 2; if (*lpdwSizeofBuffer < len + 1) { *lpdwSizeofBuffer = len + 1; SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } for (i = 0; i < nelts; i += 2) if (!strncmp(env[i], "HTTP_", 5)) { strcpy(lpvBuffer, env[i]); ((char*)lpvBuffer) += strlen(env[i]); *(((char*)lpvBuffer)++) = ':'; strcpy(lpvBuffer, env[i + 1]); ((char*)lpvBuffer) += strlen(env[i + 1]); *(((char*)lpvBuffer)++) = '\n'; } *(((char*)lpvBuffer)++) = '\0'; *lpdwSizeofBuffer = len; return TRUE; } if (!strcmp(lpszVariableName, "ALL_RAW")) { /* lf delimited, colon split, comma seperated and * null terminated list of the raw request header */ char **raw = (char**) ap_table_elts(r->headers_in)->elts; int nelts = 2 * ap_table_elts(r->headers_in)->nelts; int i; for (len = 0, i = 0; i < nelts; i += 2) len += strlen(raw[i]) + strlen(raw[i + 1]) + 2; if (*lpdwSizeofBuffer < len + 1) { *lpdwSizeofBuffer = len + 1; SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } for (i = 0; i < nelts; i += 2) { strcpy(lpvBuffer, raw[i]); ((char*)lpvBuffer) += strlen(raw[i]); *(((char*)lpvBuffer)++) = ':'; *(((char*)lpvBuffer)++) = ' '; strcpy(lpvBuffer, raw[i + 1]); ((char*)lpvBuffer) += strlen(raw[i + 1]); *(((char*)lpvBuffer)++) = '\n'; i += 2; } *(((char*)lpvBuffer)++) = '\0'; *lpdwSizeofBuffer = len; return TRUE; } /* Not a special case */ result = ap_table_get(r->subprocess_env, lpszVariableName); if (result) { len = strlen(result); if (*lpdwSizeofBuffer < len + 1) { *lpdwSizeofBuffer = len + 1; SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } strcpy(lpvBuffer, result); *lpdwSizeofBuffer = len; return TRUE; } /* Not Found */ SetLastError(ERROR_INVALID_INDEX); return FALSE;}BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes, DWORD dwReserved) { request_rec *r = ((isapi_cid *)ConnID)->r; /* We only support synchronous writing */ if (dwReserved && dwReserved != HSE_IO_SYNC) { if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if ((*lpwdwBytes = ap_rwrite(Buffer, *lpwdwBytes, r)) <= 0) { if (!GetLastError()) SetLastError(ERROR); /* XXX: Find the right error code */ return FALSE; } 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 (!GetLastError()) SetLastError(ERROR); /* XXX: Find the right error code */ return FALSE; } read += res; } *lpdwSize = read; return TRUE;}static BOOL SendResponseHeaderEx(isapi_cid *cid, const char *stat, const char *head, DWORD statlen, DWORD headlen){ int termarg; char *termch; if (!stat || statlen == 0 || !*stat) { stat = "Status: 200 OK"; } else { char *newstat; newstat = ap_palloc(cid->r->pool, statlen + 9); strcpy(newstat, "Status: "); ap_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 = ap_pstrndup(cid->r->pool, head, headlen); } } /* Parse them out, or die trying */ cid->status = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, stat, head, NULL); cid->ecb->dwHttpStatusCode = cid->r->status; /* All the headers should be set now */ ap_send_http_header(cid->r); /* Any data left should now be sent directly, * it may be raw if headlen was provided. */ if (termch && (termarg == 1)) { if (headlen == -1 && *termch) ap_rputs(termch, cid->r); else if (headlen > (size_t) (termch - head)) ap_rwrite(termch, headlen - (termch - head), cid->r); } if (cid->status == HTTP_INTERNAL_SERVER_ERROR) return FALSE; return TRUE;}/* 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. */ ap_table_set(r->headers_out, "Location", lpvBuffer); cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; return TRUE; case 2: /* HSE_REQ_SEND_URL */ /* Soak up remaining input (there should be none) */ if (r->remaining > 0) { char argsbuffer[HUGE_STRING_LEN]; while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0); } /* Reset the method to GET */ r->method = ap_pstrdup(r->pool, "GET"); r->method_number = M_GET; /* Don't let anyone think there's still data */ ap_table_unset(r->headers_in, "Content-Length"); /* AV fault per PR3598 - redirected path is lost! */ (char*)lpvBuffer = ap_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 */ DWORD statlen = 0, headlen = 0; if (lpvBuffer) statlen = strlen((char*) lpvBuffer); if (lpdwDataType) headlen = strlen((char*) lpdwDataType); return SendResponseHeaderEx(cid, (char*) lpvBuffer, (char*) lpdwDataType, statlen, headlen); } case 4: /* HSE_REQ_DONE_WITH_SESSION */ /* Do nothing... since we don't support async I/O, they'll * return from HttpExtensionProc soon */ 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(ap_pstrndup(r->pool, file, *lpdwSize), r); len = ap_cpystrn(file, subreq->filename, *lpdwSize) - file; /* IIS puts a trailing slash on directories, Apache doesn't */ if (S_ISDIR (subreq->finfo.st_mode)) { if (len < *lpdwSize - 1) { file[len++] = '\\'; file[len] = '\0'; } } *lpdwSize = len; return TRUE; } case 1002: /* HSE_REQ_GET_SSPI_INFO */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 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 * This code will do for now... */ ap_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer); if (AppendLogToQuery) { if (r->args) r->args = ap_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL); else r->args = ap_pstrdup(r->pool, (char*) lpvBuffer); } if (AppendLogToErrors) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r, "ISAPI %s: %s", cid->r->filename, (char*) lpvBuffer); return TRUE; /* We don't support all this async I/O, Microsoft-specific stuff */ case 1005: /* HSE_REQ_IO_COMPLETION */ case 1006: /* HSE_REQ_TRANSMIT_FILE */ if (LogNotSupported)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -