1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-09 03:22:45 +03:00

Moved options to struct

This commit is contained in:
Lammert Bies
2016-12-28 03:00:53 +01:00
parent 0d31377ec8
commit 52675c9b3b
3 changed files with 87 additions and 104 deletions

View File

@@ -285,6 +285,11 @@ struct httplib_callbacks {
void (*exit_context)(const struct httplib_context *ctx); void (*exit_context)(const struct httplib_context *ctx);
}; };
struct httplib_option_t {
const char * name;
const char * value;
};
/* Start web server. /* Start web server.
@@ -970,7 +975,7 @@ LIBHTTP_API int httplib_remove( const char *path );
LIBHTTP_API void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); LIBHTTP_API void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers );
LIBHTTP_API void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func ); LIBHTTP_API void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func );
LIBHTTP_API void httplib_set_user_connection_data( struct httplib_connection *conn, void *data ); LIBHTTP_API void httplib_set_user_connection_data( struct httplib_connection *conn, void *data );
LIBHTTP_API struct httplib_context * httplib_start(const struct httplib_callbacks *callbacks, void *user_data, const char **configuration_options ); LIBHTTP_API struct httplib_context * httplib_start(const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_option_t *options );
LIBHTTP_API void httplib_stop( struct httplib_context *ctx ); LIBHTTP_API void httplib_stop( struct httplib_context *ctx );
LIBHTTP_API int httplib_strcasecmp( const char *s1, const char *s2 ); LIBHTTP_API int httplib_strcasecmp( const char *s1, const char *s2 );
LIBHTTP_API const char * httplib_strcasestr( const char *big_str, const char *small_str ); LIBHTTP_API const char * httplib_strcasestr( const char *big_str, const char *small_str );

View File

@@ -41,11 +41,9 @@ static struct httplib_context * cleanup( struct httplib_context *ctx, PRINTF_FO
* context to the running server for future reference. * context to the running server for future reference.
*/ */
struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks, void *user_data, const char **options ) { struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_option_t *options ) {
struct httplib_context *ctx; struct httplib_context *ctx;
const char *name;
const char *value;
const char *default_value; const char *default_value;
int idx; int idx;
int workerthreadcount; int workerthreadcount;
@@ -152,19 +150,21 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
ctx->user_data = user_data; ctx->user_data = user_data;
ctx->handlers = NULL; ctx->handlers = NULL;
while ( options && (name = *options++) != NULL ) { while ( options && options->name != NULL ) {
idx = XX_httplib_get_option_index( name ); idx = XX_httplib_get_option_index( options->name );
if ( idx == -1 ) return cleanup( ctx, "Invalid option: %s", name ); if ( idx == -1 ) return cleanup( ctx, "Invalid option: %s", options->name );
if ( (value = *options++) == NULL ) return cleanup( ctx, "%s: option value cannot be NULL", name ); if ( options->value == NULL ) return cleanup( ctx, "%s: option value cannot be NULL", options->name );
if ( ctx->cfg[idx] != NULL ) { if ( ctx->cfg[idx] != NULL ) {
httplib_cry( ctx, NULL, "warning: %s: duplicate option", name ); httplib_cry( ctx, NULL, "warning: %s: duplicate option", options->name );
httplib_free( ctx->cfg[idx] ); httplib_free( ctx->cfg[idx] );
} }
ctx->cfg[idx] = httplib_strdup( value ); ctx->cfg[idx] = httplib_strdup( options->value );
options++;
} }
/* /*

View File

@@ -164,12 +164,12 @@ enum { OPTION_TITLE, OPTION_ICON, NUM_MAIN_OPTIONS };
static struct httplib_option main_config_options[] = { static struct httplib_option main_config_options[] = {
{ "title", CONFIG_TYPE_STRING, NULL }, { "title", CONFIG_TYPE_STRING, NULL },
{ "icon", CONFIG_TYPE_STRING, NULL }, { "icon", CONFIG_TYPE_STRING, NULL },
{NULL, CONFIG_TYPE_UNKNOWN, NULL}}; { NULL, CONFIG_TYPE_UNKNOWN, NULL }
};
static void WINCDECL static void WINCDECL signal_handler(int sig_num) {
signal_handler(int sig_num)
{
g_exit_flag = sig_num; g_exit_flag = sig_num;
} }
@@ -215,9 +215,7 @@ static NO_RETURN void show_usage_and_exit(const char *exeName) {
const struct httplib_option *options; const struct httplib_option *options;
int i; int i;
if (exeName == 0 || *exeName == 0) { if ( exeName == NULL || *exeName == '\0' ) exeName = "libhttp";
exeName = "libhttp";
}
show_server_name(); show_server_name();
@@ -237,22 +235,12 @@ static NO_RETURN void show_usage_and_exit(const char *exeName) {
options = httplib_get_valid_options(); options = httplib_get_valid_options();
for (i = 0; options[i].name != NULL; i++) { for (i = 0; options[i].name != NULL; i++) {
fprintf(stderr, fprintf(stderr, " -%s %s\n", options[i].name, ((options[i].default_value == NULL) ? "<empty>" : options[i].default_value));
" -%s %s\n",
options[i].name,
((options[i].default_value == NULL)
? "<empty>"
: options[i].default_value));
} }
options = main_config_options; options = main_config_options;
for (i = 0; options[i].name != NULL; i++) { for (i = 0; options[i].name != NULL; i++) {
fprintf(stderr, fprintf(stderr, " -%s %s\n", options[i].name, ((options[i].default_value == NULL) ? "<empty>" : options[i].default_value));
" -%s %s\n",
options[i].name,
((options[i].default_value == NULL)
? "<empty>"
: options[i].default_value));
} }
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -329,30 +317,22 @@ static char * sdup(const char *str) {
} }
static const char * get_option(char **options, const char *option_name) { static const char * get_option( struct httplib_option_t *options, const char *option_name ) {
int i = 0; int i;
const char *opt_value = NULL;
/* TODO (low, api makeover): options should be an array of key-value-pairs, i = 0;
* like
* struct {const char * key, const char * value} options[] while ( options[i].name != NULL ) {
* but it currently is an array with
* options[2*i] = key, options[2*i + 1] = value if ( strcmp( options[i].name, option_name ) == 0 ) return options[i].value;
* (probably with a MG_LEGACY_INTERFACE definition)
*/
while (options[2 * i] != NULL) {
if (strcmp(options[2 * i], option_name) == 0) {
opt_value = options[2 * i + 1];
break;
}
i++; i++;
} }
return opt_value; return NULL;
} }
static int set_option(char **options, const char *name, const char *value) { static int set_option( struct httplib_option_t *options, const char *name, const char *value ) {
int i; int i;
int type; int type;
@@ -368,10 +348,9 @@ static int set_option(char **options, const char *name, const char *value) {
type = CONFIG_TYPE_UNKNOWN; type = CONFIG_TYPE_UNKNOWN;
for (i = 0; default_options[i].name != NULL; i++) { for (i = 0; default_options[i].name != NULL; i++) {
if (!strcmp(default_options[i].name, name)) { if (!strcmp( default_options[i].name, name ) ) type = default_options[i].type;
type = default_options[i].type;
}
} }
switch (type) { switch (type) {
case CONFIG_TYPE_UNKNOWN: case CONFIG_TYPE_UNKNOWN:
/* unknown option */ /* unknown option */
@@ -406,32 +385,35 @@ static int set_option(char **options, const char *name, const char *value) {
} }
for (i = 0; i < MAX_OPTIONS; i++) { for (i = 0; i < MAX_OPTIONS; i++) {
if (options[2 * i] == NULL) {
options[2 * i] = sdup(name); if ( options[i].name == NULL ) {
options[2 * i + 1] = sdup(value);
options[2 * i + 2] = NULL; options[i].name = sdup( name );
options[i].name = sdup( value );
options[i+1].name = NULL;
break; break;
} else if (!strcmp(options[2 * i], name)) { }
free(options[2 * i + 1]);
options[2 * i + 1] = sdup(value); if ( ! strcmp(options[i].name, name) ) {
free( (void *)options[i].value );
options[i].value = sdup( value );
break; break;
} }
} }
if (i == MAX_OPTIONS) { if ( i == MAX_OPTIONS ) die( "Too many options specified" );
die("Too many options specified");
}
if (options[2 * i] == NULL || options[2 * i + 1] == NULL) { if ( options[i].name == NULL || options[i].value == NULL ) die( "Out of memory" );
die("Out of memory");
}
/* option set correctly */ /* option set correctly */
return 1; return 1;
} }
static int read_config_file(const char *config_file, char **options) { static int read_config_file( const char *config_file, struct httplib_option_t *options ) {
char line[MAX_CONF_FILE_LINE_SIZE], *p; char line[MAX_CONF_FILE_LINE_SIZE], *p;
FILE *fp = NULL; FILE *fp = NULL;
@@ -490,21 +472,17 @@ static int read_config_file(const char *config_file, char **options) {
/* Set option */ /* Set option */
if (!set_option(options, line + i, line + j)) { if (!set_option(options, line + i, line + j)) {
fprintf(stderr, fprintf(stderr, "%s: line %d is invalid, ignoring it:\n %s", config_file, (int)line_no, p);
"%s: line %d is invalid, ignoring it:\n %s",
config_file,
(int)line_no,
p);
} }
} }
(void)fclose(fp); fclose( fp );
} }
return 1; return 1;
} }
static void process_command_line_arguments(int argc, char *argv[], char **options) { static void process_command_line_arguments( int argc, char *argv[], struct httplib_option_t *options ) {
char *p; char *p;
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
@@ -639,7 +617,7 @@ static int is_path_absolute(const char *path) {
} }
static void verify_existence(char **options, const char *option_name, int must_be_dir) { static void verify_existence( struct httplib_option_t *options, const char *option_name, int must_be_dir) {
struct stat st; struct stat st;
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
@@ -671,7 +649,7 @@ static void verify_existence(char **options, const char *option_name, int must_b
} }
static void set_absolute_path(char *options[], const char *option_name, const char *path_to_libhttp_exe) { static void set_absolute_path( struct httplib_option_t *options, const char *option_name, const char *path_to_libhttp_exe ) {
char path[PATH_MAX] = ""; char path[PATH_MAX] = "";
char absolute[PATH_MAX] = ""; char absolute[PATH_MAX] = "";
@@ -714,7 +692,7 @@ static void set_absolute_path(char *options[], const char *option_name, const ch
static void start_libhttp( int argc, char *argv[] ) { static void start_libhttp( int argc, char *argv[] ) {
struct httplib_callbacks callbacks; struct httplib_callbacks callbacks;
char *options[2 * MAX_OPTIONS + 1]; struct httplib_option_t options[MAX_OPTIONS+1] = { { NULL, NULL } };
int i; int i;
/* Start option -I: /* Start option -I:
@@ -842,7 +820,7 @@ static void start_libhttp(int argc, char *argv[]) {
show_usage_and_exit(argv[0]); show_usage_and_exit(argv[0]);
} }
options[0] = NULL; options[0].name = NULL;
set_option( options, "document_root", "." ); set_option( options, "document_root", "." );
/* Update config based on command line arguments */ /* Update config based on command line arguments */
@@ -874,21 +852,21 @@ static void start_libhttp(int argc, char *argv[]) {
/* Start LibHTTP */ /* Start LibHTTP */
memset(&callbacks, 0, sizeof(callbacks)); memset(&callbacks, 0, sizeof(callbacks));
callbacks.log_message = &log_message; callbacks.log_message = &log_message;
g_ctx = httplib_start(&callbacks, &g_user_data, (const char **)options ); g_ctx = httplib_start( &callbacks, &g_user_data, options );
/* httplib_start copies all options to an internal buffer. /* httplib_start copies all options to an internal buffer.
* The options data field here is not required anymore. */ * The options data field here is not required anymore. */
for (i = 0; options[i] != NULL; i++) { for (i=0; options[i].name != NULL; i++) {
free(options[i]);
if ( options[i].name != NULL ) free( (void *)options[i].name );
if ( options[i].value != NULL ) free( (void *)options[i].value );
options[i].name = NULL;
options[i].value = NULL;
} }
/* If httplib_start fails, it returns NULL */ /* If httplib_start fails, it returns NULL */
if (g_ctx == NULL) { if ( g_ctx == NULL ) die("Failed to start %s:\n%s", g_server_name, ((g_user_data.first_message == NULL) ? "unknown reason" : g_user_data.first_message));
die("Failed to start %s:\n%s",
g_server_name,
((g_user_data.first_message == NULL) ? "unknown reason"
: g_user_data.first_message));
}
} }