diff --git a/src/httplib_config_options.c b/src/httplib_config_options.c index 35601ca6..c0c2397b 100644 --- a/src/httplib_config_options.c +++ b/src/httplib_config_options.c @@ -34,7 +34,6 @@ struct httplib_option XX_httplib_config_options[] = { { "cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$" }, { "ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$" }, - { "document_root", CONFIG_TYPE_DIRECTORY, NULL }, { "hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL }, { "ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL }, { "websocket_root", CONFIG_TYPE_DIRECTORY, NULL }, diff --git a/src/httplib_delete_file.c b/src/httplib_delete_file.c index 6234b119..5aede70f 100644 --- a/src/httplib_delete_file.c +++ b/src/httplib_delete_file.c @@ -39,8 +39,8 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) struct de de; char error_string[ERROR_STRING_LEN]; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) { + if ( conn == NULL || conn->ctx == NULL ) return; + if ( conn->ctx->document_root == NULL ) { XX_httplib_send_http_error( conn, 405, "Error: File delete operations are not supported" ); return; diff --git a/src/httplib_free_context.c b/src/httplib_free_context.c index c9eff3f4..d7539e0a 100644 --- a/src/httplib_free_context.c +++ b/src/httplib_free_context.c @@ -85,6 +85,7 @@ void XX_httplib_free_context( struct httplib_context *ctx ) { ctx->authentication_domain = httplib_free( ctx->authentication_domain ); ctx->cgi_environment = httplib_free( ctx->cgi_environment ); ctx->cgi_interpreter = httplib_free( ctx->cgi_interpreter ); + ctx->document_root = httplib_free( ctx->document_root ); ctx->error_log_file = httplib_free( ctx->error_log_file ); ctx->extra_mime_types = httplib_free( ctx->extra_mime_types ); ctx->global_auth_file = httplib_free( ctx->global_auth_file ); diff --git a/src/httplib_handle_propfind.c b/src/httplib_handle_propfind.c index 2e195d3e..7dddba70 100644 --- a/src/httplib_handle_propfind.c +++ b/src/httplib_handle_propfind.c @@ -103,7 +103,7 @@ void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *pa time_t curtime; if ( conn == NULL || conn->ctx == NULL || path == NULL || filep == NULL ) return; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn->ctx->document_root == NULL ) return; depth = httplib_get_header( conn, "Depth" ); curtime = time( NULL ); diff --git a/src/httplib_handle_request.c b/src/httplib_handle_request.c index 34a8ab22..a6b65025 100644 --- a/src/httplib_handle_request.c +++ b/src/httplib_handle_request.c @@ -270,7 +270,7 @@ no_callback_resource: * 6.2.1. thus, the server must have real files */ - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) { + if ( conn->ctx->document_root == NULL ) { /* * This server does not have any real files, thus the @@ -391,7 +391,7 @@ no_callback_resource: * by a script file. Thus, a DOCUMENT_ROOT must exist. */ - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) { + if ( conn->ctx->document_root == NULL ) { XX_httplib_send_http_error( conn, 404, "%s", "Not Found" ); return; diff --git a/src/httplib_interpret_uri.c b/src/httplib_interpret_uri.c index d7fa3d8c..1168fc2c 100644 --- a/src/httplib_interpret_uri.c +++ b/src/httplib_interpret_uri.c @@ -65,7 +65,7 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return; uri = conn->request_info.local_uri; - root = conn->ctx->cfg[DOCUMENT_ROOT]; + root = conn->ctx->document_root; memset( filep, 0, sizeof(*filep) ); diff --git a/src/httplib_is_authorized_for_put.c b/src/httplib_is_authorized_for_put.c index 8725ea88..e67fb567 100644 --- a/src/httplib_is_authorized_for_put.c +++ b/src/httplib_is_authorized_for_put.c @@ -38,8 +38,8 @@ bool XX_httplib_is_authorized_for_put( struct httplib_connection *conn ) { const char *passfile; bool ret; - if ( conn == NULL || conn->ctx == NULL ) return false; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return false; + if ( conn == NULL || conn->ctx == NULL ) return false; + if ( conn->ctx->document_root == NULL ) return false; passfile = conn->ctx->put_delete_auth_file; diff --git a/src/httplib_main.h b/src/httplib_main.h index 8f6e8423..38462046 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -393,7 +393,6 @@ union usa { enum { CGI_EXTENSIONS, SSI_EXTENSIONS, - DOCUMENT_ROOT, HIDE_FILES, SSL_CA_PATH, WEBSOCKET_ROOT, @@ -583,6 +582,7 @@ struct httplib_context { char * authentication_domain; char * cgi_environment; char * cgi_interpreter; + char * document_root; char * error_log_file; char * extra_mime_types; char * global_auth_file; diff --git a/src/httplib_mkcol.c b/src/httplib_mkcol.c index 63dcefe7..ccc0519b 100644 --- a/src/httplib_mkcol.c +++ b/src/httplib_mkcol.c @@ -45,8 +45,8 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { time_t curtime; char error_string[ERROR_STRING_LEN]; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn == NULL || conn->ctx == NULL ) return; + if ( conn->ctx->document_root == NULL ) return; curtime = time( NULL ); diff --git a/src/httplib_prepare_cgi_environment.c b/src/httplib_prepare_cgi_environment.c index 56309203..1c848c8d 100644 --- a/src/httplib_prepare_cgi_environment.c +++ b/src/httplib_prepare_cgi_environment.c @@ -49,7 +49,7 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const int i; bool truncated; - if ( conn == NULL || conn->ctx == NULL || prog == NULL || env == NULL || conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn == NULL || conn->ctx == NULL || prog == NULL || env == NULL || conn->ctx->document_root == NULL ) return; env->conn = conn; env->buflen = CGI_ENVIRONMENT_SIZE; @@ -60,9 +60,9 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const env->var = httplib_malloc( env->buflen * sizeof(char *) ); if ( conn->ctx->authentication_domain != NULL ) XX_httplib_addenv( env, "SERVER_NAME=%s", conn->ctx->authentication_domain ); - XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->cfg[DOCUMENT_ROOT] ); - XX_httplib_addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->cfg[DOCUMENT_ROOT] ); - XX_httplib_addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() ); + XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->document_root ); + XX_httplib_addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->document_root ); + XX_httplib_addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() ); /* * Prepare the environment block @@ -91,8 +91,8 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const XX_httplib_addenv( env, "SCRIPT_FILENAME=%s", prog ); - if ( conn->path_info == NULL ) XX_httplib_addenv( env, "PATH_TRANSLATED=%s", conn->ctx->cfg[DOCUMENT_ROOT] ); - else XX_httplib_addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->cfg[DOCUMENT_ROOT], conn->path_info ); + if ( conn->path_info == NULL ) XX_httplib_addenv( env, "PATH_TRANSLATED=%s", conn->ctx->document_root ); + else XX_httplib_addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->document_root, conn->path_info ); XX_httplib_addenv( env, "HTTPS=%s", (conn->ssl == NULL) ? "off" : "on" ); diff --git a/src/httplib_put_file.c b/src/httplib_put_file.c index bdfd792f..e107a5b6 100644 --- a/src/httplib_put_file.c +++ b/src/httplib_put_file.c @@ -46,8 +46,8 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { char error_string[ERROR_STRING_LEN]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn == NULL || conn->ctx == NULL ) return; + if ( conn->ctx->document_root == NULL ) return; curtime = time( NULL ); diff --git a/src/httplib_send_options.c b/src/httplib_send_options.c index d5533af2..2d1f2145 100644 --- a/src/httplib_send_options.c +++ b/src/httplib_send_options.c @@ -40,8 +40,8 @@ void XX_httplib_send_options( struct httplib_connection *conn ) { char date[64]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn == NULL || conn->ctx == NULL ) return; + if ( conn->ctx->document_root == NULL ) return; curtime = time( NULL ); conn->status_code = 200; diff --git a/src/httplib_ssi.c b/src/httplib_ssi.c index 8037a7b6..918419f6 100644 --- a/src/httplib_ssi.c +++ b/src/httplib_ssi.c @@ -44,7 +44,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch size_t len; bool truncated; - if ( conn == NULL || conn->ctx == NULL || conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return; + if ( conn == NULL || conn->ctx == NULL || conn->ctx->document_root == NULL ) return; truncated = false; @@ -61,7 +61,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch */ file_name[511] = 0; - doc_root = conn->ctx->cfg[DOCUMENT_ROOT]; + doc_root = conn->ctx->document_root; XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s/%s", doc_root, file_name ); diff --git a/src/httplib_start.c b/src/httplib_start.c index cabe6ba8..bafb8cfd 100644 --- a/src/httplib_start.c +++ b/src/httplib_start.c @@ -31,10 +31,11 @@ #include "httplib_string.h" #include "httplib_utils.h" -static bool check_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config ); +static bool check_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config ); +static bool check_dir( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); static bool check_file( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); -static bool check_int( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, int *config, int minval, int maxval ); -static bool check_str( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); +static bool check_int( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, int *config, int minval, int maxval ); +static bool check_str( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); static struct httplib_context * cleanup( struct httplib_context *ctx, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); static bool process_options( struct httplib_context *ctx, const struct httplib_option_t *options ); @@ -284,31 +285,40 @@ static bool process_options( struct httplib_context *ctx, const struct httplib_o if ( ctx == NULL ) return false; - ctx->access_control_list = NULL; - ctx->access_log_file = NULL; - ctx->allow_sendfile_call = true; - ctx->cgi_environment = NULL; - ctx->decode_url = true; - ctx->enable_directory_listing = true; - ctx->enable_keep_alive = false; - ctx->error_log_file = NULL; - ctx->extra_mime_types = NULL; - ctx->num_threads = 50; - ctx->protect_uri = NULL; - ctx->request_timeout = 30000; - ctx->run_as_user = NULL; - ctx->ssl_ca_file = NULL; - ctx->ssl_cipher_list = NULL; - ctx->ssl_protocol_version = 0; - ctx->ssl_short_trust = false; - ctx->ssl_verify_depth = 9; - ctx->ssl_verify_paths = true; - ctx->ssl_verify_peer = false; - ctx->static_file_max_age = 0; - ctx->throttle = NULL; - ctx->tcp_nodelay = false; - ctx->url_rewrite_patterns = NULL; - ctx->websocket_timeout = 30000; + ctx->access_control_allow_origin = NULL; + ctx->access_control_list = NULL; + ctx->access_log_file = NULL; + ctx->allow_sendfile_call = true; + ctx->authentication_domain = NULL; + ctx->cgi_environment = NULL; + ctx->cgi_interpreter = NULL; + ctx->decode_url = true; + ctx->document_root = NULL; + ctx->enable_directory_listing = true; + ctx->enable_keep_alive = false; + ctx->error_log_file = NULL; + ctx->extra_mime_types = NULL; + ctx->global_auth_file = NULL; + ctx->index_files = NULL; + ctx->listening_ports = NULL; + ctx->num_threads = 50; + ctx->protect_uri = NULL; + ctx->put_delete_auth_file = NULL; + ctx->request_timeout = 30000; + ctx->run_as_user = NULL; + ctx->ssl_ca_file = NULL; + ctx->ssl_certificate = NULL; + ctx->ssl_cipher_list = NULL; + ctx->ssl_protocol_version = 0; + ctx->ssl_short_trust = false; + ctx->ssl_verify_depth = 9; + ctx->ssl_verify_paths = true; + ctx->ssl_verify_peer = false; + ctx->static_file_max_age = 0; + ctx->throttle = NULL; + ctx->tcp_nodelay = false; + ctx->url_rewrite_patterns = NULL; + ctx->websocket_timeout = 30000; if ( (ctx->access_control_allow_origin = strdup( "*" )) == NULL ) { @@ -344,6 +354,7 @@ static bool process_options( struct httplib_context *ctx, const struct httplib_o if ( check_str( ctx, options, "cgi_environment", & ctx->cgi_environment ) ) return true; if ( check_file( ctx, options, "cgi_interpreter", & ctx->cgi_interpreter ) ) return true; if ( check_bool( ctx, options, "decode_url", & ctx->decode_url ) ) return true; + if ( check_dir( ctx, options, "document_root", & ctx->document_root ) ) return true; if ( check_bool( ctx, options, "enable_directory_listing", & ctx->enable_directory_listing ) ) return true; if ( check_bool( ctx, options, "enable_keep_alive", & ctx->enable_keep_alive ) ) return true; if ( check_file( ctx, options, "error_log_file", & ctx->error_log_file ) ) return true; @@ -434,6 +445,42 @@ static bool check_bool( struct httplib_context *ctx, const struct httplib_option +/* + * static bool check_dir( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); + * + * The function check_dir() checks if an option is equal to a directory config + * parameter and stores the value if that is the case. If the value cannot be + * recognized, true is returned and the function performs a complete cleanup. + * If the option name could not be found, the function returns false to + * indicate that the search should go on. IF the value could be found, also + * false is returned. + */ + +static bool check_dir( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ) { + + if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) { + + cleanup( ctx, "Internal error parsing directory option" ); + return true; + } + + if ( httplib_strcasecmp( option->name, name ) ) return false; + + *config = httplib_free( *config ); + + if ( option->value == NULL ) return false; + + *config = httplib_strdup( option->value ); + if ( *config != NULL ) return false; + + cleanup( ctx, "Out of memory assigning value \"%s\" to option \"%s\"", option->value, option->name ); + return true; + +} /* check_dir */ + + + + /* * static bool check_file( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config ); * @@ -449,7 +496,7 @@ static bool check_file( struct httplib_context *ctx, const struct httplib_option if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) { - cleanup( ctx, "Internal error parsing string option" ); + cleanup( ctx, "Internal error parsing file option" ); return true; } diff --git a/src/httplib_substitute_index_file.c b/src/httplib_substitute_index_file.c index f6c4df52..68f1d88e 100644 --- a/src/httplib_substitute_index_file.c +++ b/src/httplib_substitute_index_file.c @@ -46,7 +46,7 @@ int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *pat bool found; if ( conn == NULL || conn->ctx == NULL || path == NULL ) return 0; - if ( conn->ctx->cfg[DOCUMENT_ROOT] == NULL ) return 0; + if ( conn->ctx->document_root == NULL ) return 0; list = conn->ctx->index_files; n = strlen( path );