mirror of
https://github.com/lammertb/libhttp.git
synced 2025-08-06 05:02:40 +03:00
Client contexts are now real, not fake
This commit is contained in:
45
Makefile
45
Makefile
@@ -189,6 +189,7 @@ OBJLIST = \
|
|||||||
${OBJDIR}extern_md5${OBJEXT} \
|
${OBJDIR}extern_md5${OBJEXT} \
|
||||||
${OBJDIR}extern_sha1${OBJEXT} \
|
${OBJDIR}extern_sha1${OBJEXT} \
|
||||||
${OBJDIR}extern_ssl_lut${OBJEXT} \
|
${OBJDIR}extern_ssl_lut${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_abort_start${OBJEXT} \
|
||||||
${OBJDIR}httplib_accept_new_connection${OBJEXT} \
|
${OBJDIR}httplib_accept_new_connection${OBJEXT} \
|
||||||
${OBJDIR}httplib_addenv${OBJEXT} \
|
${OBJDIR}httplib_addenv${OBJEXT} \
|
||||||
${OBJDIR}httplib_atomic_dec${OBJEXT} \
|
${OBJDIR}httplib_atomic_dec${OBJEXT} \
|
||||||
@@ -204,14 +205,15 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_close_socket_gracefully${OBJEXT} \
|
${OBJDIR}httplib_close_socket_gracefully${OBJEXT} \
|
||||||
${OBJDIR}httplib_closedir${OBJEXT} \
|
${OBJDIR}httplib_closedir${OBJEXT} \
|
||||||
${OBJDIR}httplib_compare_dir_entries${OBJEXT} \
|
${OBJDIR}httplib_compare_dir_entries${OBJEXT} \
|
||||||
${OBJDIR}httplib_config_options${OBJEXT} \
|
|
||||||
${OBJDIR}httplib_connect_client${OBJEXT} \
|
${OBJDIR}httplib_connect_client${OBJEXT} \
|
||||||
${OBJDIR}httplib_connect_socket${OBJEXT} \
|
${OBJDIR}httplib_connect_socket${OBJEXT} \
|
||||||
${OBJDIR}httplib_connect_websocket_client${OBJEXT} \
|
${OBJDIR}httplib_connect_websocket_client${OBJEXT} \
|
||||||
${OBJDIR}httplib_construct_etag${OBJEXT} \
|
${OBJDIR}httplib_construct_etag${OBJEXT} \
|
||||||
${OBJDIR}httplib_consume_socket${OBJEXT} \
|
${OBJDIR}httplib_consume_socket${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_create_client_context${OBJEXT} \
|
||||||
${OBJDIR}httplib_cry${OBJEXT} \
|
${OBJDIR}httplib_cry${OBJEXT} \
|
||||||
${OBJDIR}httplib_delete_file${OBJEXT} \
|
${OBJDIR}httplib_delete_file${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_destroy_client_context${OBJEXT} \
|
||||||
${OBJDIR}httplib_difftimespec${OBJEXT} \
|
${OBJDIR}httplib_difftimespec${OBJEXT} \
|
||||||
${OBJDIR}httplib_dir_scan_callback${OBJEXT} \
|
${OBJDIR}httplib_dir_scan_callback${OBJEXT} \
|
||||||
${OBJDIR}httplib_discard_unread_request_data${OBJEXT} \
|
${OBJDIR}httplib_discard_unread_request_data${OBJEXT} \
|
||||||
@@ -223,6 +225,7 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_fgets${OBJEXT} \
|
${OBJDIR}httplib_fgets${OBJEXT} \
|
||||||
${OBJDIR}httplib_fopen${OBJEXT} \
|
${OBJDIR}httplib_fopen${OBJEXT} \
|
||||||
${OBJDIR}httplib_forward_body_data${OBJEXT} \
|
${OBJDIR}httplib_forward_body_data${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_free_config_options${OBJEXT} \
|
||||||
${OBJDIR}httplib_free_context${OBJEXT} \
|
${OBJDIR}httplib_free_context${OBJEXT} \
|
||||||
${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} \
|
${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} \
|
||||||
${OBJDIR}httplib_get_context${OBJEXT} \
|
${OBJDIR}httplib_get_context${OBJEXT} \
|
||||||
@@ -260,6 +263,7 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_handle_websocket_request${OBJEXT} \
|
${OBJDIR}httplib_handle_websocket_request${OBJEXT} \
|
||||||
${OBJDIR}httplib_header_has_option${OBJEXT} \
|
${OBJDIR}httplib_header_has_option${OBJEXT} \
|
||||||
${OBJDIR}httplib_inet_pton${OBJEXT} \
|
${OBJDIR}httplib_inet_pton${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_init_options${OBJEXT} \
|
||||||
${OBJDIR}httplib_initialize_ssl${OBJEXT} \
|
${OBJDIR}httplib_initialize_ssl${OBJEXT} \
|
||||||
${OBJDIR}httplib_interpret_uri${OBJEXT} \
|
${OBJDIR}httplib_interpret_uri${OBJEXT} \
|
||||||
${OBJDIR}httplib_is_authorized_for_put${OBJEXT} \
|
${OBJDIR}httplib_is_authorized_for_put${OBJEXT} \
|
||||||
@@ -270,6 +274,7 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_is_valid_http_method${OBJEXT} \
|
${OBJDIR}httplib_is_valid_http_method${OBJEXT} \
|
||||||
${OBJDIR}httplib_is_valid_port${OBJEXT} \
|
${OBJDIR}httplib_is_valid_port${OBJEXT} \
|
||||||
${OBJDIR}httplib_is_websocket_protocol${OBJEXT} \
|
${OBJDIR}httplib_is_websocket_protocol${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_process_options${OBJEXT} \
|
||||||
${OBJDIR}httplib_pthread_join${OBJEXT} \
|
${OBJDIR}httplib_pthread_join${OBJEXT} \
|
||||||
${OBJDIR}httplib_kill${OBJEXT} \
|
${OBJDIR}httplib_kill${OBJEXT} \
|
||||||
${OBJDIR}httplib_load_dll${OBJEXT} \
|
${OBJDIR}httplib_load_dll${OBJEXT} \
|
||||||
@@ -375,6 +380,8 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_strndup${OBJEXT} \
|
${OBJDIR}httplib_strndup${OBJEXT} \
|
||||||
${OBJDIR}httplib_substitute_index_file${OBJEXT} \
|
${OBJDIR}httplib_substitute_index_file${OBJEXT} \
|
||||||
${OBJDIR}httplib_suggest_connection_header${OBJEXT} \
|
${OBJDIR}httplib_suggest_connection_header${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_system_exit${OBJEXT} \
|
||||||
|
${OBJDIR}httplib_system_init${OBJEXT} \
|
||||||
${OBJDIR}httplib_timer${OBJEXT} \
|
${OBJDIR}httplib_timer${OBJEXT} \
|
||||||
${OBJDIR}httplib_tls_dtor${OBJEXT} \
|
${OBJDIR}httplib_tls_dtor${OBJEXT} \
|
||||||
${OBJDIR}httplib_uninitialize_ssl${OBJEXT} \
|
${OBJDIR}httplib_uninitialize_ssl${OBJEXT} \
|
||||||
@@ -448,6 +455,10 @@ ${OBJDIR}extern_ssl_lut${OBJEXT} : ${SRCDIR}extern_ssl_lut.c \
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_abort_start${OBJEXT} : ${SRCDIR}httplib_abort_start.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_accept_new_connection${OBJEXT} : ${SRCDIR}httplib_accept_new_connection.c \
|
${OBJDIR}httplib_accept_new_connection${OBJEXT} : ${SRCDIR}httplib_accept_new_connection.c \
|
||||||
${SRCDIR}httplib_ssl.h \
|
${SRCDIR}httplib_ssl.h \
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
@@ -517,10 +528,6 @@ ${OBJDIR}httplib_compare_dir_entries${OBJEXT} : ${SRCDIR}httplib_compare_dir_
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_config_options${OBJEXT} : ${SRCDIR}httplib_config_options.c \
|
|
||||||
${SRCDIR}httplib_main.h \
|
|
||||||
${INCDIR}libhttp.h
|
|
||||||
|
|
||||||
${OBJDIR}httplib_connect_client${OBJEXT} : ${SRCDIR}httplib_connect_client.c \
|
${OBJDIR}httplib_connect_client${OBJEXT} : ${SRCDIR}httplib_connect_client.c \
|
||||||
${SRCDIR}httplib_pthread.h \
|
${SRCDIR}httplib_pthread.h \
|
||||||
${SRCDIR}httplib_ssl.h \
|
${SRCDIR}httplib_ssl.h \
|
||||||
@@ -550,6 +557,10 @@ ${OBJDIR}httplib_consume_socket${OBJEXT} : ${SRCDIR}httplib_consume_socket.c
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_create_client_context${OBJEXT} : ${SRCDIR}httplib_create_client_context.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_cry${OBJEXT} : ${SRCDIR}httplib_cry.c \
|
${OBJDIR}httplib_cry${OBJEXT} : ${SRCDIR}httplib_cry.c \
|
||||||
${SRCDIR}httplib_ssl.h \
|
${SRCDIR}httplib_ssl.h \
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
@@ -559,6 +570,10 @@ ${OBJDIR}httplib_delete_file${OBJEXT} : ${SRCDIR}httplib_delete_file.c \
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_destroy_client_context${OBJEXT} : ${SRCDIR}httplib_destroy_client_context.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_difftimespec${OBJEXT} : ${SRCDIR}httplib_difftimespec.c \
|
${OBJDIR}httplib_difftimespec${OBJEXT} : ${SRCDIR}httplib_difftimespec.c \
|
||||||
${SRCDIR}httplib_utils.h \
|
${SRCDIR}httplib_utils.h \
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
@@ -606,6 +621,10 @@ ${OBJDIR}httplib_forward_body_data${OBJEXT} : ${SRCDIR}httplib_forward_body_d
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_free_config_options${OBJEXT} : ${SRCDIR}httplib_free_config_options.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_free_context${OBJEXT} : ${SRCDIR}httplib_free_context.c \
|
${OBJDIR}httplib_free_context${OBJEXT} : ${SRCDIR}httplib_free_context.c \
|
||||||
${SRCDIR}httplib_pthread.h \
|
${SRCDIR}httplib_pthread.h \
|
||||||
${SRCDIR}httplib_ssl.h \
|
${SRCDIR}httplib_ssl.h \
|
||||||
@@ -776,6 +795,10 @@ ${OBJDIR}httplib_inet_pton${OBJEXT} : ${SRCDIR}httplib_inet_pton.c \
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_init_options${OBJEXT} : ${SRCDIR}httplib_init_options.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_initialize_ssl${OBJEXT} : ${SRCDIR}httplib_initialize_ssl.c \
|
${OBJDIR}httplib_initialize_ssl${OBJEXT} : ${SRCDIR}httplib_initialize_ssl.c \
|
||||||
${SRCDIR}httplib_pthread.h \
|
${SRCDIR}httplib_pthread.h \
|
||||||
${SRCDIR}httplib_ssl.h \
|
${SRCDIR}httplib_ssl.h \
|
||||||
@@ -821,6 +844,10 @@ ${OBJDIR}httplib_is_websocket_protocol${OBJEXT} : ${SRCDIR}httplib_is_websock
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_process_options${OBJEXT} : ${SRCDIR}httplib_process_options.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_pthread_join${OBJEXT} : ${SRCDIR}httplib_pthread_join.c \
|
${OBJDIR}httplib_pthread_join${OBJEXT} : ${SRCDIR}httplib_pthread_join.c \
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
@@ -1303,6 +1330,14 @@ ${OBJDIR}httplib_substitute_index_file${OBJEXT} : ${SRCDIR}httplib_substitute
|
|||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_system_exit${OBJEXT} : ${SRCDIR}httplib_system_exit.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
|
${OBJDIR}httplib_system_init${OBJEXT} : ${SRCDIR}httplib_system_init.c \
|
||||||
|
${SRCDIR}httplib_main.h \
|
||||||
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}httplib_suggest_connection_header${OBJEXT} : ${SRCDIR}httplib_suggest_connection_header.c \
|
${OBJDIR}httplib_suggest_connection_header${OBJEXT} : ${SRCDIR}httplib_suggest_connection_header.c \
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
@@ -667,14 +667,6 @@ LIBHTTP_API int httplib_get_cookie(const char *cookie, const char *var_name, cha
|
|||||||
conn = httplib_download("google.com", 80, 0, ebuf, sizeof(ebuf),
|
conn = httplib_download("google.com", 80, 0, ebuf, sizeof(ebuf),
|
||||||
"%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
|
"%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
|
||||||
*/
|
*/
|
||||||
LIBHTTP_API struct httplib_connection *
|
|
||||||
httplib_download(const char *host,
|
|
||||||
int port,
|
|
||||||
int use_ssl,
|
|
||||||
char *error_buffer,
|
|
||||||
size_t error_buffer_size,
|
|
||||||
PRINTF_FORMAT_STRING(const char *request_fmt),
|
|
||||||
...) PRINTF_ARGS(6, 7);
|
|
||||||
|
|
||||||
|
|
||||||
/* Close the connection opened by httplib_download(). */
|
/* Close the connection opened by httplib_download(). */
|
||||||
@@ -841,16 +833,6 @@ LIBHTTP_API char *httplib_md5(char buf[33], ...);
|
|||||||
On success, valid httplib_connection object.
|
On success, valid httplib_connection object.
|
||||||
On error, NULL. Se error_buffer for details.
|
On error, NULL. Se error_buffer for details.
|
||||||
*/
|
*/
|
||||||
LIBHTTP_API struct httplib_connection *httplib_connect_websocket_client( const char *host,
|
|
||||||
int port,
|
|
||||||
int use_ssl,
|
|
||||||
char *error_buffer,
|
|
||||||
size_t error_buffer_size,
|
|
||||||
const char *path,
|
|
||||||
const char *origin,
|
|
||||||
httplib_websocket_data_handler data_func,
|
|
||||||
httplib_websocket_close_handler close_func,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
|
/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
|
||||||
@@ -865,7 +847,6 @@ LIBHTTP_API struct httplib_connection *httplib_connect_websocket_client( const c
|
|||||||
On success, valid httplib_connection object.
|
On success, valid httplib_connection object.
|
||||||
On error, NULL. Se error_buffer for details.
|
On error, NULL. Se error_buffer for details.
|
||||||
*/
|
*/
|
||||||
LIBHTTP_API struct httplib_connection *httplib_connect_client(const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size);
|
|
||||||
|
|
||||||
|
|
||||||
struct httplib_client_options {
|
struct httplib_client_options {
|
||||||
@@ -877,7 +858,6 @@ struct httplib_client_options {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LIBHTTP_API struct httplib_connection *httplib_connect_client_secure(const struct httplib_client_options *client_options, char *error_buffer, size_t error_buffer_size);
|
|
||||||
|
|
||||||
|
|
||||||
enum debug_level_t {
|
enum debug_level_t {
|
||||||
@@ -924,7 +904,13 @@ LIBHTTP_API int httplib_atomic_inc( volatile int *addr );
|
|||||||
LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, char *dst, int dst_len );
|
LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, char *dst, int dst_len );
|
||||||
LIBHTTP_API unsigned httplib_check_feature( unsigned feature );
|
LIBHTTP_API unsigned httplib_check_feature( unsigned feature );
|
||||||
LIBHTTP_API int httplib_closedir( DIR *dir );
|
LIBHTTP_API int httplib_closedir( DIR *dir );
|
||||||
|
LIBHTTP_API struct httplib_connection * httplib_connect_client( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size );
|
||||||
|
LIBHTTP_API struct httplib_connection * httplib_connect_client_secure( struct httplib_context *ctx, const struct httplib_client_options *client_options, char *error_buffer, size_t error_buffer_size );
|
||||||
|
LIBHTTP_API struct httplib_connection * httplib_connect_websocket_client( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, httplib_websocket_data_handler data_func, httplib_websocket_close_handler close_func, void *user_data );
|
||||||
|
LIBHTTP_API struct httplib_context * httplib_create_client_context( const struct httplib_option_t *options );
|
||||||
LIBHTTP_API void httplib_cry( enum debug_level_t debug_level, const struct httplib_context *ctx, const struct httplib_connection *conn, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(4, 5);
|
LIBHTTP_API void httplib_cry( enum debug_level_t debug_level, const struct httplib_context *ctx, const struct httplib_connection *conn, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(4, 5);
|
||||||
|
LIBHTTP_API void httplib_destroy_client_context( struct httplib_context *ctx );
|
||||||
|
LIBHTTP_API struct httplib_connection * httplib_download( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, PRINTF_FORMAT_STRING(const char *request_fmt), ...) PRINTF_ARGS(7, 8);
|
||||||
LIBHTTP_API char * httplib_error_string( int error_code, char *buf, size_t buf_len );
|
LIBHTTP_API char * httplib_error_string( int error_code, char *buf, size_t buf_len );
|
||||||
LIBHTTP_API const char * httplib_get_builtin_mime_type( const char *file_name );
|
LIBHTTP_API const char * httplib_get_builtin_mime_type( const char *file_name );
|
||||||
LIBHTTP_API enum debug_level_t httplib_get_debug_level( struct httplib_context *ctx );
|
LIBHTTP_API enum debug_level_t httplib_get_debug_level( struct httplib_context *ctx );
|
||||||
@@ -967,6 +953,8 @@ LIBHTTP_API char * httplib_strdup( const char *str );
|
|||||||
LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len );
|
LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len );
|
||||||
LIBHTTP_API int httplib_strncasecmp( const char *s1, const char *s2, size_t len );
|
LIBHTTP_API int httplib_strncasecmp( const char *s1, const char *s2, size_t len );
|
||||||
LIBHTTP_API char * httplib_strndup( const char *str, size_t len );
|
LIBHTTP_API char * httplib_strndup( const char *str, size_t len );
|
||||||
|
LIBHTTP_API int httplib_system_exit( void );
|
||||||
|
LIBHTTP_API int httplib_system_init( void );
|
||||||
LIBHTTP_API const char * httplib_version( void );
|
LIBHTTP_API const char * httplib_version( void );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
56
src/httplib_abort_start.c
Normal file
56
src/httplib_abort_start.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct httplib_context *XX_httplib_abort_start( struct httplib_context *ctx, const char *fmt, ... );
|
||||||
|
*
|
||||||
|
* The function XX_httplib_abort_start() is called to do some cleanup work when
|
||||||
|
* an error occured initializing a context. The function returns NULL which is
|
||||||
|
* then further returned to the calling party.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct httplib_context *XX_httplib_abort_start( struct httplib_context *ctx, const char *fmt, ... ) {
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
char buf[MG_BUF_LEN];
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return NULL;
|
||||||
|
|
||||||
|
if ( fmt != NULL ) {
|
||||||
|
|
||||||
|
va_start( ap, fmt );
|
||||||
|
vsnprintf_impl( buf, sizeof(buf), fmt, ap );
|
||||||
|
va_end( ap );
|
||||||
|
buf[sizeof(buf)-1] = 0;
|
||||||
|
|
||||||
|
httplib_cry( DEBUG_LEVEL_CRASH, ctx, NULL, "%s", buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
XX_httplib_free_context( ctx );
|
||||||
|
|
||||||
|
httplib_pthread_setspecific( XX_httplib_sTlsKey, NULL );
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} /* XX_httplib_abort_start */
|
@@ -30,30 +30,30 @@
|
|||||||
#include "httplib_ssl.h"
|
#include "httplib_ssl.h"
|
||||||
#include "httplib_string.h"
|
#include "httplib_string.h"
|
||||||
|
|
||||||
static struct httplib_connection * httplib_connect_client_impl( const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len );
|
static struct httplib_connection * httplib_connect_client_impl( struct httplib_context *ctx, const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct httplib_connection *httplib_connect_client_secure( const struct httplib_client_options *client options, char *error buffer, size_t error_buffer_size );
|
* struct httplib_connection *httplib_connect_client_secure( struct httplib_context_*ctx, const struct httplib_client_options *client options, char *error buffer, size_t error_buffer_size );
|
||||||
*
|
*
|
||||||
* The function httplib_connect_client_secure() creates a secure connection as a
|
* The function httplib_connect_client_secure() creates a secure connection as a
|
||||||
* client to a remote server and returns a pointer to the connection
|
* client to a remote server and returns a pointer to the connection
|
||||||
* information, or NULL if an error occured.
|
* information, or NULL if an error occured.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LIBHTTP_API struct httplib_connection *httplib_connect_client_secure( const struct httplib_client_options *client_options, char *error_buffer, size_t error_buffer_size ) {
|
LIBHTTP_API struct httplib_connection *httplib_connect_client_secure( struct httplib_context *ctx, const struct httplib_client_options *client_options, char *error_buffer, size_t error_buffer_size ) {
|
||||||
|
|
||||||
return httplib_connect_client_impl( client_options, 1, error_buffer, error_buffer_size );
|
return httplib_connect_client_impl( ctx, client_options, 1, error_buffer, error_buffer_size );
|
||||||
|
|
||||||
} /* httplib_connect_client_secure */
|
} /* httplib_connect_client_secure */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct httplib_connection *httplib_connect_client( const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size );
|
* struct httplib_connection *httplib_connect_client( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size );
|
||||||
*
|
*
|
||||||
* The function httplib_connect_client() connects to a remote server as a client
|
* The function httplib_connect_client() connects to a remote server as a client
|
||||||
* with the options of the connection provided as parameters.
|
* with the options of the connection provided as parameters.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct httplib_connection * httplib_connect_client( const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size ) {
|
struct httplib_connection *httplib_connect_client( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size ) {
|
||||||
|
|
||||||
struct httplib_client_options opts;
|
struct httplib_client_options opts;
|
||||||
|
|
||||||
@@ -61,22 +61,21 @@ struct httplib_connection * httplib_connect_client( const char *host, int port,
|
|||||||
opts.host = host;
|
opts.host = host;
|
||||||
opts.port = port;
|
opts.port = port;
|
||||||
|
|
||||||
return httplib_connect_client_impl( &opts, use_ssl, error_buffer, error_buffer_size );
|
return httplib_connect_client_impl( ctx, &opts, use_ssl, error_buffer, error_buffer_size );
|
||||||
|
|
||||||
} /* httplib_connect_client */
|
} /* httplib_connect_client */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* static struct httplib_connection *httplib_connect_client_impl( const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len );
|
* static struct httplib_connection *httplib_connect_client_impl( struct httplib_context *ctx, const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len );
|
||||||
*
|
*
|
||||||
* The function httplib_connect_client_impl() is the background function doing the
|
* The function httplib_connect_client_impl() is the background function doing the
|
||||||
* heavy lifting to make connections as a client to remote servers.
|
* heavy lifting to make connections as a client to remote servers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct httplib_connection *httplib_connect_client_impl( const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len ) {
|
static struct httplib_connection *httplib_connect_client_impl( struct httplib_context *ctx, const struct httplib_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len ) {
|
||||||
|
|
||||||
static struct httplib_context fake_ctx;
|
|
||||||
struct httplib_connection *conn;
|
struct httplib_connection *conn;
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
union usa sa;
|
union usa sa;
|
||||||
@@ -84,6 +83,8 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
|||||||
struct sockaddr *psa;
|
struct sockaddr *psa;
|
||||||
char error_string[ERROR_STRING_LEN];
|
char error_string[ERROR_STRING_LEN];
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return NULL;
|
||||||
|
|
||||||
if ( ! XX_httplib_connect_socket( client_options->host, client_options->port, use_ssl, ebuf, ebuf_len, &sock, &sa ) ) return NULL;
|
if ( ! XX_httplib_connect_socket( client_options->host, client_options->port, use_ssl, ebuf, ebuf_len, &sock, &sa ) ) return NULL;
|
||||||
|
|
||||||
if ( (conn = httplib_calloc( 1, sizeof(*conn) + MAX_REQUEST_SIZE )) == NULL ) {
|
if ( (conn = httplib_calloc( 1, sizeof(*conn) + MAX_REQUEST_SIZE )) == NULL ) {
|
||||||
@@ -108,11 +109,11 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
|||||||
|
|
||||||
conn->buf_size = MAX_REQUEST_SIZE;
|
conn->buf_size = MAX_REQUEST_SIZE;
|
||||||
conn->buf = (char *)(conn + 1);
|
conn->buf = (char *)(conn + 1);
|
||||||
conn->ctx = &fake_ctx;
|
conn->ctx = ctx;
|
||||||
conn->client.sock = sock;
|
conn->client.sock = sock;
|
||||||
conn->client.lsa = sa;
|
conn->client.lsa = sa;
|
||||||
|
|
||||||
if ( getsockname( sock, psa, &len ) != 0 ) httplib_cry( DEBUG_LEVEL_ERROR, &fake_ctx, conn, "%s: getsockname() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) );
|
if ( getsockname( sock, psa, &len ) != 0 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: getsockname() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) );
|
||||||
|
|
||||||
conn->client.has_ssl = (use_ssl) ? true : false;
|
conn->client.has_ssl = (use_ssl) ? true : false;
|
||||||
httplib_pthread_mutex_init( &conn->mutex, &XX_httplib_pthread_mutex_attr );
|
httplib_pthread_mutex_init( &conn->mutex, &XX_httplib_pthread_mutex_attr );
|
||||||
@@ -120,7 +121,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
|||||||
#ifndef NO_SSL
|
#ifndef NO_SSL
|
||||||
if ( use_ssl ) {
|
if ( use_ssl ) {
|
||||||
|
|
||||||
fake_ctx.ssl_ctx = conn->client_ssl_ctx;
|
ctx->ssl_ctx = conn->client_ssl_ctx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Check ssl_verify_peer and ssl_ca_path here.
|
* TODO: Check ssl_verify_peer and ssl_ca_path here.
|
||||||
@@ -134,7 +135,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
|||||||
|
|
||||||
if ( client_options->client_cert ) {
|
if ( client_options->client_cert ) {
|
||||||
|
|
||||||
if ( ! XX_httplib_ssl_use_pem_file( &fake_ctx, client_options->client_cert ) ) {
|
if ( ! XX_httplib_ssl_use_pem_file( ctx, client_options->client_cert ) ) {
|
||||||
|
|
||||||
XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "Can not use SSL client certificate" );
|
XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "Can not use SSL client certificate" );
|
||||||
SSL_CTX_free( conn->client_ssl_ctx );
|
SSL_CTX_free( conn->client_ssl_ctx );
|
||||||
|
@@ -36,16 +36,14 @@
|
|||||||
* returned, otherwise NULL.
|
* returned, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct httplib_connection *httplib_connect_websocket_client( const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, httplib_websocket_data_handler data_func, httplib_websocket_close_handler close_func, void *user_data ) {
|
struct httplib_connection *httplib_connect_websocket_client( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, httplib_websocket_data_handler data_func, httplib_websocket_close_handler close_func, void *user_data ) {
|
||||||
|
|
||||||
struct httplib_connection *conn;
|
struct httplib_connection *conn;
|
||||||
struct httplib_context *newctx;
|
|
||||||
struct websocket_client_thread_data *thread_data;
|
struct websocket_client_thread_data *thread_data;
|
||||||
static const char *magic = "x3JJHMbDL1EzLkh9GBhXDw==";
|
static const char *magic = "x3JJHMbDL1EzLkh9GBhXDw==";
|
||||||
const char *handshake_req;
|
const char *handshake_req;
|
||||||
|
|
||||||
conn = NULL;
|
conn = NULL;
|
||||||
newctx = NULL;
|
|
||||||
|
|
||||||
if ( origin != NULL ) handshake_req = "GET %s HTTP/1.1\r\n"
|
if ( origin != NULL ) handshake_req = "GET %s HTTP/1.1\r\n"
|
||||||
"Host: %s\r\n"
|
"Host: %s\r\n"
|
||||||
@@ -68,7 +66,7 @@ struct httplib_connection *httplib_connect_websocket_client( const char *host, i
|
|||||||
* Establish the client connection and request upgrade
|
* Establish the client connection and request upgrade
|
||||||
*/
|
*/
|
||||||
|
|
||||||
conn = httplib_download( host, port, use_ssl, error_buffer, error_buffer_size, handshake_req, path, host, magic, origin );
|
conn = httplib_download( ctx, host, port, use_ssl, error_buffer, error_buffer_size, handshake_req, path, host, magic, origin );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connection object will be null if something goes wrong
|
* Connection object will be null if something goes wrong
|
||||||
@@ -90,36 +88,28 @@ struct httplib_connection *httplib_connect_websocket_client( const char *host, i
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ctx->user_data = user_data;
|
||||||
* For client connections, httplib_context is fake. Since we need to set a
|
ctx->ctx_type = CTX_TYPE_CLIENT;
|
||||||
* callback function, we need to create a copy and modify it.
|
ctx->num_threads = 1; /* one worker thread will be created */
|
||||||
*/
|
ctx->workerthreadids = httplib_calloc( ctx->num_threads, sizeof(pthread_t) );
|
||||||
|
|
||||||
newctx = httplib_malloc( sizeof(struct httplib_context) );
|
if ( ctx->workerthreadids == NULL ) {
|
||||||
if ( newctx == NULL ) { conn = httplib_free( conn ); return NULL; }
|
|
||||||
|
|
||||||
*newctx = *conn->ctx;
|
ctx->num_threads = 0;
|
||||||
newctx->user_data = user_data;
|
ctx->user_data = NULL;
|
||||||
newctx->ctx_type = CTX_TYPE_CLIENT;
|
conn = httplib_free( conn );
|
||||||
newctx->num_threads = 1; /* one worker thread will be created */
|
|
||||||
newctx->workerthreadids = httplib_calloc( newctx->num_threads, sizeof(pthread_t) );
|
|
||||||
|
|
||||||
if ( newctx->workerthreadids == NULL ) {
|
|
||||||
|
|
||||||
newctx = httplib_free( newctx );
|
|
||||||
conn = httplib_free( conn );
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->ctx = newctx;
|
thread_data = httplib_calloc( sizeof(struct websocket_client_thread_data), 1 );
|
||||||
thread_data = httplib_calloc( sizeof(struct websocket_client_thread_data), 1 );
|
|
||||||
|
|
||||||
if ( thread_data == NULL ) {
|
if ( thread_data == NULL ) {
|
||||||
|
|
||||||
newctx->workerthreadids = httplib_free( newctx->workerthreadids );
|
ctx->workerthreadids = httplib_free( ctx->workerthreadids );
|
||||||
newctx = httplib_free( newctx );
|
ctx->num_threads = 0;
|
||||||
conn = httplib_free( conn );
|
ctx->user_data = NULL;
|
||||||
|
conn = httplib_free( conn );
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -135,12 +125,13 @@ struct httplib_connection *httplib_connect_websocket_client( const char *host, i
|
|||||||
* called on the client connection
|
* called on the client connection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( XX_httplib_start_thread_with_id( XX_httplib_websocket_client_thread, thread_data, newctx->workerthreadids) != 0 ) {
|
if ( XX_httplib_start_thread_with_id( XX_httplib_websocket_client_thread, thread_data, ctx->workerthreadids) != 0 ) {
|
||||||
|
|
||||||
thread_data = httplib_free( thread_data );
|
thread_data = httplib_free( thread_data );
|
||||||
newctx->workerthreadids = httplib_free( newctx->workerthreadids );
|
ctx->workerthreadids = httplib_free( ctx->workerthreadids );
|
||||||
newctx = httplib_free( newctx );
|
ctx->num_threads = 0;
|
||||||
conn = httplib_free( conn );
|
ctx->user_data = NULL;
|
||||||
|
conn = httplib_free( conn );
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
46
src/httplib_create_client_context.c
Normal file
46
src/httplib_create_client_context.c
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct httplib_context *httplib_create_client_context( const struct httplib_option_t *options );
|
||||||
|
*
|
||||||
|
* The function httplib_create_client_context() creates a context to be used
|
||||||
|
* for one simultaneous client connection. It is not possible to use one client
|
||||||
|
* context for multiple connections at the same time, because the contect
|
||||||
|
* contains SSL context information which is specific for one connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct httplib_context *httplib_create_client_context( const struct httplib_option_t *options ) {
|
||||||
|
|
||||||
|
struct httplib_context *ctx;
|
||||||
|
|
||||||
|
ctx = httplib_calloc( 1, sizeof(struct httplib_context) );
|
||||||
|
if ( ctx == NULL ) return NULL;
|
||||||
|
|
||||||
|
if ( XX_httplib_init_options( ctx ) ) return NULL;
|
||||||
|
if ( XX_httplib_process_options( ctx, options ) ) return NULL;
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
|
||||||
|
} /* httplib_create_client_context */
|
41
src/httplib_destroy_client_context.c
Normal file
41
src/httplib_destroy_client_context.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void httplib_destroy_client_context( struct httplib_context *ctx );
|
||||||
|
*
|
||||||
|
* The function httplib_destroy_client_context() destroys the context for a
|
||||||
|
* client connection. This function should not be called for server contexts.
|
||||||
|
* Use httplib_stop() for server contexts instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void httplib_destroy_client_context( struct httplib_context *ctx ) {
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return;
|
||||||
|
|
||||||
|
XX_httplib_free_config_options( ctx );
|
||||||
|
|
||||||
|
httplib_free( ctx );
|
||||||
|
|
||||||
|
} /* httplib_destroy_client_context */
|
@@ -35,17 +35,19 @@
|
|||||||
* and returns a pointer to the connection on success, or NULL on error.
|
* and returns a pointer to the connection on success, or NULL on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct httplib_connection * httplib_download( const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, const char *fmt, ... ) {
|
struct httplib_connection * httplib_download( struct httplib_context *ctx, const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, const char *fmt, ... ) {
|
||||||
|
|
||||||
struct httplib_connection *conn;
|
struct httplib_connection *conn;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int i;
|
int i;
|
||||||
int reqerr;
|
int reqerr;
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return NULL;
|
||||||
|
|
||||||
va_start( ap, fmt );
|
va_start( ap, fmt );
|
||||||
ebuf[0] = '\0';
|
ebuf[0] = '\0';
|
||||||
|
|
||||||
conn = httplib_connect_client( host, port, use_ssl, ebuf, ebuf_len );
|
conn = httplib_connect_client( ctx, host, port, use_ssl, ebuf, ebuf_len );
|
||||||
|
|
||||||
if ( conn != NULL ) {
|
if ( conn != NULL ) {
|
||||||
|
|
||||||
|
62
src/httplib_free_config_options.c
Normal file
62
src/httplib_free_config_options.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void XX_httplib_free_config_options( struct htptlib_context *ctx );
|
||||||
|
*
|
||||||
|
* The function XX_httplib_free_config_options() returns all the from the heap
|
||||||
|
* allocated space to store config options back to the heap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void XX_httplib_free_config_options( struct httplib_context *ctx ) {
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return;
|
||||||
|
|
||||||
|
ctx->access_control_allow_origin = httplib_free( ctx->access_control_allow_origin );
|
||||||
|
ctx->access_control_list = httplib_free( ctx->access_control_list );
|
||||||
|
ctx->access_log_file = httplib_free( ctx->access_log_file );
|
||||||
|
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->error_pages = httplib_free( ctx->error_pages );
|
||||||
|
ctx->extra_mime_types = httplib_free( ctx->extra_mime_types );
|
||||||
|
ctx->global_auth_file = httplib_free( ctx->global_auth_file );
|
||||||
|
ctx->hide_file_pattern = httplib_free( ctx->hide_file_pattern );
|
||||||
|
ctx->index_files = httplib_free( ctx->index_files );
|
||||||
|
ctx->listening_ports = httplib_free( ctx->listening_ports );
|
||||||
|
ctx->protect_uri = httplib_free( ctx->protect_uri );
|
||||||
|
ctx->put_delete_auth_file = httplib_free( ctx->put_delete_auth_file );
|
||||||
|
ctx->run_as_user = httplib_free( ctx->run_as_user );
|
||||||
|
ctx->ssi_pattern = httplib_free( ctx->ssi_pattern );
|
||||||
|
ctx->ssl_ca_file = httplib_free( ctx->ssl_ca_file );
|
||||||
|
ctx->ssl_ca_path = httplib_free( ctx->ssl_ca_path );
|
||||||
|
ctx->ssl_certificate = httplib_free( ctx->ssl_certificate );
|
||||||
|
ctx->ssl_cipher_list = httplib_free( ctx->ssl_cipher_list );
|
||||||
|
ctx->throttle = httplib_free( ctx->throttle );
|
||||||
|
ctx->url_rewrite_patterns = httplib_free( ctx->url_rewrite_patterns );
|
||||||
|
ctx->websocket_root = httplib_free( ctx->websocket_root );
|
||||||
|
|
||||||
|
} /* XX_httplib_free_config_options */
|
@@ -74,35 +74,7 @@ void XX_httplib_free_context( struct httplib_context *ctx ) {
|
|||||||
timers_exit( ctx );
|
timers_exit( ctx );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
XX_httplib_free_config_options( ctx );
|
||||||
* Deallocate config parameters
|
|
||||||
*/
|
|
||||||
|
|
||||||
ctx->access_control_allow_origin = httplib_free( ctx->access_control_allow_origin );
|
|
||||||
ctx->access_control_list = httplib_free( ctx->access_control_list );
|
|
||||||
ctx->access_log_file = httplib_free( ctx->access_log_file );
|
|
||||||
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->error_pages = httplib_free( ctx->error_pages );
|
|
||||||
ctx->extra_mime_types = httplib_free( ctx->extra_mime_types );
|
|
||||||
ctx->global_auth_file = httplib_free( ctx->global_auth_file );
|
|
||||||
ctx->hide_file_pattern = httplib_free( ctx->hide_file_pattern );
|
|
||||||
ctx->index_files = httplib_free( ctx->index_files );
|
|
||||||
ctx->listening_ports = httplib_free( ctx->listening_ports );
|
|
||||||
ctx->protect_uri = httplib_free( ctx->protect_uri );
|
|
||||||
ctx->put_delete_auth_file = httplib_free( ctx->put_delete_auth_file );
|
|
||||||
ctx->run_as_user = httplib_free( ctx->run_as_user );
|
|
||||||
ctx->ssi_pattern = httplib_free( ctx->ssi_pattern );
|
|
||||||
ctx->ssl_ca_file = httplib_free( ctx->ssl_ca_file );
|
|
||||||
ctx->ssl_ca_path = httplib_free( ctx->ssl_ca_path );
|
|
||||||
ctx->ssl_certificate = httplib_free( ctx->ssl_certificate );
|
|
||||||
ctx->ssl_cipher_list = httplib_free( ctx->ssl_cipher_list );
|
|
||||||
ctx->throttle = httplib_free( ctx->throttle );
|
|
||||||
ctx->url_rewrite_patterns = httplib_free( ctx->url_rewrite_patterns );
|
|
||||||
ctx->websocket_root = httplib_free( ctx->websocket_root );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deallocate request handlers
|
* Deallocate request handlers
|
||||||
|
118
src/httplib_init_options.c
Normal file
118
src/httplib_init_options.c
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bool XX_httplib_init_options( struct httplib_context *ctx );
|
||||||
|
*
|
||||||
|
* The function XX_httplib_init_options() sets the options of a newly created
|
||||||
|
* context to reasonablei default values. When succesful, the function returns
|
||||||
|
* false. Otherwise true is returned, and the function already performed a
|
||||||
|
* cleanup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool XX_httplib_init_options( struct httplib_context *ctx ) {
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return true;
|
||||||
|
|
||||||
|
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->cgi_pattern = NULL;
|
||||||
|
ctx->debug_level = DEBUG_LEVEL_WARNING;
|
||||||
|
ctx->decode_url = true;
|
||||||
|
ctx->document_root = NULL;
|
||||||
|
ctx->enable_directory_listing = true;
|
||||||
|
ctx->enable_keep_alive = false;
|
||||||
|
ctx->error_log_file = NULL;
|
||||||
|
ctx->error_pages = NULL;
|
||||||
|
ctx->extra_mime_types = NULL;
|
||||||
|
ctx->global_auth_file = NULL;
|
||||||
|
ctx->hide_file_pattern = 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->ssi_pattern = NULL;
|
||||||
|
ctx->ssl_ca_file = NULL;
|
||||||
|
ctx->ssl_ca_path = 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_root = NULL;
|
||||||
|
ctx->websocket_timeout = 30000;
|
||||||
|
|
||||||
|
if ( (ctx->access_control_allow_origin = httplib_strdup( "*" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"access_control_allow_origin\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ctx->authentication_domain = httplib_strdup( "example.com" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"authentication_domain\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ctx->cgi_pattern = httplib_strdup( "**.cgi$|**.pl$|**.php$" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"cgi_pattern\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ctx->index_files = httplib_strdup( "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"index_files\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ctx->listening_ports = httplib_strdup( "8080" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"listening_ports\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ctx->ssi_pattern = httplib_strdup( "**.shtml$|**.shtm$" )) == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory creating context allocating \"ssi_pattern\"" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} /* XX_httplib_init_options */
|
@@ -786,6 +786,7 @@ void SHA1Final( unsigned char digest[20], SHA1_CTX *context );
|
|||||||
void SHA1Init( SHA1_CTX *context );
|
void SHA1Init( SHA1_CTX *context );
|
||||||
void SHA1Update( SHA1_CTX *context, const unsigned char *data, uint32_t len );
|
void SHA1Update( SHA1_CTX *context, const unsigned char *data, uint32_t len );
|
||||||
|
|
||||||
|
struct httplib_context *XX_httplib_abort_start( struct httplib_context *ctx, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||||
void XX_httplib_accept_new_connection( const struct socket *listener, struct httplib_context *ctx );
|
void XX_httplib_accept_new_connection( const struct socket *listener, struct httplib_context *ctx );
|
||||||
bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep );
|
bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep );
|
||||||
const char * XX_httplib_builtin_mime_ext( int index );
|
const char * XX_httplib_builtin_mime_ext( int index );
|
||||||
@@ -808,6 +809,7 @@ void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection
|
|||||||
const char * XX_httplib_fgets( char *buf, size_t size, struct file *filep, char **p );
|
const char * XX_httplib_fgets( char *buf, size_t size, struct file *filep, char **p );
|
||||||
bool XX_httplib_fopen( const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep );
|
bool XX_httplib_fopen( const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep );
|
||||||
bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl );
|
bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl );
|
||||||
|
void XX_httplib_free_config_options( struct httplib_context *ctx );
|
||||||
void XX_httplib_free_context( struct httplib_context *ctx );
|
void XX_httplib_free_context( struct httplib_context *ctx );
|
||||||
const char * XX_httplib_get_header( const struct httplib_request_info *ri, const char *name );
|
const char * XX_httplib_get_header( const struct httplib_request_info *ri, const char *name );
|
||||||
void XX_httplib_get_mime_type( struct httplib_context *ctx, const char *path, struct vec *vec );
|
void XX_httplib_get_mime_type( struct httplib_context *ctx, const char *path, struct vec *vec );
|
||||||
@@ -828,6 +830,7 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, cons
|
|||||||
void XX_httplib_handle_static_file_request( struct httplib_connection *conn, const char *path, struct file *filep, const char *mime_type, const char *additional_headers );
|
void XX_httplib_handle_static_file_request( struct httplib_connection *conn, const char *path, struct file *filep, const char *mime_type, const char *additional_headers );
|
||||||
void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const char *path, int is_callback_resource, httplib_websocket_connect_handler ws_connect_handler, httplib_websocket_ready_handler ws_ready_handler, httplib_websocket_data_handler ws_data_handler, httplib_websocket_close_handler ws_close_handler, void *cbData );
|
void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const char *path, int is_callback_resource, httplib_websocket_connect_handler ws_connect_handler, httplib_websocket_ready_handler ws_ready_handler, httplib_websocket_data_handler ws_data_handler, httplib_websocket_close_handler ws_close_handler, void *cbData );
|
||||||
bool XX_httplib_header_has_option( const char *header, const char *option );
|
bool XX_httplib_header_has_option( const char *header, const char *option );
|
||||||
|
bool XX_httplib_init_options( struct httplib_context *ctx );
|
||||||
void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, size_t filename_buf_len, struct file *filep, bool *is_found, bool *is_script_resource, bool *is_websocket_request, bool *is_put_or_delete_request );
|
void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, size_t filename_buf_len, struct file *filep, bool *is_found, bool *is_script_resource, bool *is_websocket_request, bool *is_put_or_delete_request );
|
||||||
bool XX_httplib_is_authorized_for_put( struct httplib_connection *conn );
|
bool XX_httplib_is_authorized_for_put( struct httplib_connection *conn );
|
||||||
bool XX_httplib_is_file_in_memory( const struct httplib_connection *conn, const char *path, struct file *filep );
|
bool XX_httplib_is_file_in_memory( const struct httplib_connection *conn, const char *path, struct file *filep );
|
||||||
@@ -857,6 +860,7 @@ void XX_httplib_path_to_unicode( const char *path, wchar_t *wbuf, size_t wbuf_
|
|||||||
void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const char *prog, struct cgi_environment *env );
|
void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const char *prog, struct cgi_environment *env );
|
||||||
void XX_httplib_print_dir_entry( struct de *de );
|
void XX_httplib_print_dir_entry( struct de *de );
|
||||||
void XX_httplib_process_new_connection( struct httplib_connection *conn );
|
void XX_httplib_process_new_connection( struct httplib_connection *conn );
|
||||||
|
bool XX_httplib_process_options( struct httplib_context *ctx, const struct httplib_option_t *options );
|
||||||
void XX_httplib_produce_socket( struct httplib_context *ctx, const struct socket *sp );
|
void XX_httplib_produce_socket( struct httplib_context *ctx, const struct socket *sp );
|
||||||
int XX_httplib_pull( FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout );
|
int XX_httplib_pull( FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout );
|
||||||
int XX_httplib_pull_all( FILE *fp, struct httplib_connection *conn, char *buf, int len );
|
int XX_httplib_pull_all( FILE *fp, struct httplib_connection *conn, char *buf, int len );
|
||||||
@@ -929,3 +933,5 @@ extern pthread_mutexattr_t XX_httplib_pthread_mutex_attr;
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
extern const struct uriprot_tp XX_httplib_abs_uri_protocols[];
|
extern const struct uriprot_tp XX_httplib_abs_uri_protocols[];
|
||||||
|
extern int XX_httplib_sTlsInit;
|
||||||
|
extern pthread_key_t XX_httplib_sTlsKey;
|
||||||
|
338
src/httplib_process_options.c
Normal file
338
src/httplib_process_options.c
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
static bool check_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config );
|
||||||
|
static bool check_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, enum debug_level_t *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_patt( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
||||||
|
static bool check_str( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bool XX_httplib_process_options( struct httplib_context *ctx, const struct httplib_option_t *options );
|
||||||
|
*
|
||||||
|
* The function process_options() processes the user supplied options and adds
|
||||||
|
* them to the central option list of the context. If en error occurs, the
|
||||||
|
* function returns true, otherwise FALSE is returned. In case of an error all
|
||||||
|
* cleanup is already done before returning and an error message has been
|
||||||
|
* generated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool XX_httplib_process_options( struct httplib_context *ctx, const struct httplib_option_t *options ) {
|
||||||
|
|
||||||
|
if ( ctx == NULL ) return true;
|
||||||
|
|
||||||
|
while ( options != NULL && options->name != NULL ) {
|
||||||
|
|
||||||
|
if ( check_str( ctx, options, "access_control_allow_origin", & ctx->access_control_allow_origin ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "access_control_list", & ctx->access_control_list ) ) return true;
|
||||||
|
if ( check_file( ctx, options, "access_log_file", & ctx->access_log_file ) ) return true;
|
||||||
|
if ( check_bool( ctx, options, "allow_sendfile_call", & ctx->allow_sendfile_call ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "authentication_domain", & ctx->authentication_domain ) ) return true;
|
||||||
|
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_patt( ctx, options, "cgi_pattern", & ctx->cgi_pattern ) ) return true;
|
||||||
|
if ( check_dbg( ctx, options, "debug_level", & ctx->debug_level ) ) 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;
|
||||||
|
if ( check_dir( ctx, options, "error_pages", & ctx->error_pages ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "extra_mime_types", & ctx->extra_mime_types ) ) return true;
|
||||||
|
if ( check_file( ctx, options, "global_auth_file", & ctx->global_auth_file ) ) return true;
|
||||||
|
if ( check_patt( ctx, options, "hide_file_pattern", & ctx->hide_file_pattern ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "index_files", & ctx->index_files ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "listening_ports", & ctx->listening_ports ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "num_threads", & ctx->num_threads, 1, INT_MAX ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "protect_uri", & ctx->protect_uri ) ) return true;
|
||||||
|
if ( check_file( ctx, options, "put_delete_auth_file", & ctx->put_delete_auth_file ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "request_timeout", & ctx->request_timeout, 0, INT_MAX ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "run_as_user", & ctx->run_as_user ) ) return true;
|
||||||
|
if ( check_patt( ctx, options, "ssi_pattern", & ctx->ssi_pattern ) ) return true;
|
||||||
|
if ( check_file( ctx, options, "ssl_ca_file", & ctx->ssl_ca_file ) ) return true;
|
||||||
|
if ( check_dir( ctx, options, "ssl_ca_path", & ctx->ssl_ca_path ) ) return true;
|
||||||
|
if ( check_file( ctx, options, "ssl_certificate", & ctx->ssl_certificate ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "ssl_cipher_list", & ctx->ssl_cipher_list ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "ssl_protocol_version", & ctx->ssl_protocol_version, 0, 4 ) ) return true;
|
||||||
|
if ( check_bool( ctx, options, "ssl_short_trust", & ctx->ssl_short_trust ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "ssl_verify_depth", & ctx->ssl_verify_depth, 0, 9 ) ) return true;
|
||||||
|
if ( check_bool( ctx, options, "ssl_verify_paths", & ctx->ssl_verify_paths ) ) return true;
|
||||||
|
if ( check_bool( ctx, options, "ssl_verify_peer", & ctx->ssl_verify_peer ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "static_file_max_age", & ctx->static_file_max_age, 0, INT_MAX ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "throttle", & ctx->throttle ) ) return true;
|
||||||
|
if ( check_bool( ctx, options, "tcp_nodelay", & ctx->tcp_nodelay ) ) return true;
|
||||||
|
if ( check_str( ctx, options, "url_rewrite_patterns", & ctx->url_rewrite_patterns ) ) return true;
|
||||||
|
if ( check_dir( ctx, options, "websocket_root", & ctx->websocket_root ) ) return true;
|
||||||
|
if ( check_int( ctx, options, "websocket_timeout", & ctx->websocket_timeout, 0, INT_MAX ) ) return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Currently silently ignoring unrecognized options
|
||||||
|
*/
|
||||||
|
|
||||||
|
options++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} /* XX_httplib_process_options */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config );
|
||||||
|
*
|
||||||
|
* The function check_bool() checks if an option is equal to a boolean 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_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config ) {
|
||||||
|
|
||||||
|
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing boolean option" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
||||||
|
if ( ! XX_httplib_option_value_to_bool( option->value, config ) ) return false;
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Invalid boolean value \"%s\" for option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_bool */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( 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;
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory assigning value \"%s\" to option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_dir */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_patt( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
||||||
|
*
|
||||||
|
* The function check_patt() checks if an option is equal to a pattern 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_patt( 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 ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing pattern 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;
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory assigning value \"%s\" to option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_patt */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_file( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
||||||
|
*
|
||||||
|
* The function check_file() checks if an option is equal to a filename 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_file( 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 ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing file 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;
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory assigning value \"%s\" to option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_file */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_str( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
||||||
|
*
|
||||||
|
* The function check_str() checks if an option is equal to a string 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_str( 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 ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing string 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;
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Out of memory assigning value \"%s\" to option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_str */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_int( struct httplib_context *ctx, const struct httplib_opion_t *option, const char *name, int *config, int minval, int maxval );
|
||||||
|
*
|
||||||
|
* The function check_int() checks in an option is equal to an integer 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 and is
|
||||||
|
* valud, also false is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool check_int( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, int *config, int minval, int maxval ) {
|
||||||
|
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing integer option" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
||||||
|
|
||||||
|
if ( ! XX_httplib_option_value_to_int( option->value, & val ) ) {
|
||||||
|
|
||||||
|
if ( val < minval ) { XX_httplib_abort_start( ctx, "Integer \"%s\" too small for option \"%s\"", option->value, option->name ); return true; }
|
||||||
|
if ( val > maxval ) { XX_httplib_abort_start( ctx, "Integer \"%s\" too large for option \"%s\"", option->value, option->name ); return true; }
|
||||||
|
|
||||||
|
*config = val;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Invalid integer value \"%s\" for option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_int */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static bool check_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name );
|
||||||
|
*
|
||||||
|
* The function check_dbg() checks if an option is equal to a debug level
|
||||||
|
* 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 and is
|
||||||
|
* valid, also false is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool check_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, enum debug_level_t *config ) {
|
||||||
|
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Internal error parsing debug level option" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
||||||
|
|
||||||
|
if ( ! XX_httplib_option_value_to_int( option->value, &val ) ) {
|
||||||
|
|
||||||
|
switch ( val ) {
|
||||||
|
|
||||||
|
case DEBUG_LEVEL_NONE :
|
||||||
|
case DEBUG_LEVEL_CRASH :
|
||||||
|
case DEBUG_LEVEL_ERROR :
|
||||||
|
case DEBUG_LEVEL_WARNING :
|
||||||
|
case DEBUG_LEVEL_INFO :
|
||||||
|
*config = val;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XX_httplib_abort_start( ctx, "Invalid value \"%s\" for option \"%s\"", option->value, option->name );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /* check_dbg */
|
@@ -23,5 +23,4 @@
|
|||||||
|
|
||||||
|
|
||||||
extern pthread_mutex_t * XX_httplib_ssl_mutexes;
|
extern pthread_mutex_t * XX_httplib_ssl_mutexes;
|
||||||
extern pthread_key_t XX_httplib_sTlsKey;
|
|
||||||
extern int XX_httplib_thread_idx_max;
|
extern int XX_httplib_thread_idx_max;
|
||||||
|
@@ -150,6 +150,5 @@ void XX_httplib_uninitialize_ssl( struct httplib_context *ctx );
|
|||||||
extern int XX_httplib_cryptolib_users;
|
extern int XX_httplib_cryptolib_users;
|
||||||
extern struct ssl_func XX_httplib_crypto_sw[];
|
extern struct ssl_func XX_httplib_crypto_sw[];
|
||||||
extern struct ssl_func XX_httplib_ssl_sw[];
|
extern struct ssl_func XX_httplib_ssl_sw[];
|
||||||
extern int XX_httplib_sTlsInit;
|
|
||||||
|
|
||||||
#endif /* NO_SSL */
|
#endif /* NO_SSL */
|
||||||
|
@@ -31,16 +31,6 @@
|
|||||||
#include "httplib_string.h"
|
#include "httplib_string.h"
|
||||||
#include "httplib_utils.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_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, enum debug_level_t *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_patt( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
|
||||||
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 );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_t *options );
|
* struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_t *options );
|
||||||
*
|
*
|
||||||
@@ -56,19 +46,6 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
void (*exit_callback)(const struct httplib_context *ctx);
|
void (*exit_callback)(const struct httplib_context *ctx);
|
||||||
struct httplib_workerTLS tls;
|
struct httplib_workerTLS tls;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Yes, this is Windows and nothing works out of the box. We first have
|
|
||||||
* to initialize socket communications by telling Windows which socket
|
|
||||||
* version we want to use. 2.2 in this case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
WSADATA data;
|
|
||||||
WSAStartup( MAKEWORD(2, 2), &data );
|
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No memory for the ctx structure is the only error which we
|
* No memory for the ctx structure is the only error which we
|
||||||
* don't log through httplib_cry() for the simple reason that we do not
|
* don't log through httplib_cry() for the simple reason that we do not
|
||||||
@@ -78,7 +55,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
exit_callback = NULL;
|
exit_callback = NULL;
|
||||||
ctx = httplib_calloc( 1, sizeof(*ctx) );
|
ctx = httplib_calloc( 1, sizeof(struct httplib_context) );
|
||||||
|
|
||||||
if ( ctx == NULL ) return NULL;
|
if ( ctx == NULL ) return NULL;
|
||||||
|
|
||||||
@@ -145,17 +122,18 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
#endif
|
#endif
|
||||||
httplib_pthread_setspecific( XX_httplib_sTlsKey, & tls );
|
httplib_pthread_setspecific( XX_httplib_sTlsKey, & tls );
|
||||||
|
|
||||||
if ( httplib_pthread_mutex_init( & ctx->thread_mutex, &XX_httplib_pthread_mutex_attr ) ) return cleanup( ctx, "Cannot initialize thread mutex" );
|
if ( httplib_pthread_mutex_init( & ctx->thread_mutex, &XX_httplib_pthread_mutex_attr ) ) return XX_httplib_abort_start( ctx, "Cannot initialize thread mutex" );
|
||||||
#if !defined(ALTERNATIVE_QUEUE)
|
#if !defined(ALTERNATIVE_QUEUE)
|
||||||
if ( httplib_pthread_cond_init( & ctx->sq_empty, NULL ) ) return cleanup( ctx, "Cannot initialize empty queue condition" );
|
if ( httplib_pthread_cond_init( & ctx->sq_empty, NULL ) ) return XX_httplib_abort_start( ctx, "Cannot initialize empty queue condition" );
|
||||||
if ( httplib_pthread_cond_init( & ctx->sq_full, NULL ) ) return cleanup( ctx, "Cannot initialize full queue condition" );
|
if ( httplib_pthread_cond_init( & ctx->sq_full, NULL ) ) return XX_httplib_abort_start( ctx, "Cannot initialize full queue condition" );
|
||||||
#endif
|
#endif
|
||||||
if ( httplib_pthread_mutex_init( & ctx->nonce_mutex, & XX_httplib_pthread_mutex_attr ) ) return cleanup( ctx, "Cannot initialize nonce mutex" );
|
if ( httplib_pthread_mutex_init( & ctx->nonce_mutex, & XX_httplib_pthread_mutex_attr ) ) return XX_httplib_abort_start( ctx, "Cannot initialize nonce mutex" );
|
||||||
|
|
||||||
ctx->user_data = user_data;
|
ctx->user_data = user_data;
|
||||||
ctx->handlers = NULL;
|
ctx->handlers = NULL;
|
||||||
|
|
||||||
if ( process_options( ctx, options ) ) return NULL;
|
if ( XX_httplib_init_options( ctx ) ) return NULL;
|
||||||
|
if ( XX_httplib_process_options( ctx, options ) ) return NULL;
|
||||||
|
|
||||||
XX_httplib_get_system_name( & ctx->systemName );
|
XX_httplib_get_system_name( & ctx->systemName );
|
||||||
|
|
||||||
@@ -164,13 +142,13 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
* be initialized before listening ports. UID must be set last.
|
* be initialized before listening ports. UID must be set last.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( ! XX_httplib_set_gpass_option( ctx ) ) return cleanup( ctx, "Error setting gpass option" );
|
if ( ! XX_httplib_set_gpass_option( ctx ) ) return XX_httplib_abort_start( ctx, "Error setting gpass option" );
|
||||||
#if !defined(NO_SSL)
|
#if !defined(NO_SSL)
|
||||||
if ( ! XX_httplib_set_ssl_option( ctx ) ) return cleanup( ctx, "Error setting SSL option" );
|
if ( ! XX_httplib_set_ssl_option( ctx ) ) return XX_httplib_abort_start( ctx, "Error setting SSL option" );
|
||||||
#endif
|
#endif
|
||||||
if ( ! XX_httplib_set_ports_option( ctx ) ) return cleanup( ctx, "Error setting ports option" );
|
if ( ! XX_httplib_set_ports_option( ctx ) ) return XX_httplib_abort_start( ctx, "Error setting ports option" );
|
||||||
if ( ! XX_httplib_set_uid_option( ctx ) ) return cleanup( ctx, "Error setting UID option" );
|
if ( ! XX_httplib_set_uid_option( ctx ) ) return XX_httplib_abort_start( ctx, "Error setting UID option" );
|
||||||
if ( ! XX_httplib_set_acl_option( ctx ) ) return cleanup( ctx, "Error setting ACL option" );
|
if ( ! XX_httplib_set_acl_option( ctx ) ) return XX_httplib_abort_start( ctx, "Error setting ACL option" );
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
|
|
||||||
@@ -183,33 +161,33 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
|
|
||||||
#endif /* !_WIN32 */
|
#endif /* !_WIN32 */
|
||||||
|
|
||||||
if ( ctx->num_threads < 1 ) return cleanup( ctx, "No worker thread number specified" );
|
if ( ctx->num_threads < 1 ) return XX_httplib_abort_start( ctx, "No worker thread number specified" );
|
||||||
|
|
||||||
if ( ctx->num_threads > MAX_WORKER_THREADS ) return cleanup( ctx, "Too many worker threads" );
|
if ( ctx->num_threads > MAX_WORKER_THREADS ) return XX_httplib_abort_start( ctx, "Too many worker threads" );
|
||||||
|
|
||||||
if ( ctx->num_threads > 0 ) {
|
if ( ctx->num_threads > 0 ) {
|
||||||
|
|
||||||
ctx->workerthreadids = httplib_calloc( ctx->num_threads, sizeof(pthread_t) );
|
ctx->workerthreadids = httplib_calloc( ctx->num_threads, sizeof(pthread_t) );
|
||||||
if ( ctx->workerthreadids == NULL ) return cleanup( ctx, "Not enough memory for worker thread ID array" );
|
if ( ctx->workerthreadids == NULL ) return XX_httplib_abort_start( ctx, "Not enough memory for worker thread ID array" );
|
||||||
|
|
||||||
#if defined(ALTERNATIVE_QUEUE)
|
#if defined(ALTERNATIVE_QUEUE)
|
||||||
|
|
||||||
ctx->client_wait_events = httplib_calloc( sizeof(ctx->client_wait_events[0]), ctx->num_threads );
|
ctx->client_wait_events = httplib_calloc( sizeof(ctx->client_wait_events[0]), ctx->num_threads );
|
||||||
if ( ctx->client_wait_events == NULL ) return cleanup( ctx, "Not enough memory for worker event array" );
|
if ( ctx->client_wait_events == NULL ) return XX_httplib_abort_start( ctx, "Not enough memory for worker event array" );
|
||||||
|
|
||||||
ctx->client_socks = httplib_calloc( sizeof(ctx->client_socks[0]), ctx->num_threads );
|
ctx->client_socks = httplib_calloc( sizeof(ctx->client_socks[0]), ctx->num_threads );
|
||||||
if ( ctx->client_socks == NULL ) return cleanup( ctx, "Not enough memory for worker socket array" );
|
if ( ctx->client_socks == NULL ) return XX_httplib_abort_start( ctx, "Not enough memory for worker socket array" );
|
||||||
|
|
||||||
for (i=0; i<ctx->num_threads; i++) {
|
for (i=0; i<ctx->num_threads; i++) {
|
||||||
|
|
||||||
ctx->client_wait_events[i] = event_create();
|
ctx->client_wait_events[i] = event_create();
|
||||||
if ( ctx->client_wait_events[i] == 0 ) return cleanup( ctx, "Error creating worker event %u", i );
|
if ( ctx->client_wait_events[i] == 0 ) return XX_httplib_abort_start( ctx, "Error creating worker event %u", i );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_TIMERS)
|
#if defined(USE_TIMERS)
|
||||||
if ( timers_init( ctx ) != 0 ) return cleanup( ctx, "Error creating timers" );
|
if ( timers_init( ctx ) != 0 ) return XX_httplib_abort_start( ctx, "Error creating timers" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -255,7 +233,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
|
|
||||||
if ( i > 0 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, NULL, "Cannot start worker thread %i: error %ld", i + 1, (long)ERRNO );
|
if ( i > 0 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, NULL, "Cannot start worker thread %i: error %ld", i + 1, (long)ERRNO );
|
||||||
|
|
||||||
else return cleanup( ctx, "Cannot create worker threads: error %ld", (long)ERRNO );
|
else return XX_httplib_abort_start( ctx, "Cannot create worker threads: error %ld", (long)ERRNO );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -266,439 +244,3 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
|||||||
return ctx;
|
return ctx;
|
||||||
|
|
||||||
} /* httplib_start */
|
} /* httplib_start */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool process_options( struct httplib_context *ctx, const struct httplib_option_t *options );
|
|
||||||
*
|
|
||||||
* The function process_options() processes the user supplied options and adds
|
|
||||||
* them to the central option list of the context. If en error occurs, the
|
|
||||||
* function returns true, otherwise FALSE is returned. In case of an error all
|
|
||||||
* cleanup is already done before returning and an error message has been
|
|
||||||
* generated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool process_options( struct httplib_context *ctx, const struct httplib_option_t *options ) {
|
|
||||||
|
|
||||||
if ( ctx == NULL ) return false;
|
|
||||||
|
|
||||||
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->cgi_pattern = NULL;
|
|
||||||
ctx->debug_level = DEBUG_LEVEL_WARNING;
|
|
||||||
ctx->decode_url = true;
|
|
||||||
ctx->document_root = NULL;
|
|
||||||
ctx->enable_directory_listing = true;
|
|
||||||
ctx->enable_keep_alive = false;
|
|
||||||
ctx->error_log_file = NULL;
|
|
||||||
ctx->error_pages = NULL;
|
|
||||||
ctx->extra_mime_types = NULL;
|
|
||||||
ctx->global_auth_file = NULL;
|
|
||||||
ctx->hide_file_pattern = 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->ssi_pattern = NULL;
|
|
||||||
ctx->ssl_ca_file = NULL;
|
|
||||||
ctx->ssl_ca_path = 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_root = NULL;
|
|
||||||
ctx->websocket_timeout = 30000;
|
|
||||||
|
|
||||||
if ( (ctx->access_control_allow_origin = httplib_strdup( "*" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"access_control_allow_origin\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ctx->authentication_domain = httplib_strdup( "example.com" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"authentication_domain\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ctx->cgi_pattern = httplib_strdup( "**.cgi$|**.pl$|**.php$" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"cgi_pattern\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ctx->index_files = httplib_strdup( "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"index_files\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ctx->listening_ports = httplib_strdup( "8080" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"listening_ports\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ctx->ssi_pattern = httplib_strdup( "**.shtml$|**.shtm$" )) == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Out of memory creating context allocating \"ssi_pattern\"" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( options != NULL && options->name != NULL ) {
|
|
||||||
|
|
||||||
if ( check_str( ctx, options, "access_control_allow_origin", & ctx->access_control_allow_origin ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "access_control_list", & ctx->access_control_list ) ) return true;
|
|
||||||
if ( check_file( ctx, options, "access_log_file", & ctx->access_log_file ) ) return true;
|
|
||||||
if ( check_bool( ctx, options, "allow_sendfile_call", & ctx->allow_sendfile_call ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "authentication_domain", & ctx->authentication_domain ) ) return true;
|
|
||||||
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_patt( ctx, options, "cgi_pattern", & ctx->cgi_pattern ) ) return true;
|
|
||||||
if ( check_dbg( ctx, options, "debug_level", & ctx->debug_level ) ) 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;
|
|
||||||
if ( check_dir( ctx, options, "error_pages", & ctx->error_pages ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "extra_mime_types", & ctx->extra_mime_types ) ) return true;
|
|
||||||
if ( check_file( ctx, options, "global_auth_file", & ctx->global_auth_file ) ) return true;
|
|
||||||
if ( check_patt( ctx, options, "hide_file_pattern", & ctx->hide_file_pattern ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "index_files", & ctx->index_files ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "listening_ports", & ctx->listening_ports ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "num_threads", & ctx->num_threads, 1, INT_MAX ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "protect_uri", & ctx->protect_uri ) ) return true;
|
|
||||||
if ( check_file( ctx, options, "put_delete_auth_file", & ctx->put_delete_auth_file ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "request_timeout", & ctx->request_timeout, 0, INT_MAX ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "run_as_user", & ctx->run_as_user ) ) return true;
|
|
||||||
if ( check_patt( ctx, options, "ssi_pattern", & ctx->ssi_pattern ) ) return true;
|
|
||||||
if ( check_file( ctx, options, "ssl_ca_file", & ctx->ssl_ca_file ) ) return true;
|
|
||||||
if ( check_dir( ctx, options, "ssl_ca_path", & ctx->ssl_ca_path ) ) return true;
|
|
||||||
if ( check_file( ctx, options, "ssl_certificate", & ctx->ssl_certificate ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "ssl_cipher_list", & ctx->ssl_cipher_list ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "ssl_protocol_version", & ctx->ssl_protocol_version, 0, 4 ) ) return true;
|
|
||||||
if ( check_bool( ctx, options, "ssl_short_trust", & ctx->ssl_short_trust ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "ssl_verify_depth", & ctx->ssl_verify_depth, 0, 9 ) ) return true;
|
|
||||||
if ( check_bool( ctx, options, "ssl_verify_paths", & ctx->ssl_verify_paths ) ) return true;
|
|
||||||
if ( check_bool( ctx, options, "ssl_verify_peer", & ctx->ssl_verify_peer ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "static_file_max_age", & ctx->static_file_max_age, 0, INT_MAX ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "throttle", & ctx->throttle ) ) return true;
|
|
||||||
if ( check_bool( ctx, options, "tcp_nodelay", & ctx->tcp_nodelay ) ) return true;
|
|
||||||
if ( check_str( ctx, options, "url_rewrite_patterns", & ctx->url_rewrite_patterns ) ) return true;
|
|
||||||
if ( check_dir( ctx, options, "websocket_root", & ctx->websocket_root ) ) return true;
|
|
||||||
if ( check_int( ctx, options, "websocket_timeout", & ctx->websocket_timeout, 0, INT_MAX ) ) return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Currently silently ignoring unrecognized options
|
|
||||||
*/
|
|
||||||
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} /* process_options */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool check_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config );
|
|
||||||
*
|
|
||||||
* The function check_bool() checks if an option is equal to a boolean 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_bool( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, bool *config ) {
|
|
||||||
|
|
||||||
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Internal error parsing boolean option" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
|
||||||
if ( ! XX_httplib_option_value_to_bool( option->value, config ) ) return false;
|
|
||||||
|
|
||||||
cleanup( ctx, "Invalid boolean value \"%s\" for option \"%s\"", option->value, option->name );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} /* check_bool */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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_patt( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
|
||||||
*
|
|
||||||
* The function check_patt() checks if an option is equal to a pattern 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_patt( 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 pattern 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_patt */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool check_file( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
|
||||||
*
|
|
||||||
* The function check_file() checks if an option is equal to a filename 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_file( 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 file 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_file */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool check_str( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, char **config );
|
|
||||||
*
|
|
||||||
* The function check_str() checks if an option is equal to a string 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_str( 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 string 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_str */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool check_int( struct httplib_context *ctx, const struct httplib_opion_t *option, const char *name, int *config, int minval, int maxval );
|
|
||||||
*
|
|
||||||
* The function check_int() checks in an option is equal to an integer 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 and is
|
|
||||||
* valud, also false is returned.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool check_int( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, int *config, int minval, int maxval ) {
|
|
||||||
|
|
||||||
int val;
|
|
||||||
|
|
||||||
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Internal error parsing integer option" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
|
||||||
|
|
||||||
if ( ! XX_httplib_option_value_to_int( option->value, & val ) ) {
|
|
||||||
|
|
||||||
if ( val < minval ) { cleanup( ctx, "Integer \"%s\" too small for option \"%s\"", option->value, option->name ); return true; }
|
|
||||||
if ( val > maxval ) { cleanup( ctx, "Integer \"%s\" too large for option \"%s\"", option->value, option->name ); return true; }
|
|
||||||
|
|
||||||
*config = val;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup( ctx, "Invalid integer value \"%s\" for option \"%s\"", option->value, option->name );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} /* check_int */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static bool check_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name );
|
|
||||||
*
|
|
||||||
* The function check_dbg() checks if an option is equal to a debug level
|
|
||||||
* 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 and is
|
|
||||||
* valid, also false is returned.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool check_dbg( struct httplib_context *ctx, const struct httplib_option_t *option, const char *name, enum debug_level_t *config ) {
|
|
||||||
|
|
||||||
int val;
|
|
||||||
|
|
||||||
if ( ctx == NULL || option == NULL || option->name == NULL || name == NULL || config == NULL ) {
|
|
||||||
|
|
||||||
cleanup( ctx, "Internal error parsing debug level option" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( httplib_strcasecmp( option->name, name ) ) return false;
|
|
||||||
|
|
||||||
if ( ! XX_httplib_option_value_to_int( option->value, &val ) ) {
|
|
||||||
|
|
||||||
switch ( val ) {
|
|
||||||
|
|
||||||
case DEBUG_LEVEL_NONE :
|
|
||||||
case DEBUG_LEVEL_CRASH :
|
|
||||||
case DEBUG_LEVEL_ERROR :
|
|
||||||
case DEBUG_LEVEL_WARNING :
|
|
||||||
case DEBUG_LEVEL_INFO :
|
|
||||||
*config = val;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup( ctx, "Invalid value \"%s\" for option \"%s\"", option->value, option->name );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} /* check_dbg */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static struct httplib_context *cleanup( struct httplib_context *ctx, const char *fmt, ... );
|
|
||||||
*
|
|
||||||
* The function cleanup() is called to do some cleanup work when an error
|
|
||||||
* occured initializing a context. The function returns NULL which is then
|
|
||||||
* further returned to the calling party.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct httplib_context *cleanup( struct httplib_context *ctx, const char *fmt, ... ) {
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
char buf[MG_BUF_LEN];
|
|
||||||
|
|
||||||
if ( ctx == NULL ) return NULL;
|
|
||||||
|
|
||||||
if ( fmt != NULL ) {
|
|
||||||
|
|
||||||
va_start( ap, fmt );
|
|
||||||
vsnprintf_impl( buf, sizeof(buf), fmt, ap );
|
|
||||||
va_end( ap );
|
|
||||||
buf[sizeof(buf)-1] = 0;
|
|
||||||
|
|
||||||
httplib_cry( DEBUG_LEVEL_CRASH, ctx, NULL, "%s", buf );
|
|
||||||
}
|
|
||||||
|
|
||||||
XX_httplib_free_context( ctx );
|
|
||||||
|
|
||||||
httplib_pthread_setspecific( XX_httplib_sTlsKey, NULL );
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
} /* cleanup */
|
|
||||||
|
@@ -69,8 +69,4 @@ void httplib_stop( struct httplib_context *ctx ) {
|
|||||||
httplib_pthread_join( mt, NULL );
|
httplib_pthread_join( mt, NULL );
|
||||||
XX_httplib_free_context( ctx );
|
XX_httplib_free_context( ctx );
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
WSACleanup();
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
} /* httplib_stop */
|
} /* httplib_stop */
|
||||||
|
49
src/httplib_system_exit.c
Normal file
49
src/httplib_system_exit.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lammert Bies
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "httplib_main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int httplib_system_exit( void );
|
||||||
|
*
|
||||||
|
* The function httplib_system_exit() is called after all processing with other
|
||||||
|
* LibHTTP function is completed to deinitialize socket communications. The
|
||||||
|
* function returns 0 when successful, and -1 if an error occured.
|
||||||
|
*
|
||||||
|
* Please note that this function terminates socket communications for all
|
||||||
|
* threads and it should therefore be called only when all running threads have
|
||||||
|
* terminated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int httplib_system_exit( void ) {
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
return ( WSACleanup() ) ? -1 : 0;
|
||||||
|
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
} /* httplib_system_exit */
|
@@ -1,7 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016 Lammert Bies
|
* Copyright (c) 2016 Lammert Bies
|
||||||
* Copyright (c) 2013-2016 the Civetweb developers
|
|
||||||
* Copyright (c) 2004-2013 Sergey Lyubka
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -20,20 +18,29 @@
|
|||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
|
||||||
* ============
|
|
||||||
* Release: 2.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "httplib_main.h"
|
#include "httplib_main.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if the XX_httplib_config_options and the corresponding enum have
|
|
||||||
* compatible sizes
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: LJB: Move to test functions
|
* int httplib_system_init( void );
|
||||||
|
*
|
||||||
|
* The function httplib_system_init() is called before any other LibHTTP
|
||||||
|
* functions to do some basic initialisation. The function returns 0 when
|
||||||
|
* successful and -1 if an error occured.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// httplib_static_assert((sizeof(XX_httplib_config_options) / sizeof(XX_httplib_config_options[0])) == (NUM_OPTIONS + 1), "XX_httplib_config_options and enum not sync");
|
int httplib_system_init( void ) {
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
WSADATA data;
|
||||||
|
return ( WSAStartup( MAKEWORD(2,2), &data ) ) ? -1 : 0;
|
||||||
|
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
} /* httplib_system_init */
|
Reference in New Issue
Block a user