ervu-sign-module/src/fcgisrv/fcgi_worker.c

139 lines
3.8 KiB
C

#include "fcgi_server_internal.h"
#include <assert.h>
#define FCGI_DEFAULT_RESPONSE_FORMAT \
"Content-type: text/plain" CRLF\
CRLF\
"FCGI_SERVER" CRLF\
"Hello from FCGI server!" CRLF\
"Request number %d" CRLF
fcgi_handler_status_t fcgi_default_handler_func(FCGX_Request* request, void* ctx);
fcgi_handler_t fcgi_default_handler = { fcgi_default_handler_func, NULL };
fcgi_handler_status_t
fcgi_default_handler_func(FCGX_Request* request, void* ctx)
{
assert(request != NULL && "fcgi_default_handler_func: FCGX_Request* request == NULL");
/* ctx may be NULL */
static int counter = 0;
LOG_DEBUG(FCGI_DEFAULT_RESPONSE_FORMAT, ++counter);
FCGX_FPrintF(request->out, FCGI_DEFAULT_RESPONSE_FORMAT, ++counter);
/* print envp */
size_t i;
for (i = 0; request->envp[i] != NULL; ++i) {
LOG_DEBUG("envp[%zu]: %s" CRLF, i, request->envp[i]);
FCGX_FPrintF(request->out, "envp[%d]: %s" CRLF, i, request->envp[i]);
}
return HANDLER_SUCCESS;
}
static fcgi_handler_t*
fcgi_route_request(HFcgi hfcgi, FCGX_Request* request)
{
assert(hfcgi != NULL);
assert(request != NULL);
/* do request routing; map request-path to handler */
/* evaluate hash of request path */
char* path = FCGX_GetParam(FCGI_PARAM_NAME_DOCUMENT_URI, request->envp);
if (path == NULL) {
LOG_ERROR("Could not get DOCUMENT_URI of request");
return NULL;
}
return fcgi_handler_map_get(&hfcgi->handler_map, path);
}
static fcgi_handler_status_t
fcgi_handle_request(HFcgi hfcgi, FCGX_Request* request)
{
LOG_TRACE("fcgi_handle_request");
assert(hfcgi != NULL && "fcgi_handle_request: HFcgi hfcgi == NULL");
assert(request != NULL && "fcgi_handle_request: FCGX_Request* request == NULL");
fcgi_handler_status_t status;
fcgi_handler_t* handler = fcgi_route_request(hfcgi, request);
if (handler == NULL) {
LOG_WARN("appropriate fcgi handler not found");
LOG_WARN("Response status: '404 Not Found'");
status = fcgi_404_not_found_handler(request, (void*)hfcgi);
goto done;
}
/* finally - execute handler*/
status = handler->execute(request, handler->ctx);
done:
return status;
}
int
fcgi_worker_main(fcgi_thread_t* thread)
{
LOG_TRACE("fcgi_worker_main enter");
assert(thread != NULL && "fcgi_worker_main: fcgi_thread_t* thread == NULL");
fcgi_handler_status_t status = HANDLER_SUCCESS;
HFcgi hfcgi = (HFcgi)thread->ctx;
FCGX_Request request;
LOG_DEBUG("fcgi_worker_main: hfcgi->listen.fd = %d", hfcgi->listen.fd);
if (FCGX_InitRequest(&request, hfcgi->listen.fd, 0) != 0) {
LOG_ERROR("Could not init request object");
goto error;
}
/** init_handler_(); */
while (atomic_flag_test_and_set(&thread->run)) {
pthread_mutex_lock(&hfcgi->listen.accept_mutex);
int rc = FCGX_Accept_r(&request);
pthread_mutex_unlock(&hfcgi->listen.accept_mutex);
if (rc != 0) {
pthread_mutex_lock(hfcgi->mutex);
if (!hfcgi->is_stopping) {
LOG_WARN("FCGX_Accept_r failed. Desc: %d", rc);
}
pthread_mutex_unlock(hfcgi->mutex);
//goto error;
continue;
}
LOG_DEBUG("Request accepted:");
fcgi_request_print_envp(&request);
status = fcgi_handle_request(hfcgi, &request);
FCGX_Finish_r(&request);
if (status == HANDLER_ERROR) {
LOG_ERROR("fcgi_handle_request returned HANDLER_ERROR");
//goto error;
}
}
LOG_TRACE("fcgi_worker_main exit with success");
return 0;
error:
LOG_ERROR("fcgi_worker_main exit with error");
return -1;
}