📄 jk_isapi_plugin.c
字号:
/* TODO: coallesce the to jk_pool_alloc() calls into a single * buffer alloc */ statLen = 4 + strlen(reason); statBuf = jk_pool_alloc(&p->p, statLen + 1); /* slightly quicker than sprintf() we hope */ statBuf[0] = (status / 100) % 10 + '0'; statBuf[1] = (status / 10) % 10 + '0'; statBuf[2] = (status / 1) % 10 + '0'; statBuf[3] = ' '; strcpy(statBuf + 4, reason); /* Build a single string containing all the headers * because that's what the server needs. */ if (hdrCount > 0) { unsigned i; unsigned hdrLen; char *bufp; for (i = 0, hdrLen = 3; i < hdrCount; i++) hdrLen += strlen(hdrNames[i]) + strlen(hdrValues[i]) + 4; hdrBuf = jk_pool_alloc(&p->p, hdrLen); bufp = hdrBuf; for (i = 0; i < hdrCount; i++) { Append(&bufp, hdrNames[i]); Append(&bufp, ": "); Append(&bufp, hdrValues[i]); Append(&bufp, crlf); } Append(&bufp, crlf); } else { hdrBuf = crlf; } DEBUG(("%d %s\n%s", status, reason, hdrBuf)); /* TODO: check API docs for this */ if (!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, statBuf, (LPDWORD) &statLen, (LPDWORD) hdrBuf)) { jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::start_response, ServerSupportFunction failed\n"); return JK_FALSE; } } return JK_TRUE; } jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::StartResponse, NULL parameters\n"); return JK_FALSE;}static int JK_METHOD Read(jk_ws_service_t * s, void *bytes, unsigned len, unsigned *countp){#if 0 DEBUG(("Read(%p, %p, %u, %p)\n", s, bytes, len, countp)); jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Read\n"); if (s && s->ws_private && bytes && countp) { private_ws_t *p = s->ws_private; /* Copy data from the server's buffer. Although it seems slightly * improbably we're believing that the server always buffers the * entire request in memory. Not properly tested yet. */ if (len > p->reqSize) len = p->reqSize; memcpy(bytes, p->reqBuffer, len); p->reqBuffer += len; p->reqSize -= len; *countp = len; return JK_TRUE; } jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Read, NULL parameters\n");#endif return JK_FALSE;}static int JK_METHOD Write(jk_ws_service_t *s, const void *bytes, unsigned len){ DEBUG(("Write(%p, %p, %u)\n", s, bytes, len)); jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Write\n"); if (s && s->ws_private && bytes) { private_ws_t *p = s->ws_private; DWORD dwLen = len; /* Make sure the response has really started. I'm almost certain * this isn't necessary, but it was in the ISAPI code, so it's in * here too. */ if (!p->responseStarted) StartResponse(s, 200, NULL, NULL, NULL, 0); DEBUG(("Writing %d bytes of content\n", len)); /* Send the data */ if (len > 0) { if (!p->lpEcb->WriteClient(p->lpEcb->ConnID, (LPVOID) bytes, &dwLen, 0)) { jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Write, WriteClient failed\n"); return JK_FALSE; } } return JK_TRUE; } jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Write, NULL parameters\n"); return JK_FALSE;}static int RunProg(const char *cmd){#ifdef WIN32 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); // Start the child process. si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWMAXIMIZED; if (!CreateProcess(NULL, (char *) cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { DWORD err = GetLastError(); LogMessage("Command \"%s\" (error %u)", NOERROR, cmd, err); return FALSE; } if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, TOMCAT_STARTSTOP_TO)) return TRUE; LogMessage("Command \"%s\" didn't complete in time", NOERROR, cmd); return FALSE;#else int err = system(cmd); if (0 == err) return 1; LogMessage("Command \"%s\" failed (error %d)", NOERROR, cmd, err); return 0;#endif}/* Called when the filter is unloaded. Free various resources and * display a banner. */BOOL WINAPI TerminateFilter(DWORD dwFlags){ if (initDone) { uri_worker_map_free(&uw_map, logger); wc_close(logger); if (logger) jk_close_file_logger(&logger); initDone = JK_FALSE; } if (NULL != tomcatStop && '\0' != *tomcatStop) { LogMessage("Attempting to stop Tomcat: %s", NOERROR, tomcatStop); RunProg(tomcatStop); } LogMessage(FILTERDESC " unloaded", NOERROR); jk_close_pool(&cfgPool); return TRUE;}/* Called when the server loads the filter. Reads a load of config data from * the registry and elsewhere and displays a banner. */BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer){ jk_open_pool(&cfgPool, NULL, 0); /* empty pool for config data */ if (!ReadInitData()) goto initFailed; if (!jk_open_file_logger(&logger, logFile, logLevel)) logger = NULL; if (NULL != tomcatStart && '\0' != *tomcatStart) { LogMessage("Attempting to start Tomcat: %s", NOERROR, tomcatStart); RunProg(tomcatStart); } pVer->dwFilterVersion = pVer->dwServerFilterVersion; //if (pVer->dwFilterVersion > HTTP_FILTER_REVISION) // pVer->dwFilterVersion = HTTP_FILTER_REVISION; /* Come back and check these... */ pVer->dwFlags = SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_PREPROC_HEADERS; strcpy(pVer->lpszFilterDesc, FILTERDESC); /* Banner */ LogMessage("%s loaded", NOERROR, pVer->lpszFilterDesc); return TRUE;initFailed: LogMessage("Error loading %s", NOERROR, FILTERDESC); return FALSE;}/* Read parameters from the registry */static int ReadInitData(void){ int ok = JK_TRUE; const char *v;#ifdef USE_INIFILE// Using an INIFILE#define GETV(key) inifile_lookup(key) ERRTYPE e; if (e = inifile_read(&cfgPool, ININAME), ERRNONE != e) { LogMessage("Error reading: %s, %s", NOERROR, ININAME, ERRTXT(e)); return JK_FALSE; }#else// Using the registry#define GETV(key) GetRegString(hkey, key) HKEY hkey; long rc; rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey); if (ERROR_SUCCESS != rc) return JK_FALSE;#endif#define GETVNB(tag, var) \ var = GETV(tag); \ if (NULL == var) \ { \ LogMessage("%s not defined in %s", NOERROR, tag, ININAME); \ ok = JK_FALSE; \ } GETVNB(JK_LOG_FILE_TAG, logFile) GETVNB(JK_LOG_LEVEL_TAG, v); GETVNB(JK_WORKER_FILE_TAG, workerFile); GETVNB(JK_MOUNT_FILE_TAG, workerMountFile); logLevel = (NULL == v) ? 0 : jk_parse_log_level(v); tomcatStart = GETV(TOMCAT_START); tomcatStop = GETV(TOMCAT_STOP);#ifndef USE_INIFILE RegCloseKey(hkey);#endif return ok;}#ifndef USE_INIFILEstatic const char *GetRegString(HKEY hkey, const char *key){ DWORD type = 0; DWORD sz = 0; LONG rc; char *val; rc = RegQueryValueEx(hkey, key, (LPDWORD) 0, &type, NULL, &sz); if (rc != ERROR_SUCCESS || type != REG_SZ) return NULL; if (val = jk_pool_alloc(&cfgPool, sz), NULL == val) return NULL; rc = RegQueryValueEx(hkey, key, (LPDWORD) 0, &type, val, &sz); if (rc == ERROR_SUCCESS) return val; return NULL;}#endif/* Main entry point for the filter. Called by the server for every HTTP request. */DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotificationType, LPVOID pvNotification){#if 0 switch (dwNotificationType) { case kFilterParsedRequest: return ParsedRequest(context, (FilterParsedRequest *) eventData); default: break; } return kFilterNotHandled;#endif return SF_STATUS_REQ_NEXT_NOTIFICATION;}/* Send a simple response. Used when we don't want to bother Tomcat, * which in practice means for various error conditions that we can * detect internally. */static void SimpleResponse(PHTTP_FILTER_CONTEXT *context, int status, char *reason, char *body){#if 0 FilterResponseHeaders frh; int rc, errID; char hdrBuf[35]; sprintf(hdrBuf, "Content-type: text/html%s%s", crlf, crlf); frh.responseCode = status; frh.reasonText = reason; frh.headerText = hdrBuf; rc = context->ServerSupport(context, kWriteResponseHeaders, &frh, NULL, 0, &errID); rc = context->WriteClient(context, body, strlen(body), 0, &errID);#endif}/* Called to reject a URI that contains the string "web-inf". We block * these because they may indicate an attempt to invoke arbitrary code. */static DWORD RejectBadURI(PHTTP_FILTER_CONTEXT *context){ static char *msg = "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>"; SimpleResponse(context, 403, "Forbidden", msg); return SF_STATUS_REQ_NEXT_NOTIFICATION;}/* Allocate space for a string given a start pointer and an end pointer * and return a pointer to the allocated, copied string. */static char *MemDup(private_ws_t *ws, const char *start, const char *end){ char *out = NULL; if (start != NULL && end != NULL && end > start) { int len = end - start; out = jk_pool_alloc(&ws->p, len + 1); memcpy(out, start, len); out[len] = '\0'; } return out;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -