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

📄 jk_dsapi_plugin.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:
                    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 + -