DWORD WINAPI HttpExtensionProc()

in native/iis/jk_isapi_plugin.c [2077:2227]


DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpEcb)
{
    DWORD rc = HSE_STATUS_ERROR;
    isapi_private_data_t private_data;
    jk_ws_service_t s;
    jk_pool_atom_t buf[SMALL_POOL_SIZE];
    char *worker_name;
    jk_log_context_t log_ctx;
    jk_log_context_t *l = &log_ctx;
    char id[HDR_BUFFER_SIZE];
    DWORD idLen = HDR_BUFFER_SIZE;

    l->logger = logger;
    if (lpEcb->GetServerVariable(lpEcb->ConnID, HTTP_REQUEST_ID_HEADER_NAME,
                                 id, &idLen)) {
        l->id = id;
    }
    else {
        l->id = "EXTENSION";
    }

    lpEcb->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR;

    JK_TRACE_ENTER(l);

    /* Initialise jk */
    EnterCriticalSection(&log_cs);
    if (is_inited && !is_mapread) {
        char serverName[MAX_SERVERNAME] = "";
        char instanceId[MAX_INSTANCEID] = "";
        DWORD dwLen = MAX_SERVERNAME - MAX_INSTANCEID - 1;

        if (lpEcb->GetServerVariable(lpEcb->ConnID, "SERVER_NAME",
                                     serverName, &dwLen)) {
            dwLen = MAX_INSTANCEID;
            if (lpEcb->GetServerVariable(lpEcb->ConnID, "INSTANCE_ID",
                                         instanceId, &dwLen)) {
                if (dwLen > 1) {
                    StringCbCat(serverName, MAX_SERVERNAME, "_");
                    StringCbCat(serverName, MAX_SERVERNAME, instanceId);
                }
            }
            if (!is_mapread) {
                WaitForSingleObject(init_cs, INFINITE);
                if (!is_mapread)
                    is_mapread = init_jk(serverName);
                ReleaseMutex(init_cs);
            }
        }
        if (!is_mapread)
            is_inited = JK_FALSE;
    }
    LeaveCriticalSection(&log_cs);

    if (!is_inited) {
        jk_log(l, JK_LOG_ERROR, "not initialized");
        JK_TRACE_EXIT(l);
        return HSE_STATUS_ERROR;
    }

    if (!watchdog_interval)
        wc_maintain(l);
    jk_init_ws_service(&s);
    jk_open_pool(&private_data.p, buf, sizeof(buf));

    private_data.bytes_read_so_far = 0;
    private_data.lpEcb = lpEcb;
    private_data.chunk_content = JK_FALSE;

    s.ws_private = &private_data;
    s.pool = &private_data.p;

    /* Needs to be replaced by a pool allocated ctx in init_ws_service() */
    s.log_ctx = l;

    if (flush_packets) {
        lpEcb->ServerSupportFunction(lpEcb->ConnID, HSE_REQ_SET_FLUSH_FLAG,
                (LPVOID) TRUE, NULL, NULL);
    }

    if (init_ws_service(&private_data, &s, &worker_name)) {
        jk_endpoint_t *e = NULL;
        jk_worker_t *worker = wc_get_worker_for_name(worker_name, l);
        /* Replace by a pool allocated ctx from init_ws_service() */
        l = s.log_ctx;

        if (!worker) {
            jk_log(l, JK_LOG_ERROR,
                   "could not get a worker for name %s",
                   worker_name);
            jk_close_pool(&private_data.p);
            JK_TRACE_EXIT(l);
            return rc;
        }
        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG,
                   "got a worker for name %s", worker_name);
        if (worker->get_endpoint(worker, &e, l)) {
            int is_error = JK_HTTP_SERVER_ERROR;
            int result;
            if ((result = e->service(e, &s, l, &is_error)) > 0) {
                if (s.extension.use_server_error_pages &&
                    s.http_response_status >= s.extension.use_server_error_pages) {
                    if (JK_IS_DEBUG_LEVEL(l))
                        jk_log(l, JK_LOG_DEBUG, "Forwarding status=%d"
                               " for worker=%s",
                               s.http_response_status, worker_name);
                    lpEcb->dwHttpStatusCode = s.http_response_status;
                    write_error_message(lpEcb, s.http_response_status,
                                        private_data.err_hdrs, l);
                }
                else {
                    rc = HSE_STATUS_SUCCESS;
                    lpEcb->dwHttpStatusCode = s.http_response_status;
                    if (JK_IS_DEBUG_LEVEL(l))
                        jk_log(l, JK_LOG_DEBUG,
                               "service() returned OK");
                }
            }
            else {
                if ((result == JK_CLIENT_ERROR) && (is_error == JK_HTTP_OK)) {
                    jk_log(l, JK_LOG_INFO,
                           "service() failed because client aborted connection");
                }
                else {
                    jk_log(l, JK_LOG_ERROR,
                           "service() failed with http error %d", is_error);
                }
                lpEcb->dwHttpStatusCode = is_error;
                write_error_message(lpEcb, is_error, private_data.err_hdrs, l);
            }
            e->done(&e, l);
        }
        else {
            int is_error = JK_HTTP_SERVER_BUSY;
            jk_log(l, JK_LOG_ERROR,
                   "Failed to obtain an endpoint to service request - "
                   "your connection_pool_size is probably less than the threads in your web server!");
            lpEcb->dwHttpStatusCode = is_error;
            write_error_message(lpEcb, is_error, private_data.err_hdrs, l);
        }
    }
    else {
        jk_log(l, JK_LOG_ERROR,
               "failed to init service for request.");
    }
    jk_close_pool(&private_data.p);
    JK_TRACE_EXIT(l);

    return rc;
}