📄 jk_dsapi_plugin.c
字号:
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;
}
frh.responseCode = status;
frh.reasonText = (char *)reason;
frh.headerText = hdrBuf;
DEBUG(("%d %s\n%s", status, reason, hdrBuf));
/* Send the headers */
rc = p->context->ServerSupport(p->context, kWriteResponseHeaders,
&frh, NULL, 0, &errID);
/*
if (rc)
{
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::StartResponse, 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)
{
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 Domino's buffer. Although it seems slightly
* improbably we're believing that Domino 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");
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;
int errID, rc;
/* 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)
rc = p->context->WriteClient(p->context, (char *)bytes, len, 0,
&errID);
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();
AddInLogMessageText("Command \"%s\" (error %u)", NOERROR, cmd, err);
return FALSE;
}
if (WAIT_OBJECT_0 ==
WaitForSingleObject(pi.hProcess, TOMCAT_STARTSTOP_TO))
return TRUE;
AddInLogMessageText("Command \"%s\" didn't complete in time", NOERROR,
cmd);
return FALSE;
#else
int err = system(cmd);
if (0 == err)
return 1;
AddInLogMessageText("Command \"%s\" failed (error %d)", NOERROR, cmd,
err);
return 0;
#endif
}
/* Called when the filter is unloaded. Free various resources and
* display a banner.
*/
DLLEXPORT unsigned int TerminateFilter(unsigned int reserved)
{
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) {
AddInLogMessageText("Attempting to stop Tomcat: %s", NOERROR,
tomcatStop);
RunProg(tomcatStop);
}
AddInLogMessageText(FILTERDESC " unloaded", NOERROR);
jk_close_pool(&cfgPool);
return kFilterHandledEvent;
}
/* Called when Domino loads the filter. Reads a load of config data from
* the registry and elsewhere and displays a banner.
*/
DLLEXPORT unsigned int FilterInit(FilterInitData * filterInitData)
{
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) {
AddInLogMessageText("Attempting to start Tomcat: %s", NOERROR,
tomcatStart);
RunProg(tomcatStart);
}
filterInitData->appFilterVersion = kInterfaceVersion;
filterInitData->eventFlags = kFilterParsedRequest;
strcpy(filterInitData->filterDesc, FILTERDESC);
// Banner
AddInLogMessageText("%s loaded", NOERROR, filterInitData->filterDesc);
return kFilterHandledEvent;
initFailed:
AddInLogMessageText("Error loading %s", NOERROR, FILTERDESC);
return kFilterError;
}
/* 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) {
AddInLogMessageText("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) \
{ \
AddInLogMessageText("%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_INIFILE
static 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 Domino for every HTTP request.
*/
DLLEXPORT unsigned int HttpFilterProc(FilterContext * context,
unsigned int eventType, void *eventData)
{
switch (eventType) {
case kFilterParsedRequest:
return ParsedRequest(context, (FilterParsedRequest *) eventData);
default:
break;
}
return kFilterNotHandled;
}
/* 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(FilterContext * context, int status, char *reason,
char *body)
{
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);
}
/* 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 unsigned int RejectBadURI(FilterContext * context)
{
static char *msg =
"<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>";
SimpleResponse(context, 403, "Forbidden", msg);
return kFilterHandledRequest;
}
/* 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;
}
/* Given all the HTTP headers as a single string parse them into individual
* name, value pairs. Called twice: once to work out how many headers there
* are, then again to copy them.
*/
static int ParseHeaders(private_ws_t * ws, const char *hdrs, int hdrsz,
jk_ws_service_t *s)
{
int hdrCount = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -