ervu-sign-module/src/fcgisrv/fcgi_utils.h

226 lines
7.6 KiB
C

#ifndef FCGI_UTILS_H_INCLUDED
#define FCGI_UTILS_H_INCLUDED
#include "fcgi_server.h"
#include "utils/logger.h"
#include "utils/str_t.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************** fastCGI parameters: *******************************/
#define FCGI_PARAM_NAME_REMOTE_ADDR "REMOTE_ADDR"
#define FCGI_PARAM_NAME_HTTP_COOKIE "HTTP_COOKIE"
#define FCGI_PARAM_NAME_REQUEST_URI "REQUEST_URI"
#define FCGI_PARAM_NAME_CONTENT_LENGTH "CONTENT_LENGTH"
#define FCGI_PARAM_NAME_CONTENT_TYPE "CONTENT_TYPE"
#define FCGI_PARAM_NAME_REQUEST_METHOD "REQUEST_METHOD"
#define FCGI_PARAM_NAME_SERVER_ADDR "SERVER_ADDR"
#define FCGI_PARAM_NAME_SERVER_PORT "SERVER_PORT"
#define FCGI_PARAM_NAME_SERVER_NAME "SERVER_NAME"
#define FCGI_PARAM_NAME_DOCUMENT_URI "DOCUMENT_URI"
#define FCGI_PARAM_NAME_QUERY_STRING "QUERY_STRING"
#define FCGI_PARAM_NAME_REQUEST_SCHEME "REQUEST_SCHEME"
#define FCGI_PARAM_NAME_HOST "HTTP_HOST"
/******************************************************************************/
static inline void
fcgi_request_print_envp(const FCGX_Request* request)
{
if (request == NULL) return;
char **envp = request->envp;
if (envp == NULL) return;
int i = 0;
for (; envp[i] != NULL; i++) {
LOG_DEBUG("%d: %s", i, envp[i]);
}
}
/**
* @note just pointer is copied
*/
char* fcgi_request_get_param(const FCGX_Request* request, const char* name, bool* err);
int
fcgi_get_content_length(const FCGX_Request* request);
/**
* Returns: HANDLER_SUCCESS, HANDLER_HTTP_OK (no body), HANDLER_HTTP_BAD_REQUEST,
* HANDLER_HTTP_REQUEST_ENTITY_TOO_LARGE, HANDLER_ERROR
*/
fcgi_handler_status_t
check_content_length(int content_length, int client_max_body_size);
/**
* Returns: HANDLER_SUCCESS, HANDLER_HTTP_BAD_REQUEST, HANDLER_HTTP_NOT_ACCEPTABLE
*/
fcgi_handler_status_t
check_content_type(const FCGX_Request* request, const str_t* acceptable_content_type, const char** actual_content_type);
/**
* Returns: HANDLER_SUCCESS, HANDLER_HTTP_BAD_REQUEST, HANDLER_ERROR
*/
fcgi_handler_status_t
fcgi_request_load_data(const FCGX_Request* request, int content_length, char** content);
fcgi_handler_status_t
fcgi_printf_str(const FCGX_Request* request, const char* response, int response_len);
fcgi_handler_status_t
fcgi_printf_header(const FCGX_Request* request, const char* name, const char* value, int value_len);
/************************** fastCGI handlers: *********************************/
#define CRLF "\r\n"
#define FCGI_200_EMPTY_RESPONSE_FORMAT \
"Status: 200 OK" CRLF\
CRLF
#define FCGI_200_JSON_RESPONSE_FORMAT \
"Status: 200 OK" CRLF\
"Content-type: application/json" CRLF\
CRLF\
"%s" CRLF
#define FCGI_400_RESPONSE_FORMAT \
"Status: 400 Bad Request" CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"400 Bad Request" CRLF
#define FCGI_401_RESPONSE_FORMAT \
"Status: 401 Unauthorized" CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"%s" CRLF
#define FCGI_404_RESPONSE_FORMAT \
"Status: 404 Not Found" CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"404 Not Found" CRLF
#define FCGI_405_RESPONSE_FORMAT \
"Status: 405 Method Not Allowed" CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"405 Method Not Allowed" CRLF
#define FCGI_406_RESPONSE_FORMAT \
"Status: 406 Not Acceptable" CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"406 Not Acceptable" CRLF
#define FCGI_413_RESPONSE_FORMAT \
"Status: 413 Request Entity Too Large " CRLF\
"Content-type: text/plain" CRLF\
CRLF\
"413 Request Entity Too Large " CRLF
#define FCGI_500_RESPONSE_FORMAT \
"Status: 500 Internal Server Error" CRLF\
"Content-type: application/json" CRLF\
CRLF\
"%s" CRLF
#define FCGI_CHECK_PRINTF_STATUS(request, format, code) \
(HANDLER_ERROR != fcgi_printf_str(request, format, sizeof(format) - 1)) ? \
code : HANDLER_ERROR
typedef fcgi_handler_status_t (*fcgi_request_handler_pt)(const FCGX_Request* request, void* ctx);
typedef fcgi_request_handler_pt (*FCGI_REQUEST_FINALIZE_HANDLER)(int rc);
static inline void
fcgi_print_log(const FCGX_Request* request, const char* status)
{
const char* uri = fcgi_request_get_param(request, FCGI_PARAM_NAME_REQUEST_URI, NULL);
uri = uri != NULL ? uri : "nil";
const char* method = fcgi_request_get_param(request, FCGI_PARAM_NAME_REQUEST_METHOD, NULL);
method = method != NULL ? method : "nil";
LOG_INFO("%s %s, '%s'", method, uri, status);
}
fcgi_handler_status_t
fcgi_200_ok_handler(const FCGX_Request* request, const char* response);
static inline fcgi_handler_status_t
fcgi_400_bad_request_handler(const FCGX_Request* request, void* ctx __attribute__((unused)))
{
fcgi_print_log(request, "400 Bad Request");
return FCGI_CHECK_PRINTF_STATUS(request, FCGI_400_RESPONSE_FORMAT, 400);
}
fcgi_handler_status_t
fcgi_401_bad_signature_handler(const FCGX_Request* request, const char* verify_error);
static inline fcgi_handler_status_t
fcgi_404_not_found_handler(const FCGX_Request* request, void* ctx __attribute__((unused)))
{
fcgi_print_log(request, "404 Not Found");
return FCGI_CHECK_PRINTF_STATUS(request, FCGI_404_RESPONSE_FORMAT, 404);
}
static inline fcgi_handler_status_t
fcgi_405_method_not_allowed_handler(const FCGX_Request* request, void* ctx __attribute__((unused)))
{
fcgi_print_log(request, "405 Method Not Allowed");
return FCGI_CHECK_PRINTF_STATUS(request, FCGI_405_RESPONSE_FORMAT, 405);
}
static inline fcgi_handler_status_t
fcgi_406_not_acceptable_handler(const FCGX_Request* request, void* ctx __attribute__((unused)))
{
fcgi_print_log(request, "406 Not Acceptable");
return FCGI_CHECK_PRINTF_STATUS(request, FCGI_406_RESPONSE_FORMAT, 406);
}
static inline fcgi_handler_status_t
fcgi_413_request_entity_too_large_handler(const FCGX_Request* request, void* ctx __attribute__((unused)))
{
fcgi_print_log(request, "413 Request Entity Too Large'");
return FCGI_CHECK_PRINTF_STATUS(request, FCGI_413_RESPONSE_FORMAT, 413);
}
fcgi_handler_status_t
fcgi_500_internal_server_error_handler(const FCGX_Request* request, const char *error_code);
/******************************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* FCGI_UTILS_H_INCLUDED */