139 lines
3.8 KiB
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;
|
|
}
|