diff --git a/Makefile b/Makefile index 2d29019a..8cef3ebe 100644 --- a/Makefile +++ b/Makefile @@ -228,7 +228,6 @@ OBJLIST = \ ${OBJDIR}httplib_free_config_options${OBJEXT} \ ${OBJDIR}httplib_free_context${OBJEXT} \ ${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} \ - ${OBJDIR}httplib_get_context${OBJEXT} \ ${OBJDIR}httplib_get_cookie${OBJEXT} \ ${OBJDIR}httplib_get_debug_level${OBJEXT} \ ${OBJDIR}httplib_get_first_ssl_listener_index${OBJEXT} \ @@ -635,10 +634,6 @@ ${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} : ${SRCDIR}httplib_get_builti ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h -${OBJDIR}httplib_get_context${OBJEXT} : ${SRCDIR}httplib_get_context.c \ - ${SRCDIR}httplib_main.h \ - ${INCDIR}libhttp.h - ${OBJDIR}httplib_get_cookie${OBJEXT} : ${SRCDIR}httplib_get_cookie.c \ ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ diff --git a/include/libhttp.h b/include/libhttp.h index 15727e27..52ce2a50 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -431,10 +431,6 @@ LIBHTTP_API void httplib_set_auth_handler(struct httplib_context *ctx, const cha set, zero-length string is returned. */ -/* Get context from connection. */ -LIBHTTP_API struct httplib_context * -httplib_get_context(const struct httplib_connection *conn); - /* Get user data passed to httplib_start from context. */ LIBHTTP_API void *httplib_get_user_data(const struct httplib_context *ctx); @@ -480,7 +476,6 @@ LIBHTTP_API const struct httplib_request_info *httplib_get_request_info(const st 0 when the connection has been closed -1 on error >0 number of bytes written on success */ -LIBHTTP_API int httplib_write(struct httplib_connection *, const void *buf, size_t len); /* Send data to a websocket client wrapped in a websocket frame. Uses @@ -494,7 +489,6 @@ LIBHTTP_API int httplib_write(struct httplib_connection *, const void *buf, size 0 when the connection has been closed -1 on error >0 number of bytes written on success */ -LIBHTTP_API int httplib_websocket_write(struct httplib_connection *conn, int opcode, const char *data, size_t data_len); /* Send data to a websocket server wrapped in a masked websocket frame. Uses @@ -508,7 +502,6 @@ LIBHTTP_API int httplib_websocket_write(struct httplib_connection *conn, int opc 0 when the connection has been closed -1 on error >0 number of bytes written on success */ -LIBHTTP_API int httplib_websocket_client_write(struct httplib_connection *conn, int opcode, const char *data, size_t data_len); /* Blocks until unique access is obtained to this connection. Intended for use @@ -559,12 +552,10 @@ enum { /* Send data to the client using printf() semantics. Works exactly like httplib_write(), but allows to do message formatting. */ -LIBHTTP_API int httplib_printf(struct httplib_connection *, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); /* Store body data into a file. */ -LIBHTTP_API int64_t httplib_store_body(struct httplib_connection *conn, const char *path); /* Read entire request body and store it in a file "path". Return: < 0 Error @@ -577,7 +568,6 @@ LIBHTTP_API int64_t httplib_store_body(struct httplib_connection *conn, const ch 0 connection has been closed by peer. No more data could be read. < 0 read error. No more data could be read from the connection. > 0 number of bytes read into the buffer. */ -LIBHTTP_API int httplib_read(struct httplib_connection *, void *buf, size_t len); /* Get the value of particular HTTP header. @@ -670,7 +660,6 @@ LIBHTTP_API int httplib_get_cookie(const char *cookie, const char *var_name, cha /* Close the connection opened by httplib_download(). */ -LIBHTTP_API void httplib_close_connection(struct httplib_connection *conn); /* This structure contains callback functions for handling form fields. @@ -755,7 +744,6 @@ enum { * error. In this case a number < 0 is returned as well. * In any case, it is the duty of the caller to remove files once they are * no longer required. */ -LIBHTTP_API int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_form_data_handler *fdh); #ifndef LIBHTTP_THREAD @@ -783,7 +771,6 @@ LIBHTTP_API int httplib_start_thread(httplib_thread_func_t f, void *p); /* Get text representation of HTTP status code. */ -LIBHTTP_API const char *httplib_get_response_code_text(struct httplib_connection *conn, int response_code); @@ -883,7 +870,6 @@ enum { TIMEOUT_INFINITE = -1 }; On success, >= 0 On error/timeout, < 0 */ -LIBHTTP_API int httplib_get_response( struct httplib_connection *conn, int timeout ); @@ -903,6 +889,7 @@ LIBHTTP_API int httplib_atomic_dec( volatile int *addr ); 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 unsigned httplib_check_feature( unsigned feature ); +LIBHTTP_API void httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn ); 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 ); LIBHTTP_API struct httplib_connection * httplib_connect_client_secure( struct httplib_context *ctx, const struct httplib_client_options *client_options ); @@ -916,13 +903,17 @@ 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 const char * httplib_get_option( const struct httplib_context *ctx, const char *name, char *buffer, size_t buflen ); LIBHTTP_API uint64_t httplib_get_random( void ); +LIBHTTP_API int httplib_get_response( const struct httplib_context *ctx, struct httplib_connection *conn, int timeout ); +LIBHTTP_API const char * httplib_get_response_code_text( const struct httplib_context *ctx, struct httplib_connection *conn, int response_code ); LIBHTTP_API void * httplib_get_user_connection_data( const struct httplib_connection *conn ); LIBHTTP_API struct tm * httplib_gmtime_r( const time_t *clock, struct tm *result ); +LIBHTTP_API int httplib_handle_form_request( const struct httplib_context *ctx, struct httplib_connection *conn, struct httplib_form_data_handler *fdh ); LIBHTTP_API int httplib_kill( pid_t pid, int sig_num ); LIBHTTP_API struct tm * httplib_localtime_r( const time_t *clock, struct tm *result ); LIBHTTP_API int httplib_mkdir( const char *path, int mode ); LIBHTTP_API DIR * httplib_opendir( const char *name ); LIBHTTP_API int httplib_poll( struct pollfd *pfd, unsigned int nfds, int timeout ); +LIBHTTP_API int httplib_printf( const struct httplib_context *ctx, struct httplib_connection *, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4); LIBHTTP_API int httplib_pthread_cond_broadcast( pthread_cond_t *cv ); LIBHTTP_API int httplib_pthread_cond_destroy( pthread_cond_t *cv ); LIBHTTP_API int httplib_pthread_cond_init( pthread_cond_t *cv, const pthread_condattr_t *attr ); @@ -940,14 +931,16 @@ LIBHTTP_API int httplib_pthread_mutex_trylock( pthread_mutex_t *mutex ); LIBHTTP_API int httplib_pthread_mutex_unlock( pthread_mutex_t *mutex ); LIBHTTP_API pthread_t httplib_pthread_self( void ); LIBHTTP_API int httplib_pthread_setspecific( pthread_key_t key, void *value ); +LIBHTTP_API int httplib_read( const struct httplib_context *ctx, struct httplib_connection *, void *buf, size_t len ); LIBHTTP_API struct dirent * httplib_readdir( DIR *dir ); LIBHTTP_API int httplib_remove( const char *path ); -LIBHTTP_API void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); +LIBHTTP_API void httplib_send_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); LIBHTTP_API void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func ); LIBHTTP_API enum debug_level_t httplib_set_debug_level( struct httplib_context *ctx, enum debug_level_t new_level ); LIBHTTP_API void httplib_set_user_connection_data( struct httplib_connection *conn, void *data ); LIBHTTP_API struct httplib_context * httplib_start(const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_option_t *options ); LIBHTTP_API void httplib_stop( struct httplib_context *ctx ); +LIBHTTP_API int64_t httplib_store_body( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); LIBHTTP_API int httplib_strcasecmp( const char *s1, const char *s2 ); LIBHTTP_API const char * httplib_strcasestr( const char *big_str, const char *small_str ); LIBHTTP_API char * httplib_strdup( const char *str ); @@ -957,6 +950,9 @@ 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 int httplib_websocket_client_write( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t data_len ); +LIBHTTP_API int httplib_websocket_write( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t data_len ); +LIBHTTP_API int httplib_write( const struct httplib_context *ctx, struct httplib_connection * conn, const void *buf, size_t len ); #ifdef __cplusplus } diff --git a/src/httplib_addenv.c b/src/httplib_addenv.c index 1333ac27..087d65c0 100644 --- a/src/httplib_addenv.c +++ b/src/httplib_addenv.c @@ -30,7 +30,7 @@ #include "httplib_utils.h" /* - * void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ); + * void XX_httplib_addenv( const struct httplib_context *ctx, struct cgi_environment *env, const char *fmt, ... ); * * The function XX_httplib_addenv() adds one item to the environment before * a CGI script is called. The environment variable has the form @@ -44,7 +44,7 @@ #if !defined(NO_CGI) -void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) { +void XX_httplib_addenv( const struct httplib_context *ctx, struct cgi_environment *env, const char *fmt, ... ) { size_t n; size_t space; @@ -52,7 +52,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) { char *added; va_list ap; - if ( env == NULL || env->conn == NULL || env->conn->ctx == NULL ) return; + if ( ctx == NULL || env == NULL || env->conn == NULL ) return; /* * Calculate how much space is left in the buffer @@ -79,7 +79,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) { * Out of memory */ - httplib_cry( DEBUG_LEVEL_ERROR, env->conn->ctx, env->conn, "%s: Cannot allocate memory for CGI variable [%s]", __func__, fmt ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, env->conn, "%s: Cannot allocate memory for CGI variable [%s]", __func__, fmt ); return; } @@ -99,7 +99,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) { */ va_start( ap, fmt ); - XX_httplib_vsnprintf( env->conn, &truncated, added, (size_t)space, fmt, ap ); + XX_httplib_vsnprintf( ctx, env->conn, &truncated, added, (size_t)space, fmt, ap ); va_end( ap ); /* @@ -133,7 +133,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) { if ( space < 2 ) { - httplib_cry( DEBUG_LEVEL_ERROR, env->conn->ctx, env->conn, "%s: Cannot register CGI variable [%s]", __func__, fmt ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, env->conn, "%s: Cannot register CGI variable [%s]", __func__, fmt ); return; } diff --git a/src/httplib_authorize.c b/src/httplib_authorize.c index af6b7240..61b9b1f8 100644 --- a/src/httplib_authorize.c +++ b/src/httplib_authorize.c @@ -28,25 +28,25 @@ #include "httplib_main.h" /* - * bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep ); + * bool XX_httplib_authorize( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ); * * The function XX_httplib_authorize() authorizes agains the open passwords * file. It returns 1 if authorized. */ -bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep ) { +bool XX_httplib_authorize( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ) { struct read_auth_file_struct workdata; char buf[MG_BUF_LEN]; - if ( conn == NULL || conn->ctx == NULL ) return false; + if ( ctx == NULL || conn == NULL ) return false; memset( & workdata, 0, sizeof(workdata) ); workdata.conn = conn; - if ( ! XX_httplib_parse_auth_header( conn, buf, sizeof(buf), &workdata.ah ) ) return false; - workdata.domain = conn->ctx->authentication_domain; + if ( ! XX_httplib_parse_auth_header( ctx, conn, buf, sizeof(buf), &workdata.ah ) ) return false; + workdata.domain = ctx->authentication_domain; - return XX_httplib_read_auth_file( filep, &workdata ); + return XX_httplib_read_auth_file( ctx, filep, &workdata ); } /* XX_httplib_authorize */ diff --git a/src/httplib_check_authorization.c b/src/httplib_check_authorization.c index f0e276b8..6e8869df 100644 --- a/src/httplib_check_authorization.c +++ b/src/httplib_check_authorization.c @@ -29,7 +29,7 @@ #include "httplib_string.h" /* Return 1 if request is authorised, 0 otherwise. */ -bool XX_httplib_check_authorization( struct httplib_connection *conn, const char *path ) { +bool XX_httplib_check_authorization( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { char fname[PATH_MAX]; char error_string[ERROR_STRING_LEN]; @@ -40,31 +40,31 @@ bool XX_httplib_check_authorization( struct httplib_connection *conn, const char bool authorized; bool truncated; - if ( conn == NULL || conn->ctx == NULL ) return false; + if ( ctx == NULL || conn == NULL ) return false; authorized = true; - list = conn->ctx->protect_uri; + list = ctx->protect_uri; while ( (list = XX_httplib_next_option( list, &uri_vec, &filename_vec )) != NULL ) { if ( ! memcmp( conn->request_info.local_uri, uri_vec.ptr, uri_vec.len ) ) { - XX_httplib_snprintf( conn, &truncated, fname, sizeof(fname), "%.*s", (int)filename_vec.len, filename_vec.ptr ); + XX_httplib_snprintf( ctx, conn, &truncated, fname, sizeof(fname), "%.*s", (int)filename_vec.len, filename_vec.ptr ); - if ( truncated || ! XX_httplib_fopen( conn, fname, "r", &file ) ) { + if ( truncated || ! XX_httplib_fopen( ctx, conn, fname, "r", &file ) ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: cannot open %s: %s", __func__, fname, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: cannot open %s: %s", __func__, fname, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } break; } } - if ( ! XX_httplib_is_file_opened( & file ) ) XX_httplib_open_auth_file( conn, path, & file ); + if ( ! XX_httplib_is_file_opened( & file ) ) XX_httplib_open_auth_file( ctx, conn, path, & file ); if ( XX_httplib_is_file_opened( & file ) ) { - authorized = XX_httplib_authorize( conn, & file ); + authorized = XX_httplib_authorize( ctx, conn, & file ); XX_httplib_fclose( & file ); } diff --git a/src/httplib_close_connection.c b/src/httplib_close_connection.c index 55f627a7..9e3bc12b 100644 --- a/src/httplib_close_connection.c +++ b/src/httplib_close_connection.c @@ -30,21 +30,21 @@ #include "httplib_ssl.h" /* - * void XX_httplib_close_connection( struct httplib_connection *conn ); + * void XX_httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_close_connection() is the internal function which * does the heavy lifting to close a connection. */ -void XX_httplib_close_connection( struct httplib_connection *conn ) { +void XX_httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn ) { - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; /* * call the connection_close callback if assigned */ - if ( conn->ctx->callbacks.connection_close != NULL && conn->ctx->ctx_type == CTX_TYPE_SERVER ) conn->ctx->callbacks.connection_close( conn ); + if ( ctx->callbacks.connection_close != NULL && ctx->ctx_type == CTX_TYPE_SERVER ) ctx->callbacks.connection_close( conn ); httplib_lock_connection( conn ); @@ -71,7 +71,7 @@ void XX_httplib_close_connection( struct httplib_connection *conn ) { #endif if ( conn->client.sock != INVALID_SOCKET ) { - XX_httplib_close_socket_gracefully( conn ); + XX_httplib_close_socket_gracefully( ctx, conn ); conn->client.sock = INVALID_SOCKET; } @@ -82,24 +82,24 @@ void XX_httplib_close_connection( struct httplib_connection *conn ) { /* - * void httplib_close_connection( struct httplib_connection *conn ); + * void httplib_close_connection( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function httplib_close_connection() closes the connection passed as a * parameter to this function. The function does not return a success or * failure value. */ -void httplib_close_connection( struct httplib_connection *conn ) { +void httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn ) { struct httplib_context *client_ctx; int i; - if ( conn == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; - if ( conn->ctx->ctx_type == CTX_TYPE_CLIENT ) { + if ( ctx->ctx_type == CTX_TYPE_CLIENT ) { - client_ctx = conn->ctx; - conn->ctx->status = CTX_STATUS_STOPPING; + client_ctx = ctx; + ctx->status = CTX_STATUS_STOPPING; } else client_ctx = NULL; @@ -111,7 +111,7 @@ void httplib_close_connection( struct httplib_connection *conn ) { conn->client_ssl_ctx = NULL; } #endif - XX_httplib_close_connection( conn ); + XX_httplib_close_connection( ctx, conn ); if ( client_ctx != NULL ) { diff --git a/src/httplib_close_socket_gracefully.c b/src/httplib_close_socket_gracefully.c index 0a23f581..359a5f6c 100644 --- a/src/httplib_close_socket_gracefully.c +++ b/src/httplib_close_socket_gracefully.c @@ -28,13 +28,13 @@ #include "httplib_main.h" /* - * void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ); + * void XX_httplib_close_socket_gracefully( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_close_socket_gracefully() closes a socket in a * graceful way. */ -void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) { +void XX_httplib_close_socket_gracefully( const struct httplib_context *ctx, struct httplib_connection *conn ) { #if defined(_WIN32) char buf[MG_BUF_LEN]; @@ -45,7 +45,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) { int error_code; socklen_t opt_len; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; error_code = 0; opt_len = sizeof(error_code); @@ -67,7 +67,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) { else { if ( setsockopt( conn->client.sock, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) ) != 0 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: setsockopt(SOL_SOCKET SO_LINGER) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: setsockopt(SOL_SOCKET SO_LINGER) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index 0e21b4c6..fe5b2fea 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -109,7 +109,6 @@ static struct httplib_connection *httplib_connect_client_impl( struct httplib_co conn->buf_size = MAX_REQUEST_SIZE; conn->buf = (char *)(conn + 1); - conn->ctx = ctx; conn->client.sock = sock; conn->client.lsa = sa; @@ -152,7 +151,7 @@ static struct httplib_connection *httplib_connect_client_impl( struct httplib_co else SSL_CTX_set_verify( conn->client_ssl_ctx, SSL_VERIFY_NONE, NULL ); - if ( ! XX_httplib_sslize( conn, conn->client_ssl_ctx, SSL_connect ) ) { + if ( ! XX_httplib_sslize( ctx, conn, conn->client_ssl_ctx, SSL_connect ) ) { httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: SSL connection error", __func__ ); SSL_CTX_free( conn->client_ssl_ctx ); diff --git a/src/httplib_connect_websocket_client.c b/src/httplib_connect_websocket_client.c index 774d5629..bd6d6125 100644 --- a/src/httplib_connect_websocket_client.c +++ b/src/httplib_connect_websocket_client.c @@ -117,6 +117,7 @@ struct httplib_connection *httplib_connect_websocket_client( struct httplib_cont return NULL; } + thread_data->ctx = ctx; thread_data->conn = conn; thread_data->data_handler = data_func; thread_data->close_handler = close_func; @@ -133,8 +134,8 @@ struct httplib_connection *httplib_connect_websocket_client( struct httplib_cont httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: thread failed to start", __func__ ); thread_data = httplib_free( thread_data ); - ctx->workerthreadids = httplib_free( ctx->workerthreadids ); conn = httplib_free( conn ); + ctx->workerthreadids = httplib_free( ctx->workerthreadids ); ctx->num_threads = 0; ctx->user_data = NULL; diff --git a/src/httplib_construct_etag.c b/src/httplib_construct_etag.c index b6382e78..cbc14cd2 100644 --- a/src/httplib_construct_etag.c +++ b/src/httplib_construct_etag.c @@ -29,17 +29,17 @@ #include "httplib_string.h" /* - * void XX_httplib_construct_etag( char *buf, size_t buf_len, const struct file *filep ); + * void XX_httplib_construct_etag( const struct httplib_context *ctx, char *buf, size_t buf_len, const struct file *filep ); * * The function XX_httplib_construct_etag() is used to construct an etag which * can be used to identify a file on a specific moment. */ -void XX_httplib_construct_etag( char *buf, size_t buf_len, const struct file *filep ) { +void XX_httplib_construct_etag( const struct httplib_context *ctx, char *buf, size_t buf_len, const struct file *filep ) { if ( filep != NULL && buf != NULL && buf_len > 0 ) { - XX_httplib_snprintf( NULL, NULL, buf, buf_len, "\"%lx.%" INT64_FMT "\"", (unsigned long)filep->last_modified, filep->size ); + XX_httplib_snprintf( ctx, NULL, NULL, buf, buf_len, "\"%lx.%" INT64_FMT "\"", (unsigned long)filep->last_modified, filep->size ); } } /* XX_httplib_construct_etag */ diff --git a/src/httplib_cry.c b/src/httplib_cry.c index 2873b3af..2a6c0da2 100644 --- a/src/httplib_cry.c +++ b/src/httplib_cry.c @@ -83,8 +83,8 @@ void httplib_cry( enum debug_level_t debug_level, const struct httplib_context * * may not even be available on all platforms (Windows etc). */ - if ( ctx->error_log_file == NULL ) return; - if ( ! XX_httplib_fopen( conn, ctx->error_log_file, "a+", &fi ) ) return; + if ( ctx->error_log_file == NULL ) return; + if ( ! XX_httplib_fopen( ctx, conn, ctx->error_log_file, "a+", &fi ) ) return; /* * We now have an open FILE stream pointer in fi.fp and can dump the diff --git a/src/httplib_delete_file.c b/src/httplib_delete_file.c index 5aede70f..6d572b66 100644 --- a/src/httplib_delete_file.c +++ b/src/httplib_delete_file.c @@ -28,33 +28,33 @@ #include "httplib_main.h" /* - * void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ); + * void XX_httplib_delete_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); * * The function XX_httplib_delete_file() deletes a file after a request over a * connection. */ -void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) { +void XX_httplib_delete_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { struct de de; char error_string[ERROR_STRING_LEN]; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->document_root == NULL ) { + if ( ctx == NULL || conn == NULL ) return; + if ( ctx->document_root == NULL ) { - XX_httplib_send_http_error( conn, 405, "Error: File delete operations are not supported" ); + XX_httplib_send_http_error( ctx, conn, 405, "Error: File delete operations are not supported" ); return; } memset( &de.file, 0, sizeof(de.file) ); - if ( ! XX_httplib_stat( conn, path, &de.file ) ) { + if ( ! XX_httplib_stat( ctx, conn, path, &de.file ) ) { /* * XX_httplib_stat returns 0 if the file does not exist */ - XX_httplib_send_http_error( conn, 404, "Error: Cannot delete file\nFile %s not found", path ); + XX_httplib_send_http_error( ctx, conn, 404, "Error: Cannot delete file\nFile %s not found", path ); return; } @@ -64,19 +64,19 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) * the file is cached in memory */ - XX_httplib_send_http_error( conn, 405, "Error: Delete not possible\nDeleting %s is not supported", path ); + XX_httplib_send_http_error( ctx, conn, 405, "Error: Delete not possible\nDeleting %s is not supported", path ); return; } if ( de.file.is_directory ) { - if ( XX_httplib_remove_directory( conn, path ) ) { + if ( XX_httplib_remove_directory( ctx, conn, path ) ) { /* * Delete is successful: Return 204 without content. */ - XX_httplib_send_http_error( conn, 204, "%s", "" ); + XX_httplib_send_http_error( ctx, conn, 204, "%s", "" ); } else { @@ -84,7 +84,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) * Delete is not successful: Return 500 (Server error). */ - XX_httplib_send_http_error( conn, 500, "Error: Could not delete %s", path ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Could not delete %s", path ); } return; } @@ -100,7 +100,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) * File is read only */ - XX_httplib_send_http_error( conn, 403, "Error: Delete not possible\nDeleting %s is not allowed", path ); + XX_httplib_send_http_error( ctx, conn, 403, "Error: Delete not possible\nDeleting %s is not allowed", path ); return; } @@ -108,7 +108,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ) * Try to delete it */ - if ( httplib_remove( path ) == 0 ) XX_httplib_send_http_error( conn, 204, "%s", "" ); - else XX_httplib_send_http_error( conn, 423, "Error: Cannot delete file\nremove(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + if ( httplib_remove( path ) == 0 ) XX_httplib_send_http_error( ctx, conn, 204, "%s", "" ); + else XX_httplib_send_http_error( ctx, conn, 423, "Error: Cannot delete file\nremove(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } /* XX_httplib_delete_file */ diff --git a/src/httplib_dir_scan_callback.c b/src/httplib_dir_scan_callback.c index 80ca7b27..8b56605c 100644 --- a/src/httplib_dir_scan_callback.c +++ b/src/httplib_dir_scan_callback.c @@ -28,11 +28,13 @@ #include "httplib_main.h" #include "httplib_string.h" -void XX_httplib_dir_scan_callback( struct de *de, void *data ) { +void XX_httplib_dir_scan_callback( const struct httplib_context *ctx, struct de *de, void *data ) { struct dir_scan_data *dsd; struct de* old_entries; + UNUSED_PARAMETER(ctx); + dsd = data; if ( dsd->entries == NULL || dsd->num_entries >= dsd->arr_size ) { diff --git a/src/httplib_discard_unread_request_data.c b/src/httplib_discard_unread_request_data.c index d975bed1..7d91267f 100644 --- a/src/httplib_discard_unread_request_data.c +++ b/src/httplib_discard_unread_request_data.c @@ -28,20 +28,20 @@ #include "httplib_main.h" /* - * void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ); + * void XX_httplib_discard_unread_request_data( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_discard_unread_request_data() discards any request * data on a connection which is not further needed but has alread been * received. */ -void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ) { +void XX_httplib_discard_unread_request_data( const struct httplib_context *ctx, struct httplib_connection *conn ) { char buf[MG_BUF_LEN]; size_t to_read; int nread; - if ( conn == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; to_read = sizeof(buf); @@ -54,7 +54,7 @@ void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ) { while ( conn->is_chunked == 1 ) { - nread = httplib_read( conn, buf, to_read ); + nread = httplib_read( ctx, conn, buf, to_read ); if ( nread <= 0 ) break; } @@ -72,7 +72,7 @@ void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ) { to_read = (size_t)(conn->content_len - conn->consumed_content); } - nread = httplib_read( conn, buf, to_read ); + nread = httplib_read( ctx, conn, buf, to_read ); if (nread <= 0) break; } } diff --git a/src/httplib_download.c b/src/httplib_download.c index efa0ac5a..ce36c5d1 100644 --- a/src/httplib_download.c +++ b/src/httplib_download.c @@ -50,7 +50,7 @@ struct httplib_connection * httplib_download( struct httplib_context *ctx, const if ( conn != NULL ) { - i = XX_httplib_vprintf( conn, fmt, ap ); + i = XX_httplib_vprintf( ctx, conn, fmt, ap ); if ( i <= 0 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: error sending request", __func__ ); @@ -74,7 +74,7 @@ struct httplib_connection * httplib_download( struct httplib_context *ctx, const if ( i <= 0 && conn != NULL ) { - httplib_close_connection( conn ); + httplib_close_connection( ctx, conn ); conn = NULL; } diff --git a/src/httplib_fclose_on_exec.c b/src/httplib_fclose_on_exec.c index 1a5b993c..760254d2 100644 --- a/src/httplib_fclose_on_exec.c +++ b/src/httplib_fclose_on_exec.c @@ -27,9 +27,9 @@ #include "httplib_main.h" -void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *conn ) { +void XX_httplib_fclose_on_exec( const struct httplib_context *ctx, struct file *filep, struct httplib_connection *conn ) { - if ( filep == NULL || filep->fp == NULL ) return; + if ( ctx == NULL || filep == NULL || filep->fp == NULL ) return; #ifdef _WIN32 UNUSED_PARAMETER(conn); @@ -39,7 +39,7 @@ void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *c if ( fcntl( fileno( filep->fp ), F_SETFD, FD_CLOEXEC) != 0 ) { - if ( conn != NULL && conn->ctx != NULL ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + if ( conn != NULL ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } #endif diff --git a/src/httplib_fopen.c b/src/httplib_fopen.c index 581f45ff..5d82c8fc 100644 --- a/src/httplib_fopen.c +++ b/src/httplib_fopen.c @@ -28,7 +28,7 @@ #include "httplib_main.h" /* - * 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_context *ctx, const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep ); * * The function XX_httplib_fopen() can be used to open a file which is either * in memory or on the disk. The path is in UTF-8 and therefore needs @@ -44,17 +44,17 @@ * of the same structure (bad cohesion). */ -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_context *ctx, const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep ) { struct stat st; - if ( filep == NULL ) return false; + if ( ctx == NULL || filep == NULL ) return false; memset( filep, 0, sizeof(*filep) ); if ( stat( path, &st ) == 0 ) filep->size = (uint64_t)st.st_size; - if ( ! XX_httplib_is_file_in_memory( conn, path, filep ) ) { + if ( ! XX_httplib_is_file_in_memory( ctx, conn, path, filep ) ) { #ifdef _WIN32 wchar_t wbuf[PATH_MAX]; wchar_t wmode[20]; diff --git a/src/httplib_forward_body_data.c b/src/httplib_forward_body_data.c index d480320e..e1f49dce 100644 --- a/src/httplib_forward_body_data.c +++ b/src/httplib_forward_body_data.c @@ -28,13 +28,13 @@ #include "httplib_main.h" /* - * bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ); + * bool XX_httplib_forward_body_data( const struct httplib_context *ctx, struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ); * * The function XX_httplib_forward_body_data() forwards body data to the * client. The function returns true if successful, and false otherwise. */ -bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ) { +bool XX_httplib_forward_body_data( const struct httplib_context *ctx, struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ) { const char *expect; const char *body; @@ -45,15 +45,15 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO int64_t buffered_len; double timeout; - if ( conn == NULL || conn->ctx == NULL ) return false; + if ( ctx == NULL || conn == NULL ) return false; success = false; - timeout = ((double)conn->ctx->request_timeout) / 1000.0; + timeout = ((double)ctx->request_timeout) / 1000.0; expect = httplib_get_header( conn, "Expect" ); if ( fp == NULL ) { - XX_httplib_send_http_error( conn, 500, "%s", "Error: NULL File" ); + XX_httplib_send_http_error( ctx, conn, 500, "%s", "Error: NULL File" ); return false; } @@ -63,7 +63,7 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO * Content length is not specified by the client. */ - XX_httplib_send_http_error( conn, 411, "%s", "Error: Client did not specify content length" ); + XX_httplib_send_http_error( ctx, conn, 411, "%s", "Error: Client did not specify content length" ); } @@ -73,14 +73,14 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO * Client sent an "Expect: xyz" header and xyz is not 100-continue. */ - XX_httplib_send_http_error( conn, 417, "Error: Can not fulfill expectation %s", expect ); + XX_httplib_send_http_error( ctx, conn, 417, "Error: Can not fulfill expectation %s", expect ); } else { if ( expect != NULL ) { - httplib_printf(conn, "%s", "HTTP/1.1 100 Continue\r\n\r\n"); + httplib_printf( ctx, conn, "%s", "HTTP/1.1 100 Continue\r\n\r\n" ); conn->status_code = 100; } @@ -90,7 +90,7 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO if ( buffered_len < 0 || conn->consumed_content != 0 ) { - XX_httplib_send_http_error( conn, 500, "%s", "Error: Size mismatch" ); + XX_httplib_send_http_error( ctx, conn, 500, "%s", "Error: Size mismatch" ); return false; } @@ -99,7 +99,7 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO if ((int64_t)buffered_len > conn->content_len) buffered_len = (int)conn->content_len; body = conn->buf + conn->request_len + conn->consumed_content; - XX_httplib_push_all( conn->ctx, fp, sock, ssl, body, (int64_t)buffered_len ); + XX_httplib_push_all( ctx, fp, sock, ssl, body, (int64_t)buffered_len ); conn->consumed_content += buffered_len; } @@ -110,8 +110,8 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO to_read = sizeof(buf); if ( (int64_t)to_read > conn->content_len - conn->consumed_content ) to_read = (int)(conn->content_len - conn->consumed_content); - nread = XX_httplib_pull( NULL, conn, buf, to_read, timeout ); - if ( nread <= 0 || XX_httplib_push_all( conn->ctx, fp, sock, ssl, buf, nread ) != nread ) break; + nread = XX_httplib_pull( ctx, NULL, conn, buf, to_read, timeout ); + if ( nread <= 0 || XX_httplib_push_all( ctx, fp, sock, ssl, buf, nread ) != nread ) break; conn->consumed_content += nread; } @@ -129,7 +129,7 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO * reply can no longer be sent, so just close the connection */ - XX_httplib_send_http_error( conn, 500, "%s", "" ); + XX_httplib_send_http_error( ctx, conn, 500, "%s", "" ); } } diff --git a/src/httplib_get_context.c b/src/httplib_get_context.c deleted file mode 100644 index 14482287..00000000 --- a/src/httplib_get_context.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 - * 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. - * - * ============ - * Release: 2.0 - */ - -#include "httplib_main.h" - -/* - * struct httplib_context *httplib_get_context( const struct httplib_connection *conn ); - * - * The function httplib_get_context() returns a pointer to the context - * associated with a connection or NULL if the connection or context could not - * be found. - */ - -struct httplib_context *httplib_get_context( const struct httplib_connection *conn ) { - - if ( conn == NULL ) return NULL; - - return conn->ctx; - -} /* httplib_get_context */ diff --git a/src/httplib_get_mime_type.c b/src/httplib_get_mime_type.c index b5805bd9..77940774 100644 --- a/src/httplib_get_mime_type.c +++ b/src/httplib_get_mime_type.c @@ -30,7 +30,7 @@ /* Look at the "path" extension and figure what mime type it has. * Store mime type in the vector. */ -void XX_httplib_get_mime_type( struct httplib_context *ctx, const char *path, struct vec *vec ) { +void XX_httplib_get_mime_type( const struct httplib_context *ctx, const char *path, struct vec *vec ) { struct vec ext_vec; struct vec mime_vec; diff --git a/src/httplib_get_rel_url_at_current_server.c b/src/httplib_get_rel_url_at_current_server.c index ae50c0b9..7531fba2 100644 --- a/src/httplib_get_rel_url_at_current_server.c +++ b/src/httplib_get_rel_url_at_current_server.c @@ -28,13 +28,13 @@ #include "httplib_main.h" /* - * const char *XX_httplib_get_rel_url_at_current_server( const char *uri, const struct httplib_connection *conn ); + * const char *XX_httplib_get_rel_url_at_current_server( const struct httplib_context *ctx, const char *uri, const struct httplib_connection *conn ); * * The function XX_httplib_get_rel_url_at_current_server() returns the relative * uri at the current server. */ -const char *XX_httplib_get_rel_url_at_current_server( const char *uri, const struct httplib_connection *conn ) { +const char *XX_httplib_get_rel_url_at_current_server( const struct httplib_context *ctx, const char *uri, const struct httplib_connection *conn ) { const char *server_domain; size_t server_domain_len; @@ -46,7 +46,7 @@ const char *XX_httplib_get_rel_url_at_current_server( const char *uri, const str const char *portbegin; char *portend; - if ( conn == NULL || conn->ctx == NULL ) return NULL; + if ( ctx == NULL || conn == NULL ) return NULL; request_domain_len = 0; port = 0; @@ -57,7 +57,7 @@ const char *XX_httplib_get_rel_url_at_current_server( const char *uri, const str * DNS is case insensitive, so use case insensitive string compare here */ - server_domain = conn->ctx->authentication_domain; + server_domain = ctx->authentication_domain; if ( server_domain == NULL ) return NULL; server_domain_len = strlen( server_domain ); diff --git a/src/httplib_get_request_handler.c b/src/httplib_get_request_handler.c index 80dc159e..6f5bf046 100644 --- a/src/httplib_get_request_handler.c +++ b/src/httplib_get_request_handler.c @@ -35,14 +35,14 @@ * and 0 otherwise. */ -int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler_type, httplib_request_handler *handler, httplib_websocket_connect_handler *connect_handler, httplib_websocket_ready_handler *ready_handler, httplib_websocket_data_handler *data_handler, httplib_websocket_close_handler *close_handler, httplib_authorization_handler *auth_handler, void **cbdata ) { +int XX_httplib_get_request_handler( struct httplib_context *ctx, struct httplib_connection *conn, int handler_type, httplib_request_handler *handler, httplib_websocket_connect_handler *connect_handler, httplib_websocket_ready_handler *ready_handler, httplib_websocket_data_handler *data_handler, httplib_websocket_close_handler *close_handler, httplib_authorization_handler *auth_handler, void **cbdata ) { const struct httplib_request_info *request_info; const char *uri; size_t urilen; struct httplib_handler_info *tmp_rh; - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; request_info = httplib_get_request_info( conn ); if ( request_info == NULL ) return 0; @@ -50,13 +50,13 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler uri = request_info->local_uri; urilen = strlen( uri ); - httplib_lock_context( conn->ctx ); + httplib_lock_context( ctx ); /* * first try for an exact match */ - for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { + for (tmp_rh = ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { if ( tmp_rh->handler_type == handler_type ) { @@ -73,7 +73,7 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler else *auth_handler = tmp_rh->auth_handler; *cbdata = tmp_rh->cbdata; - httplib_unlock_context( conn->ctx ); + httplib_unlock_context( ctx ); return 1; } @@ -84,7 +84,7 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler * next try for a partial match, we will accept uri/something */ - for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { + for (tmp_rh = ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { if ( tmp_rh->handler_type == handler_type ) { @@ -102,7 +102,7 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler else *auth_handler = tmp_rh->auth_handler; *cbdata = tmp_rh->cbdata; - httplib_unlock_context( conn->ctx ); + httplib_unlock_context( ctx ); return 1; } @@ -113,7 +113,7 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler * finally try for pattern match */ - for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { + for (tmp_rh = ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) { if ( tmp_rh->handler_type == handler_type ) { @@ -131,14 +131,14 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler else *auth_handler = tmp_rh->auth_handler; *cbdata = tmp_rh->cbdata; - httplib_unlock_context( conn->ctx ); + httplib_unlock_context( ctx ); return 1; } } } - httplib_unlock_context( conn->ctx ); + httplib_unlock_context( ctx ); return 0; /* none found */ diff --git a/src/httplib_get_response.c b/src/httplib_get_response.c index 5ce9646f..d39f6058 100644 --- a/src/httplib_get_response.c +++ b/src/httplib_get_response.c @@ -29,7 +29,7 @@ #include "httplib_string.h" /* - * int httplib_get_response( struct httplib_connection *conn, int timeout ); + * int httplib_get_response( const struct httplib_context *ctx, struct httplib_connection *conn, int timeout ); * * The function httplib_get_response() tries to get a response from a remote * peer. This function does some dirty action by temporarily replacing the @@ -40,22 +40,20 @@ * place. */ -int httplib_get_response( struct httplib_connection *conn, int timeout ) { +int httplib_get_response( const struct httplib_context *ctx, struct httplib_connection *conn, int timeout ) { int err; int ret; - struct httplib_context *octx; struct httplib_context rctx; - if ( conn == NULL || conn->ctx == NULL ) return -1; + if ( ctx == NULL || conn == NULL ) return -1; /* * Replace the connection context with a copy of it where the timeout * value is changed to a parameter passed value. */ - octx = conn->ctx; - rctx = *(conn->ctx); + rctx = *ctx; if ( timeout >= 0 ) { @@ -65,9 +63,7 @@ int httplib_get_response( struct httplib_connection *conn, int timeout ) { else rctx.request_timeout = 0; - conn->ctx = &rctx; - ret = XX_httplib_getreq( conn->ctx, conn, &err ); - conn->ctx = octx; + ret = XX_httplib_getreq( &rctx, conn, &err ); /* * End of dirty context swap code. diff --git a/src/httplib_get_response_code_text.c b/src/httplib_get_response_code_text.c index ed33e537..2948af74 100644 --- a/src/httplib_get_response_code_text.c +++ b/src/httplib_get_response_code_text.c @@ -28,13 +28,13 @@ #include "httplib_main.h" /* - * const char *httplib_get_response_code_text( struct httplib_connection *conn, int response_code ); + * const char *httplib_get_response_code_text( const struct httplib_context *ctx, struct httplib_connection *conn, int response_code ); * * The function httplib_get_response_code_text() returns a text associated with an * HTTP response code. */ -const char *httplib_get_response_code_text( struct httplib_connection *conn, int response_code ) { +const char *httplib_get_response_code_text( const struct httplib_context *ctx, struct httplib_connection *conn, int response_code ) { /* * See IANA HTTP status code assignment: @@ -118,7 +118,7 @@ const char *httplib_get_response_code_text( struct httplib_connection *conn, int * This error code is unknown. This should not happen. */ - if ( conn != NULL && conn->ctx != NULL ) httplib_cry( DEBUG_LEVEL_INFO, conn->ctx, conn, "%s: unknown HTTP response code: %u", __func__, response_code ); + if ( ctx != NULL && conn != NULL ) httplib_cry( DEBUG_LEVEL_INFO, ctx, conn, "%s: unknown HTTP response code: %u", __func__, response_code ); /* * Return at least a category according to RFC 2616 Section 10. diff --git a/src/httplib_getreq.c b/src/httplib_getreq.c index 33f465ed..fbcae0d9 100644 --- a/src/httplib_getreq.c +++ b/src/httplib_getreq.c @@ -29,12 +29,12 @@ #include "httplib_string.h" /* - * bool XX_httplib_getreq( struct httplib_context *ctx, struct httplib_connection *conn, int *err ); + * bool XX_httplib_getreq( const struct httplib_context *ctx, struct httplib_connection *conn, int *err ); * * The function XX_httplib_getreq() processes a request from a remote client. */ -bool XX_httplib_getreq( struct httplib_context *ctx, struct httplib_connection *conn, int *err ) { +bool XX_httplib_getreq( const struct httplib_context *ctx, struct httplib_connection *conn, int *err ) { const char *cl; @@ -58,7 +58,7 @@ bool XX_httplib_getreq( struct httplib_context *ctx, struct httplib_connection * clock_gettime( CLOCK_MONOTONIC, &conn->req_time ); - conn->request_len = XX_httplib_read_request( NULL, conn, conn->buf, conn->buf_size, &conn->data_len ); + conn->request_len = XX_httplib_read_request( ctx, NULL, conn, conn->buf, conn->buf_size, &conn->data_len ); /* * assert(conn->request_len < 0 || conn->data_len >= conn->request_len); diff --git a/src/httplib_handle_cgi_request.c b/src/httplib_handle_cgi_request.c index e1b238d1..245d70e8 100644 --- a/src/httplib_handle_cgi_request.c +++ b/src/httplib_handle_cgi_request.c @@ -29,7 +29,7 @@ #include "httplib_string.h" /* - * void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char *prog ); + * void XX_httplib_handle_cgi_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog ); * * The function XX_httplib_handle_cgi_request() handles a request for a CGI * resource. @@ -37,7 +37,7 @@ #if !defined(NO_CGI) -void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char *prog ) { +void XX_httplib_handle_cgi_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog ) { char *buf; size_t buflen; @@ -64,7 +64,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char struct file fout = STRUCT_FILE_INITIALIZER; pid_t pid = (pid_t)-1; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; in = NULL; out = NULL; @@ -73,7 +73,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char buf = NULL; buflen = 16384; - XX_httplib_prepare_cgi_environment( conn, prog, &blk ); + XX_httplib_prepare_cgi_environment( ctx, conn, prog, &blk ); /* * CGI must be executed in its own directory. 'dir' must point to the @@ -81,12 +81,12 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char * executable program name relative to 'dir'. */ - XX_httplib_snprintf( conn, &truncated, dir, sizeof(dir), "%s", prog ); + XX_httplib_snprintf( ctx, conn, &truncated, dir, sizeof(dir), "%s", prog ); if ( truncated ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Path too long", __func__, prog ); - XX_httplib_send_http_error( conn, 500, "Error: %s", "CGI path too long" ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Path too long", __func__, prog ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: %s", "CGI path too long" ); goto done; } @@ -106,19 +106,19 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0 ) { status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Can not create CGI pipes: %s", __func__, prog, status ); - XX_httplib_send_http_error( conn, 500, "Error: Cannot create CGI pipe: %s", status ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Can not create CGI pipes: %s", __func__, prog, status ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot create CGI pipe: %s", status ); goto done; } - pid = XX_httplib_spawn_process( conn, cptr, blk.buf, blk.var, fdin, fdout, fderr, dir ); + pid = XX_httplib_spawn_process( ctx, conn, cptr, blk.buf, blk.var, fdin, fdout, fderr, dir ); if ( pid == (pid_t)-1 ) { status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Can not spawn CGI process: %s", __func__, prog, status ); - XX_httplib_send_http_error( conn, 500, "Error: Cannot spawn CGI process [%s]: %s", prog, status ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Can not spawn CGI process: %s", __func__, prog, status ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot spawn CGI process [%s]: %s", prog, status ); goto done; } @@ -152,8 +152,8 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (in = fdopen( fdin[1], "wb" )) == NULL ) { status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Can not open stdin: %s", __func__, prog, status ); - XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdin\nfopen: %s", status ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Can not open stdin: %s", __func__, prog, status ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdin\nfopen: %s", status ); goto done; } @@ -161,8 +161,8 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (out = fdopen( fdout[0], "rb" )) == NULL ) { status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Can not open stdout: %s", __func__, prog, status ); - XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Can not open stdout: %s", __func__, prog, status ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); goto done; } @@ -170,8 +170,8 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( (err = fdopen( fderr[0], "rb" )) == NULL ) { status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Can not open stderr: %s", __func__, prog, status ); - XX_httplib_send_http_error( conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Can not open stderr: %s", __func__, prog, status ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdout\nfopen: %s", status ); goto done; } @@ -188,13 +188,13 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char * This is a POST/PUT request, or another request with body data. */ - if ( ! XX_httplib_forward_body_data( conn, in, INVALID_SOCKET, NULL ) ) { + if ( ! XX_httplib_forward_body_data( ctx, conn, in, INVALID_SOCKET, NULL ) ) { /* * Error sending the body data */ - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Forward body data failed", __func__, prog ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Forward body data failed", __func__, prog ); goto done; } @@ -221,13 +221,13 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char if ( buf == NULL ) { - XX_httplib_send_http_error( conn, 500, "Error: Not enough memory for CGI buffer (%u bytes)", (unsigned int)buflen ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Not enough memory for buffer (%u " "bytes)", __func__, prog, (unsigned int)buflen ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Not enough memory for CGI buffer (%u bytes)", (unsigned int)buflen ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Not enough memory for buffer (%u " "bytes)", __func__, prog, (unsigned int)buflen ); goto done; } - headers_len = XX_httplib_read_request( out, conn, buf, (int)buflen, &data_len ); + headers_len = XX_httplib_read_request( ctx, out, conn, buf, (int)buflen, &data_len ); if ( headers_len <= 0 ) { /* @@ -235,18 +235,18 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char * stderr. */ - i = XX_httplib_pull_all( err, conn, buf, (int)buflen ); + i = XX_httplib_pull_all( ctx, err, conn, buf, (int)buflen ); if ( i > 0 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\" sent error " "message: [%.*s]", __func__, prog, i, buf ); - XX_httplib_send_http_error( conn, 500, "Error: CGI program \"%s\" sent error " "message: [%.*s]", prog, i, buf ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\" sent error " "message: [%.*s]", __func__, prog, i, buf ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI program \"%s\" sent error " "message: [%.*s]", prog, i, buf ); } else { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program sent malformed or too big " "(>%u bytes) HTTP headers: [%.*s]", __func__, (unsigned)buflen, data_len, buf ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program sent malformed or too big " "(>%u bytes) HTTP headers: [%.*s]", __func__, (unsigned)buflen, data_len, buf ); - XX_httplib_send_http_error( conn, + XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI program sent malformed or too big " "(>%u bytes) HTTP headers: [%.*s]", @@ -283,27 +283,27 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char connection_state = XX_httplib_get_header( &ri, "Connection" ); if ( ! XX_httplib_header_has_option( connection_state, "keep-alive" ) ) conn->must_close = true; - httplib_printf( conn, "HTTP/1.1 %d %s\r\n", conn->status_code, status_text ); + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n", conn->status_code, status_text ); /* * Send headers */ - for (i=0; inum_bytes_sent += httplib_write(conn, buf + headers_len, (size_t)(data_len - headers_len)); + conn->num_bytes_sent += httplib_write( ctx, conn, buf+headers_len, (size_t)(data_len - headers_len) ); /* * Read the rest of CGI output and send to the client */ - XX_httplib_send_file_data( conn, &fout, 0, INT64_MAX ); + XX_httplib_send_file_data( ctx, conn, &fout, 0, INT64_MAX ); done: blk.var = httplib_free( blk.var ); diff --git a/src/httplib_handle_directory_request.c b/src/httplib_handle_directory_request.c index 6afd6da4..ae26548d 100644 --- a/src/httplib_handle_directory_request.c +++ b/src/httplib_handle_directory_request.c @@ -28,7 +28,7 @@ #include "httplib_main.h" #include "httplib_utils.h" -void XX_httplib_handle_directory_request( struct httplib_connection *conn, const char *dir ) { +void XX_httplib_handle_directory_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir ) { unsigned int i; int sort_direction; @@ -37,12 +37,12 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const char error_string[ERROR_STRING_LEN]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( dir == NULL ) { XX_httplib_send_http_error( conn, 500, "Internal server error\nOpening NULL directory" ); return; } + if ( ctx == NULL || conn == NULL ) return; + if ( dir == NULL ) { XX_httplib_send_http_error( ctx, conn, 500, "Internal server error\nOpening NULL directory" ); return; } - if ( ! XX_httplib_scan_directory( conn, dir, & data, XX_httplib_dir_scan_callback ) ) { + if ( ! XX_httplib_scan_directory( ctx, conn, dir, & data, XX_httplib_dir_scan_callback ) ) { - XX_httplib_send_http_error( conn, 500, "Error: Cannot open directory\nopendir(%s): %s", dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot open directory\nopendir(%s): %s", dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -53,11 +53,11 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const conn->must_close = true; - httplib_printf( conn, "HTTP/1.1 200 OK\r\n" ); - XX_httplib_send_static_cache_header( conn ); - httplib_printf( conn, "Date: %s\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=utf-8\r\n\r\n", date ); + httplib_printf( ctx, conn, "HTTP/1.1 200 OK\r\n" ); + XX_httplib_send_static_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Date: %s\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=utf-8\r\n\r\n", date ); - conn->num_bytes_sent += httplib_printf( conn, + conn->num_bytes_sent += httplib_printf( ctx, conn, "Index of %s" "" "

Index of %s

"
@@ -75,7 +75,7 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
 	 * Print first entry - link to a parent directory
 	 */
 
-	conn->num_bytes_sent += httplib_printf(conn,
+	conn->num_bytes_sent += httplib_printf( ctx, conn,
 	              ""
 	              "\n",
 	              conn->request_info.local_uri,
@@ -94,14 +94,14 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
 
 		for (i=0; inum_bytes_sent += httplib_printf( conn, "%s", "
%s %s  %s
" ); + conn->num_bytes_sent += httplib_printf( ctx, conn, "%s", "" ); conn->status_code = 200; } /* XX_httplib_handle_directory_request */ diff --git a/src/httplib_handle_file_based_request.c b/src/httplib_handle_file_based_request.c index f9845894..bc0ebb59 100644 --- a/src/httplib_handle_file_based_request.c +++ b/src/httplib_handle_file_based_request.c @@ -28,26 +28,26 @@ #include "httplib_main.h" /* - * void XX_httplib_handle_file_based_request( struct httplib_connection *conn, const char *path, struct file *file ); + * void XX_httplib_handle_file_based_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *file ); * * The function XX_httplib_handle_file_based_request() handles a request which * involves a file. This can either be a CGI request, an SSI request of a * request for a static file. */ -void XX_httplib_handle_file_based_request( struct httplib_connection *conn, const char *path, struct file *file ) { +void XX_httplib_handle_file_based_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *file ) { #if !defined(NO_CGI) const char *cgi_ext; #endif /* ! NO_CGI */ const char *ssi_ext; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; #if !defined(NO_CGI) - cgi_ext = conn->ctx->cgi_pattern; + cgi_ext = ctx->cgi_pattern; #endif /* ! NO_CGI */ - ssi_ext = conn->ctx->ssi_pattern; + ssi_ext = ctx->ssi_pattern; if (0) { #if !defined(NO_CGI) @@ -59,20 +59,20 @@ void XX_httplib_handle_file_based_request( struct httplib_connection *conn, cons * CGI scripts may support all HTTP methods */ - XX_httplib_handle_cgi_request( conn, path ); + XX_httplib_handle_cgi_request( ctx, conn, path ); #endif /* !NO_CGI */ } else if ( ssi_ext != NULL && XX_httplib_match_prefix( ssi_ext, strlen( ssi_ext ), path ) > 0 ) { - XX_httplib_handle_ssi_file_request( conn, path, file ); + XX_httplib_handle_ssi_file_request( ctx, conn, path, file ); } - else if ( conn->ctx->static_file_max_age > 0 && ! conn->in_error_handler && XX_httplib_is_not_modified( conn, file ) ) { + else if ( ctx->static_file_max_age > 0 && ! conn->in_error_handler && XX_httplib_is_not_modified( ctx, conn, file ) ) { - XX_httplib_handle_not_modified_static_file_request( conn, file ); + XX_httplib_handle_not_modified_static_file_request( ctx, conn, file ); } - else XX_httplib_handle_static_file_request( conn, path, file, NULL, NULL ); + else XX_httplib_handle_static_file_request( ctx, conn, path, file, NULL, NULL ); } /* XX_httplib_handle_file_based_request */ diff --git a/src/httplib_handle_form_request.c b/src/httplib_handle_form_request.c index 1e55a8b3..430904fe 100644 --- a/src/httplib_handle_form_request.c +++ b/src/httplib_handle_form_request.c @@ -26,14 +26,7 @@ #include "httplib_main.h" -static int url_encoded_field_found(const struct httplib_connection *conn, - const char *key, - size_t key_len, - const char *filename, - size_t filename_len, - char *path, - size_t path_len, - struct httplib_form_data_handler *fdh) { +static int url_encoded_field_found( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *key, size_t key_len, const char *filename, size_t filename_len, char *path, size_t path_len, struct httplib_form_data_handler *fdh ) { char key_dec[1024]; char filename_dec[1024]; @@ -55,7 +48,7 @@ static int url_encoded_field_found(const struct httplib_connection *conn, * Log error message and skip this field. */ - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: Cannot decode filename", __func__ ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: Cannot decode filename", __func__ ); return FORM_FIELD_STORAGE_SKIP; } @@ -67,7 +60,7 @@ static int url_encoded_field_found(const struct httplib_connection *conn, if ( fdh->field_get == NULL ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: Function \"Get\" not available", __func__ ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: Function \"Get\" not available", __func__ ); return FORM_FIELD_STORAGE_SKIP; } } @@ -75,7 +68,7 @@ static int url_encoded_field_found(const struct httplib_connection *conn, if ( fdh->field_store == NULL ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: Function \"Store\" not available", __func__ ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: Function \"Store\" not available", __func__ ); return FORM_FIELD_STORAGE_SKIP; } } @@ -84,12 +77,7 @@ static int url_encoded_field_found(const struct httplib_connection *conn, } -static int url_encoded_field_get(const struct httplib_connection *conn, - const char *key, - size_t key_len, - const char *value, - size_t value_len, - struct httplib_form_data_handler *fdh) { +static int url_encoded_field_get( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *key, size_t key_len, const char *value, size_t value_len, struct httplib_form_data_handler *fdh ) { char key_dec[1024]; @@ -103,7 +91,7 @@ static int url_encoded_field_get(const struct httplib_connection *conn, * Log error message and stop parsing the form data. */ - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Not enough memory (required: %lu)", __func__, (unsigned long)(value_len + 1)); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Not enough memory (required: %lu)", __func__, (unsigned long)(value_len + 1)); return FORM_FIELD_STORAGE_ABORT; } @@ -167,7 +155,7 @@ static const char * search_boundary(const char *buf, size_t buf_len, const char } -int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_form_data_handler *fdh) { +int httplib_handle_form_request( const struct httplib_context *ctx, struct httplib_connection *conn, struct httplib_form_data_handler *fdh ) { const char *content_type; char path[512]; @@ -245,7 +233,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ memset( path, 0, sizeof(path) ); field_count++; - field_storage = url_encoded_field_found( conn, data, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh ); + field_storage = url_encoded_field_found( ctx, conn, data, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh ); val++; next = strchr( val, '&' ); @@ -266,7 +254,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ * Call callback */ - url_encoded_field_get( conn, data, (size_t)keylen, val, (size_t)vallen, fdh ); + url_encoded_field_get( ctx, conn, data, (size_t)keylen, val, (size_t)vallen, fdh ); } if ( field_storage == FORM_FIELD_STORAGE_STORE ) { @@ -275,17 +263,17 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ * Store the content to a file */ - if ( XX_httplib_fopen( conn, path, "wb", &fstore ) == 0 ) fstore.fp = NULL; + if ( XX_httplib_fopen( ctx, conn, path, "wb", &fstore ) == 0 ) fstore.fp = NULL; file_size = 0; if ( fstore.fp != NULL ) { size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp); if ((n != (size_t)vallen) || (ferror(fstore.fp))) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot write file %s", __func__, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot write file %s", __func__, path ); fclose( fstore.fp ); fstore.fp = NULL; - XX_httplib_remove_bad_file( conn, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } file_size += (int64_t)n; @@ -302,14 +290,14 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ } else { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); - XX_httplib_remove_bad_file( conn, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } fstore.fp = NULL; } - } else httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot create file %s", __func__, path ); + } else httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot create file %s", __func__, path ); } /* @@ -371,7 +359,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ if ((size_t)buf_fill < (sizeof(buf) - 1)) { size_t to_read = sizeof(buf) - 1 - (size_t)buf_fill; - r = httplib_read( conn, buf + (size_t)buf_fill, to_read ); + r = httplib_read( ctx, conn, buf + (size_t)buf_fill, to_read ); if ( r < 0 ) return -1; /* read error */ if ( r != (int)to_read ) { @@ -402,15 +390,15 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ memset( path, 0, sizeof(path) ); field_count++; - field_storage = url_encoded_field_found( conn, buf, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh ); + field_storage = url_encoded_field_found( ctx, conn, buf, (size_t)keylen, NULL, 0, path, sizeof(path) - 1, fdh ); if ( (field_storage & FORM_FIELD_STORAGE_ABORT) == FORM_FIELD_STORAGE_ABORT ) break; /* Stop parsing the request */ if ( field_storage == FORM_FIELD_STORAGE_STORE ) { - if (XX_httplib_fopen(conn, path, "wb", &fstore) == 0) fstore.fp = NULL; + if ( XX_httplib_fopen( ctx, conn, path, "wb", &fstore ) == 0 ) fstore.fp = NULL; file_size = 0; - if (!fstore.fp) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot create file %s", __func__, path); + if (!fstore.fp) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot create file %s", __func__, path); } get_block = 0; @@ -444,7 +432,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ #endif /* Call callback */ - url_encoded_field_get(conn, + url_encoded_field_get( ctx, conn, ((get_block > 0) ? NULL : buf), ((get_block > 0) ? 0 : (size_t)keylen), val, @@ -455,10 +443,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ if ( fstore.fp ) { size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp); if ((n != (size_t)vallen) || (ferror(fstore.fp))) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot write file %s", __func__, path); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot write file %s", __func__, path); fclose(fstore.fp); fstore.fp = NULL; - XX_httplib_remove_bad_file(conn, path); + XX_httplib_remove_bad_file( ctx, conn, path ); } file_size += (int64_t)n; } @@ -471,7 +459,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ if ((size_t)buf_fill < (sizeof(buf) - 1)) { size_t to_read = sizeof(buf) - 1 - (size_t)buf_fill; - r = httplib_read(conn, buf + (size_t)buf_fill, to_read); + r = httplib_read( ctx, conn, buf + (size_t)buf_fill, to_read ); if ( r < 0 ) return -1; /* read error */ if (r != (int)to_read) { @@ -506,8 +494,8 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ } else { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); - XX_httplib_remove_bad_file( conn, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } fstore.fp = NULL; @@ -593,7 +581,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ size_t n; int get_block; - r = httplib_read( conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill ); + r = httplib_read( ctx, conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill ); if ( r < 0 ) return -1; /* read error */ buf_fill += r; @@ -690,7 +678,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ memset( path, 0, sizeof(path) ); field_count++; - field_storage = url_encoded_field_found( conn, nbeg, (size_t)(nend - nbeg), fbeg, (size_t)(fend - fbeg), path, sizeof(path) - 1, fdh ); + field_storage = url_encoded_field_found( ctx, conn, nbeg, (size_t)(nend - nbeg), fbeg, (size_t)(fend - fbeg), path, sizeof(path) - 1, fdh ); /* * If the boundary is already in the buffer, get the address, @@ -705,10 +693,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ * Store the content to a file */ - if ( XX_httplib_fopen( conn, path, "wb", &fstore ) == 0 ) fstore.fp = NULL; + if ( XX_httplib_fopen( ctx, conn, path, "wb", &fstore ) == 0 ) fstore.fp = NULL; file_size = 0; - if ( ! fstore.fp ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot create file %s", __func__, path ); + if ( ! fstore.fp ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot create file %s", __func__, path ); } get_block = 0; @@ -752,10 +740,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ if ( n != towrite || ferror( fstore.fp ) ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot write file %s", __func__, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot write file %s", __func__, path ); fclose( fstore.fp ); fstore.fp = NULL; - XX_httplib_remove_bad_file( conn, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } file_size += (int64_t)n; @@ -770,7 +758,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ * Read new data */ - r = httplib_read( conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill ); + r = httplib_read( ctx, conn, buf + (size_t)buf_fill, sizeof(buf) - 1 - (size_t)buf_fill ); if ( r < 0 ) return -1; /* read error */ buf_fill += r; @@ -808,10 +796,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ if ( n != towrite || ferror( fstore.fp ) ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot write file %s", __func__, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot write file %s", __func__, path ); fclose( fstore.fp ); fstore.fp = NULL; - XX_httplib_remove_bad_file( conn, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } file_size += (int64_t)n; } @@ -832,8 +820,8 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_ } else { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); - XX_httplib_remove_bad_file( conn, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); } fstore.fp = NULL; } diff --git a/src/httplib_handle_not_modified_static_file_request.c b/src/httplib_handle_not_modified_static_file_request.c index bc5759b1..d38d7758 100644 --- a/src/httplib_handle_not_modified_static_file_request.c +++ b/src/httplib_handle_not_modified_static_file_request.c @@ -29,31 +29,31 @@ #include "httplib_utils.h" /* - * void XX_httplib_handle_not_modified_static_file_request( struct httplib_connection *conn, struct file *filep ); + * void XX_httplib_handle_not_modified_static_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ); * * The function XX_httplib_handle_not_modified_static_file_request() is used to * send a 304 response to a client to indicate that the requested resource has * not been changed. */ -void XX_httplib_handle_not_modified_static_file_request( struct httplib_connection *conn, struct file *filep ) { +void XX_httplib_handle_not_modified_static_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ) { char date[64]; char lm[64]; char etag[64]; time_t curtime; - if ( conn == NULL || filep == NULL ) return; + if ( ctx == NULL || conn == NULL || filep == NULL ) return; curtime = time( NULL ); conn->status_code = 304; XX_httplib_gmt_time_string( date, sizeof(date), & curtime ); XX_httplib_gmt_time_string( lm, sizeof(lm), & filep->last_modified ); - XX_httplib_construct_etag( etag, sizeof(etag), filep ); + XX_httplib_construct_etag( ctx, etag, sizeof(etag), filep ); - httplib_printf( conn, "HTTP/1.1 %d %s\r\n" "Date: %s\r\n", conn->status_code, httplib_get_response_code_text( conn, conn->status_code ), date ); - XX_httplib_send_static_cache_header( conn ); - httplib_printf( conn, "Last-Modified: %s\r\n" "Etag: %s\r\n" "Connection: %s\r\n" "\r\n", lm, etag, XX_httplib_suggest_connection_header( conn ) ); + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n" "Date: %s\r\n", conn->status_code, httplib_get_response_code_text( ctx, conn, conn->status_code ), date ); + XX_httplib_send_static_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Last-Modified: %s\r\n" "Etag: %s\r\n" "Connection: %s\r\n" "\r\n", lm, etag, XX_httplib_suggest_connection_header( ctx, conn ) ); } /* XX_httplib_handle_not_modified_static_file_request */ diff --git a/src/httplib_handle_propfind.c b/src/httplib_handle_propfind.c index 7dddba70..5c7ae8a9 100644 --- a/src/httplib_handle_propfind.c +++ b/src/httplib_handle_propfind.c @@ -30,20 +30,20 @@ #include "httplib_utils.h" /* - * static void print_props( struct httplib_connection *conn, const char *uri, struct file *filep ); + * static void print_props( const struct httplib_context *ctx, struct httplib_connection *conn, const char *uri, struct file *filep ); * * The function print_props() writes the PROPFIND properties for a collection * event. */ -static void print_props( struct httplib_connection *conn, const char *uri, struct file *filep ) { +static void print_props( const struct httplib_context *ctx, struct httplib_connection *conn, const char *uri, struct file *filep ) { char mtime[64]; if ( conn == NULL || uri == NULL || filep == NULL ) return; XX_httplib_gmt_time_string( mtime, sizeof(mtime), &filep->last_modified ); - conn->num_bytes_sent += httplib_printf(conn, + conn->num_bytes_sent += httplib_printf( ctx, conn, "" "%s" "" @@ -63,13 +63,13 @@ static void print_props( struct httplib_connection *conn, const char *uri, struc } /* print_props */ /* - * static void print_dav_dir_entry( struct de *de, void *data ); + * static void print_dav_dir_entry( const struct httplib_context *ctx, struct de *de, void *data ); * * The function print_dav_dir_entry() is used to send the properties of a * webdav directory to the remote client. */ -static void print_dav_dir_entry( struct de *de, void *data ) { +static void print_dav_dir_entry( const struct httplib_context *ctx, struct de *de, void *data ) { char href[PATH_MAX]; char href_encoded[PATH_MAX * 3 /* worst case */]; @@ -80,30 +80,30 @@ static void print_dav_dir_entry( struct de *de, void *data ) { if ( de == NULL || conn == NULL ) return; - XX_httplib_snprintf( conn, &truncated, href, sizeof(href), "%s%s", conn->request_info.local_uri, de->file_name ); + XX_httplib_snprintf( ctx, conn, &truncated, href, sizeof(href), "%s%s", conn->request_info.local_uri, de->file_name ); if ( ! truncated ) { httplib_url_encode( href, href_encoded, PATH_MAX * 3 ); - print_props( conn, href_encoded, &de->file ); + print_props( ctx, conn, href_encoded, &de->file ); } } /* print_dav_dir_entry */ /* - * void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *path, struct file *filep ); + * void XX_httplib_handle_propfind( const stuct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); * * The function XX_httlib_handle_propfind() handles a propfind request. */ -void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *path, struct file *filep ) { +void XX_httplib_handle_propfind( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ) { const char *depth; char date[64]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL || path == NULL || filep == NULL ) return; - if ( conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL || path == NULL || filep == NULL ) return; + if ( ctx->document_root == NULL ) return; depth = httplib_get_header( conn, "Depth" ); curtime = time( NULL ); @@ -112,27 +112,27 @@ void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *pa conn->must_close = true; conn->status_code = 207; - httplib_printf( conn, "HTTP/1.1 207 Multi-Status\r\n" "Date: %s\r\n", date ); - XX_httplib_send_static_cache_header( conn ); - httplib_printf( conn, "Connection: %s\r\n" "Content-Type: text/xml; charset=utf-8\r\n\r\n", XX_httplib_suggest_connection_header( conn ) ); + httplib_printf( ctx, conn, "HTTP/1.1 207 Multi-Status\r\n" "Date: %s\r\n", date ); + XX_httplib_send_static_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Connection: %s\r\n" "Content-Type: text/xml; charset=utf-8\r\n\r\n", XX_httplib_suggest_connection_header( ctx, conn ) ); - conn->num_bytes_sent += httplib_printf( conn, "" "\n" ); + conn->num_bytes_sent += httplib_printf( ctx, conn, "" "\n" ); /* * Print properties for the requested resource itself */ - print_props( conn, conn->request_info.local_uri, filep ); + print_props( ctx, conn, conn->request_info.local_uri, filep ); /* * If it is a directory, print directory entries too if Depth is not 0 */ - if ( conn->ctx->enable_directory_listing && filep && filep->is_directory && ( depth == NULL || strcmp( depth, "0" ) != 0 ) ) { + if ( ctx->enable_directory_listing && filep && filep->is_directory && ( depth == NULL || strcmp( depth, "0" ) != 0 ) ) { - XX_httplib_scan_directory( conn, path, conn, &print_dav_dir_entry ); + XX_httplib_scan_directory( ctx, conn, path, conn, &print_dav_dir_entry ); } - conn->num_bytes_sent += httplib_printf( conn, "%s\n", "" ); + conn->num_bytes_sent += httplib_printf( ctx, conn, "%s\n", "" ); } /* XX_httplib_handle_propfind */ diff --git a/src/httplib_handle_request.c b/src/httplib_handle_request.c index 89379897..5ffb2ecf 100644 --- a/src/httplib_handle_request.c +++ b/src/httplib_handle_request.c @@ -30,7 +30,7 @@ #include "httplib_utils.h" /* - * void XX_httplib_handle_request( struct httplib_connection *conn ); + * void XX_httplib_handle_request( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_handle_request() handles an incoming request. This * is the heart of the LibHTTP's logic. This function is called when the @@ -38,7 +38,7 @@ * to take: serve a file, or a directory, or call embedded function, etcetera. */ -void XX_httplib_handle_request( struct httplib_connection *conn ) { +void XX_httplib_handle_request( struct httplib_context *ctx, struct httplib_connection *conn ) { struct httplib_request_info *ri; char path[PATH_MAX]; @@ -66,7 +66,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { char * var; } ptr; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; ri = & conn->request_info; is_found = false; @@ -105,9 +105,9 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { if ( ! conn->client.has_ssl && conn->client.has_redir ) { - ssl_index = XX_httplib_get_first_ssl_listener_index( conn->ctx ); + ssl_index = XX_httplib_get_first_ssl_listener_index( ctx ); - if ( ssl_index >= 0 ) XX_httplib_redirect_to_https_port( conn, ssl_index ); + if ( ssl_index >= 0 ) XX_httplib_redirect_to_https_port( ctx, conn, ssl_index ); else { /* @@ -115,8 +115,8 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { * but no https port to forward to. */ - XX_httplib_send_http_error( conn, 503, "%s", "Error: SSL forward not configured properly" ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: can not redirect to SSL, no SSL port available", __func__ ); + XX_httplib_send_http_error( ctx, conn, 503, "%s", "Error: SSL forward not configured properly" ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: can not redirect to SSL, no SSL port available", __func__ ); } return; @@ -129,7 +129,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { */ ptr.con = ri->local_uri; - if ( XX_httplib_should_decode_url( conn ) ) httplib_url_decode( ptr.con, uri_len, ptr.var, uri_len + 1, 0 ); + if ( XX_httplib_should_decode_url( ctx ) ) httplib_url_decode( ptr.con, uri_len, ptr.var, uri_len + 1, 0 ); /* * 1.4. clean URIs, so a path like allowed_dir/../forbidden_file is @@ -149,13 +149,13 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { * 3. if this ip has limited speed, set it for this connection */ - conn->throttle = XX_httplib_set_throttle( conn->ctx->throttle, XX_httplib_get_remote_ip( conn ), ri->local_uri ); + conn->throttle = XX_httplib_set_throttle( ctx->throttle, XX_httplib_get_remote_ip( conn ), ri->local_uri ); /* * 4. call a "handle everything" callback, if registered */ - if ( conn->ctx->callbacks.begin_request != NULL ) { + if ( ctx->callbacks.begin_request != NULL ) { /* * Note that since V1.7 the "begin_request" function is called @@ -163,7 +163,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { * required, use a request_handler instead. */ - i = conn->ctx->callbacks.begin_request( conn ); + i = ctx->callbacks.begin_request( conn ); if ( i > 0 ) { @@ -210,7 +210,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) { * 5.2. check if the request will be handled by a callback */ - if ( XX_httplib_get_request_handler( conn, + if ( XX_httplib_get_request_handler( ctx, conn, is_websocket_request ? WEBSOCKET_HANDLER : REQUEST_HANDLER, &callback_handler, &ws_connect_handler, @@ -242,14 +242,7 @@ no_callback_resource: */ is_callback_resource = false; - XX_httplib_interpret_uri( conn, - path, - sizeof(path), - &file, - &is_found, - &is_script_resource, - &is_websocket_request, - &is_put_or_delete_request ); + XX_httplib_interpret_uri( ctx, conn, path, sizeof(path), &file, &is_found, &is_script_resource, &is_websocket_request, &is_put_or_delete_request ); } /* @@ -258,7 +251,7 @@ no_callback_resource: * 6.1. a custom authorization handler is installed */ - if ( XX_httplib_get_request_handler( conn, AUTH_HANDLER, NULL, NULL, NULL, NULL, NULL, &auth_handler, &auth_callback_data ) ) { + if ( XX_httplib_get_request_handler( ctx, conn, AUTH_HANDLER, NULL, NULL, NULL, NULL, NULL, &auth_handler, &auth_callback_data ) ) { if ( ! auth_handler( conn, auth_callback_data ) ) return; } @@ -270,14 +263,14 @@ no_callback_resource: * 6.2.1. thus, the server must have real files */ - if ( conn->ctx->document_root == NULL ) { + if ( ctx->document_root == NULL ) { /* * This server does not have any real files, thus the * PUT/DELETE methods are not valid. */ - XX_httplib_send_http_error( conn, 405, "%s method not allowed", conn->request_info.request_method ); + XX_httplib_send_http_error( ctx, conn, 405, "%s method not allowed", conn->request_info.request_method ); return; } @@ -285,9 +278,9 @@ no_callback_resource: * 6.2.2. Check if put authorization for static files is * available. */ - if ( ! XX_httplib_is_authorized_for_put( conn ) ) { + if ( ! XX_httplib_is_authorized_for_put( ctx, conn ) ) { - XX_httplib_send_authorization_request( conn ); + XX_httplib_send_authorization_request( ctx, conn ); return; } } @@ -299,9 +292,9 @@ no_callback_resource: * correspond to a file. Check authorization. */ - if ( ! XX_httplib_check_authorization( conn, path ) ) { + if ( ! XX_httplib_check_authorization( ctx, conn, path ) ) { - XX_httplib_send_authorization_request( conn ); + XX_httplib_send_authorization_request( ctx, conn ); return; } } @@ -328,7 +321,7 @@ no_callback_resource: */ conn->status_code = i; - XX_httplib_discard_unread_request_data( conn ); + XX_httplib_discard_unread_request_data( ctx, conn ); } else { @@ -338,14 +331,7 @@ no_callback_resource: * the authorization check might be different */ - XX_httplib_interpret_uri( conn, - path, - sizeof(path), - &file, - &is_found, - &is_script_resource, - &is_websocket_request, - &is_put_or_delete_request ); + XX_httplib_interpret_uri( ctx, conn, path, sizeof(path), &file, &is_found, &is_script_resource, &is_websocket_request, &is_put_or_delete_request ); callback_handler = NULL; goto no_callback_resource; @@ -353,14 +339,7 @@ no_callback_resource: } else { - XX_httplib_handle_websocket_request( conn, - path, - is_callback_resource, - ws_connect_handler, - ws_ready_handler, - ws_data_handler, - ws_close_handler, - callback_data ); + XX_httplib_handle_websocket_request( ctx, conn, path, is_callback_resource, ws_connect_handler, ws_ready_handler, ws_data_handler, ws_close_handler, callback_data ); } return; @@ -378,10 +357,10 @@ no_callback_resource: * Websocket Lua script, the 0 in the third parameter indicates Lua */ - XX_httplib_handle_websocket_request( conn, path, 0, NULL, NULL, NULL, NULL, &conn->ctx->callbacks ); + XX_httplib_handle_websocket_request( ctx, conn, path, 0, NULL, NULL, NULL, NULL, &ctx->callbacks ); } - else XX_httplib_send_http_error( conn, 404, "%s", "Not found" ); + else XX_httplib_send_http_error( ctx, conn, 404, "%s", "Not found" ); return; } @@ -391,9 +370,9 @@ no_callback_resource: * by a script file. Thus, a DOCUMENT_ROOT must exist. */ - if ( conn->ctx->document_root == NULL ) { + if ( ctx->document_root == NULL ) { - XX_httplib_send_http_error( conn, 404, "%s", "Not Found" ); + XX_httplib_send_http_error( ctx, conn, 404, "%s", "Not Found" ); return; } @@ -403,7 +382,7 @@ no_callback_resource: if ( is_script_resource ) { - XX_httplib_handle_file_based_request( conn, path, &file ); + XX_httplib_handle_file_based_request( ctx, conn, path, &file ); return; } @@ -413,9 +392,9 @@ no_callback_resource: if ( is_put_or_delete_request ) { - if ( ! strcmp( ri->request_method, "PUT" ) ) { XX_httplib_put_file( conn, path ); return; } - if ( ! strcmp( ri->request_method, "DELETE" ) ) { XX_httplib_delete_file( conn, path ); return; } - if ( ! strcmp( ri->request_method, "MKCOL" ) ) { XX_httplib_mkcol( conn, path ); return; } + if ( ! strcmp( ri->request_method, "PUT" ) ) { XX_httplib_put_file( ctx, conn, path ); return; } + if ( ! strcmp( ri->request_method, "DELETE" ) ) { XX_httplib_delete_file( ctx, conn, path ); return; } + if ( ! strcmp( ri->request_method, "MKCOL" ) ) { XX_httplib_mkcol( ctx, conn, path ); return; } /* * 11.4. PATCH method @@ -423,7 +402,7 @@ no_callback_resource: * only for scripts (Lua, CGI) and callbacks. */ - XX_httplib_send_http_error( conn, 405, "%s method not allowed", conn->request_info.request_method ); + XX_httplib_send_http_error( ctx, conn, 405, "%s method not allowed", conn->request_info.request_method ); return; } @@ -432,9 +411,9 @@ no_callback_resource: * hidden */ - if ( ! is_found || XX_httplib_must_hide_file( conn, path ) ) { + if ( ! is_found || XX_httplib_must_hide_file( ctx, path ) ) { - XX_httplib_send_http_error( conn, 404, "%s", "Not found" ); + XX_httplib_send_http_error( ctx, conn, 404, "%s", "Not found" ); return; } @@ -445,7 +424,7 @@ no_callback_resource: if ( file.is_directory && uri_len > 0 && ri->local_uri[uri_len - 1] != '/' ) { XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - httplib_printf( conn, + httplib_printf( ctx, conn, "HTTP/1.1 301 Moved Permanently\r\n" "Location: %s/\r\n" "Date: %s\r\n" @@ -454,7 +433,7 @@ no_callback_resource: "Connection: %s\r\n\r\n", ri->request_uri, date, - XX_httplib_suggest_connection_header( conn ) ); + XX_httplib_suggest_connection_header( ctx, conn ) ); return; } @@ -465,7 +444,7 @@ no_callback_resource: if ( ! strcmp( ri->request_method, "PROPFIND" ) ) { - XX_httplib_handle_propfind( conn, path, & file ); + XX_httplib_handle_propfind( ctx, conn, path, & file ); return; } @@ -483,7 +462,7 @@ no_callback_resource: * preflights). */ - XX_httplib_send_options( conn ); + XX_httplib_send_options( ctx, conn ); return; } @@ -493,7 +472,7 @@ no_callback_resource: if ( strcmp( ri->request_method, "GET" ) && strcmp( ri->request_method, "HEAD" ) ) { - XX_httplib_send_http_error( conn, 405, "%s method not allowed", conn->request_info.request_method ); + XX_httplib_send_http_error( ctx, conn, 405, "%s method not allowed", conn->request_info.request_method ); return; } @@ -503,7 +482,7 @@ no_callback_resource: if ( file.is_directory ) { - if ( XX_httplib_substitute_index_file( conn, path, sizeof(path), &file ) ) { + if ( XX_httplib_substitute_index_file( ctx, conn, path, sizeof(path), &file ) ) { /* * 14.1. use a substitute file @@ -517,14 +496,14 @@ no_callback_resource: * 14.2. no substitute file */ - if ( conn->ctx->enable_directory_listing ) XX_httplib_handle_directory_request( conn, path ); - else XX_httplib_send_http_error( conn, 403, "%s", "Error: Directory listing denied" ); + if ( ctx->enable_directory_listing ) XX_httplib_handle_directory_request( ctx, conn, path ); + else XX_httplib_send_http_error( ctx, conn, 403, "%s", "Error: Directory listing denied" ); return; } } - XX_httplib_handle_file_based_request( conn, path, &file ); + XX_httplib_handle_file_based_request( ctx, conn, path, &file ); #if 0 /* diff --git a/src/httplib_handle_static_file_request.c b/src/httplib_handle_static_file_request.c index e526f613..1a7a05e0 100644 --- a/src/httplib_handle_static_file_request.c +++ b/src/httplib_handle_static_file_request.c @@ -36,7 +36,7 @@ * request for a static file. */ -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( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep, const char *mime_type, const char *additional_headers ) { char date[64]; char lm[64]; @@ -58,20 +58,20 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con const char *cors2; const char *cors3; - if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return; + if ( ctx == NULL || conn == NULL || filep == NULL ) return; msg = "OK"; curtime = time( NULL ); encoding = ""; - if ( mime_type == NULL ) XX_httplib_get_mime_type( conn->ctx, path, &mime_vec ); + if ( mime_type == NULL ) XX_httplib_get_mime_type( ctx, path, &mime_vec ); else { mime_vec.ptr = mime_type; mime_vec.len = strlen( mime_type ); } - if ( filep->size > INT64_MAX ) XX_httplib_send_http_error( conn, 500, "Error: File size is too large to send\n%" INT64_FMT, filep->size ); + if ( filep->size > INT64_MAX ) XX_httplib_send_http_error( ctx, conn, 500, "Error: File size is too large to send\n%" INT64_FMT, filep->size ); cl = (int64_t)filep->size; conn->status_code = 200; @@ -85,11 +85,11 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con if ( filep->gzipped ) { - XX_httplib_snprintf( conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", path ); + XX_httplib_snprintf( ctx, conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", path ); if ( truncated ) { - XX_httplib_send_http_error( conn, 500, "Error: Path of zipped file too long (%s)", path ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Path of zipped file too long (%s)", path ); return; } @@ -97,13 +97,13 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con encoding = "Content-Encoding: gzip\r\n"; } - if ( ! XX_httplib_fopen( conn, path, "rb", filep ) ) { + if ( ! XX_httplib_fopen( ctx, conn, path, "rb", filep ) ) { - XX_httplib_send_http_error( conn, 500, "Error: Cannot open file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot open file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } - XX_httplib_fclose_on_exec( filep, conn ); + XX_httplib_fclose_on_exec( ctx, filep, conn ); /* * If Range: header specified, act accordingly @@ -122,13 +122,13 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con if ( filep->gzipped ) { - XX_httplib_send_http_error( conn, 501, "%s", "Error: Range requests in gzipped files are not supported"); XX_httplib_fclose(filep); + XX_httplib_send_http_error( ctx, conn, 501, "%s", "Error: Range requests in gzipped files are not supported"); XX_httplib_fclose(filep); return; } conn->status_code = 206; cl = (n == 2) ? (((r2 > cl) ? cl : r2) - r1 + 1) : (cl - r1); - XX_httplib_snprintf( conn, + XX_httplib_snprintf( ctx, conn, NULL, /* range buffer is big enough */ range, sizeof(range), @@ -152,7 +152,7 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con */ cors1 = "Access-Control-Allow-Origin: "; - cors2 = ( conn->ctx->access_control_allow_origin != NULL ) ? conn->ctx->access_control_allow_origin : ""; + cors2 = ( ctx->access_control_allow_origin != NULL ) ? ctx->access_control_allow_origin : ""; cors3 = "\r\n"; } else { @@ -168,11 +168,11 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con XX_httplib_gmt_time_string( date, sizeof(date), & curtime ); XX_httplib_gmt_time_string( lm, sizeof(lm), & filep->last_modified ); - XX_httplib_construct_etag( etag, sizeof(etag), filep ); + XX_httplib_construct_etag( ctx, etag, sizeof(etag), filep ); - httplib_printf( conn, "HTTP/1.1 %d %s\r\n" "%s%s%s" "Date: %s\r\n", conn->status_code, msg, cors1, cors2, cors3, date ); - XX_httplib_send_static_cache_header( conn ); - httplib_printf( conn, + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n" "%s%s%s" "Date: %s\r\n", conn->status_code, msg, cors1, cors2, cors3, date ); + XX_httplib_send_static_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Last-Modified: %s\r\n" "Etag: %s\r\n" "Content-Type: %.*s\r\n" @@ -185,7 +185,7 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con (int)mime_vec.len, mime_vec.ptr, cl, - XX_httplib_suggest_connection_header(conn), + XX_httplib_suggest_connection_header( ctx, conn ), range, encoding ); @@ -194,10 +194,10 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con * sure no one of the additional_headers is included twice */ - if ( additional_headers != NULL ) httplib_printf( conn, "%.*s\r\n\r\n", (int)strlen( additional_headers ), additional_headers ); - else httplib_printf( conn, "\r\n" ); + if ( additional_headers != NULL ) httplib_printf( ctx, conn, "%.*s\r\n\r\n", (int)strlen( additional_headers ), additional_headers ); + else httplib_printf( ctx, conn, "\r\n" ); - if ( strcmp( conn->request_info.request_method, "HEAD" ) != 0 ) XX_httplib_send_file_data( conn, filep, r1, cl ); + if ( strcmp( conn->request_info.request_method, "HEAD" ) != 0 ) XX_httplib_send_file_data( ctx, conn, filep, r1, cl ); XX_httplib_fclose( filep ); diff --git a/src/httplib_handle_websocket_request.c b/src/httplib_handle_websocket_request.c index b88e82a3..4bdac15f 100644 --- a/src/httplib_handle_websocket_request.c +++ b/src/httplib_handle_websocket_request.c @@ -34,7 +34,7 @@ * request on a connection. */ -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( const struct httplib_context *ctx, 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 ) { const char *websock_key; const char *version; @@ -45,7 +45,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const UNUSED_PARAMETER(path); - if ( conn == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; websock_key = httplib_get_header( conn, "Sec-WebSocket-Key" ); version = httplib_get_header( conn, "Sec-WebSocket-Version" ); @@ -77,13 +77,13 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const conn->content_len = 8; - if ( httplib_read( conn, key3, 8 ) == 8 ) { + if ( httplib_read( ctx, conn, key3, 8 ) == 8 ) { /* * This is the hixie version */ - XX_httplib_send_http_error( conn, 426, "%s", "Protocol upgrade to RFC 6455 required" ); + XX_httplib_send_http_error( ctx, conn, 426, "%s", "Protocol upgrade to RFC 6455 required" ); return; } } @@ -92,7 +92,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const * This is an unknown version */ - XX_httplib_send_http_error( conn, 400, "%s", "Malformed websocket request" ); + XX_httplib_send_http_error( ctx, conn, 400, "%s", "Malformed websocket request" ); return; } @@ -107,7 +107,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const * Reject wrong versions */ - XX_httplib_send_http_error( conn, 426, "%s", "Protocol upgrade required" ); + XX_httplib_send_http_error( ctx, conn, 426, "%s", "Protocol upgrade required" ); return; } @@ -149,7 +149,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const * requests to invalid websocket addresses. */ - XX_httplib_send_http_error( conn, 404, "%s", "Not found" ); + XX_httplib_send_http_error( ctx, conn, 404, "%s", "Not found" ); return; } @@ -157,9 +157,9 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const * Step 5: The websocket connection has been accepted */ - if ( ! XX_httplib_send_websocket_handshake( conn, websock_key ) ) { + if ( ! XX_httplib_send_websocket_handshake( ctx, conn, websock_key ) ) { - XX_httplib_send_http_error( conn, 500, "%s", "Websocket handshake failed" ); + XX_httplib_send_http_error( ctx, conn, 500, "%s", "Websocket handshake failed" ); return; } @@ -176,7 +176,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const * Step 7: Enter the read loop */ - if (is_callback_resource) XX_httplib_read_websocket(conn, ws_data_handler, cbData); + if (is_callback_resource) XX_httplib_read_websocket( ctx, conn, ws_data_handler, cbData ); /* * Step 8: Call the close handler diff --git a/src/httplib_interpret_uri.c b/src/httplib_interpret_uri.c index deaa08fd..97a60e49 100644 --- a/src/httplib_interpret_uri.c +++ b/src/httplib_interpret_uri.c @@ -44,7 +44,7 @@ * is_put_or_delete_request: out: put/delete file? */ -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( const struct httplib_context *ctx, 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 ) { /* TODO (high): Restructure this function */ @@ -62,10 +62,10 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, const char *cgi_ext; #endif /* !NO_CGI */ - if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return; + if ( ctx == NULL || conn == NULL || filep == NULL ) return; uri = conn->request_info.local_uri; - root = conn->ctx->document_root; + root = ctx->document_root; memset( filep, 0, sizeof(*filep) ); @@ -76,7 +76,7 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, *is_websocket_request = XX_httplib_is_websocket_protocol( conn ); - if ( *is_websocket_request && conn->ctx->websocket_root != NULL ) root = conn->ctx->websocket_root; + if ( *is_websocket_request && ctx->websocket_root != NULL ) root = ctx->websocket_root; /* * Note that root == NULL is a regular use case here. This occurs, @@ -99,11 +99,11 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, * If document_root is NULL, leave the file empty. */ - XX_httplib_snprintf( conn, &truncated, filename, filename_buf_len - 1, "%s%s", root, uri ); + XX_httplib_snprintf( ctx, conn, &truncated, filename, filename_buf_len - 1, "%s%s", root, uri ); if ( truncated ) goto interpret_cleanup; - rewrite = conn->ctx->url_rewrite_patterns; + rewrite = ctx->url_rewrite_patterns; while ( (rewrite = XX_httplib_next_option( rewrite, &a, &b )) != NULL ) { @@ -111,7 +111,7 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, if ( match_len > 0 ) { - XX_httplib_snprintf( conn, &truncated, filename, filename_buf_len - 1, "%.*s%s", (int)b.len, b.ptr, uri + match_len ); + XX_httplib_snprintf( ctx, conn, &truncated, filename, filename_buf_len - 1, "%.*s%s", (int)b.len, b.ptr, uri + match_len ); break; } } @@ -123,14 +123,14 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, * is now stored in "filename" variable. */ - if ( XX_httplib_stat( conn, filename, filep ) ) { + if ( XX_httplib_stat( ctx, conn, filename, filep ) ) { #if !defined(NO_CGI) /* * File exists. Check if it is a script type. */ - if ( conn->ctx->cgi_pattern != NULL && XX_httplib_match_prefix( conn->ctx->cgi_pattern, strlen( conn->ctx->cgi_pattern ), filename ) > 0 ) { + if ( ctx->cgi_pattern != NULL && XX_httplib_match_prefix( ctx->cgi_pattern, strlen( ctx->cgi_pattern ), filename ) > 0 ) { /* * The request addresses a CGI script or a Lua script. The URI @@ -167,11 +167,11 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, if ( strstr( accept_encoding, "gzip" ) != NULL ) { - XX_httplib_snprintf( conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename ); + XX_httplib_snprintf( ctx, conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename ); if ( truncated ) goto interpret_cleanup; - if ( XX_httplib_stat( conn, gz_path, filep ) ) { + if ( XX_httplib_stat( ctx, conn, gz_path, filep ) ) { if ( filep ) { @@ -199,9 +199,9 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, if ( *p == '/' ) { *p = '\0'; - cgi_ext = conn->ctx->cgi_pattern; + cgi_ext = ctx->cgi_pattern; - if ( cgi_ext != NULL && XX_httplib_match_prefix( cgi_ext, strlen( cgi_ext ), filename ) > 0 && XX_httplib_stat( conn, filename, filep ) ) { + if ( cgi_ext != NULL && XX_httplib_match_prefix( cgi_ext, strlen( cgi_ext ), filename ) > 0 && XX_httplib_stat( ctx, conn, filename, filep ) ) { /* * Shift PATH_INFO block one character right, e.g. diff --git a/src/httplib_is_authorized_for_put.c b/src/httplib_is_authorized_for_put.c index e67fb567..1856643a 100644 --- a/src/httplib_is_authorized_for_put.c +++ b/src/httplib_is_authorized_for_put.c @@ -25,27 +25,27 @@ #include "httplib_main.h" /* - * bool XX_httplib_is_authorized_for_put( struct httplib_connection *conn ); + * bool XX_httplib_is_authorized_for_put( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_is_authorized_for_put() returns true, if the client * on the connection has authorization to use put and equivalent methods to * write information to the server. */ -bool XX_httplib_is_authorized_for_put( struct httplib_connection *conn ) { +bool XX_httplib_is_authorized_for_put( const struct httplib_context *ctx, struct httplib_connection *conn ) { struct file file = STRUCT_FILE_INITIALIZER; const char *passfile; bool ret; - if ( conn == NULL || conn->ctx == NULL ) return false; - if ( conn->ctx->document_root == NULL ) return false; + if ( ctx == NULL || conn == NULL ) return false; + if ( ctx->document_root == NULL ) return false; - passfile = conn->ctx->put_delete_auth_file; + passfile = ctx->put_delete_auth_file; - if ( passfile != NULL && XX_httplib_fopen( conn, passfile, "r", &file ) ) { + if ( passfile != NULL && XX_httplib_fopen( ctx, conn, passfile, "r", &file ) ) { - ret = XX_httplib_authorize( conn, &file ); + ret = XX_httplib_authorize( ctx, conn, &file ); XX_httplib_fclose( & file ); return ret; diff --git a/src/httplib_is_file_in_memory.c b/src/httplib_is_file_in_memory.c index e9ac8f3f..12306d2c 100644 --- a/src/httplib_is_file_in_memory.c +++ b/src/httplib_is_file_in_memory.c @@ -28,23 +28,23 @@ #include "httplib_main.h" /* - * 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_context *ctx, const struct httplib_connection *conn, const char *path, struct file *filep ); * * The function XX_httplib_is_file_in_memory() returns true, if a file defined * by a specific path is located in memory. */ -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_context *ctx, const struct httplib_connection *conn, const char *path, struct file *filep ) { size_t size; - if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return false; + if ( ctx == NULL || conn == NULL || filep == NULL ) return false; size = 0; - if ( conn->ctx->callbacks.open_file ) { + if ( ctx->callbacks.open_file ) { - filep->membuf = conn->ctx->callbacks.open_file( conn, path, & size ); + filep->membuf = ctx->callbacks.open_file( conn, path, & size ); /* NOTE: override filep->size only on success. Otherwise, it might * break constructs like if (!XX_httplib_stat() || !XX_httplib_fopen()) ... */ diff --git a/src/httplib_is_not_modified.c b/src/httplib_is_not_modified.c index 67bd06cd..98e04c34 100644 --- a/src/httplib_is_not_modified.c +++ b/src/httplib_is_not_modified.c @@ -28,21 +28,21 @@ #include "httplib_main.h" /* - * bool XX_httplib_is_not_modified( const struct httplib_connection *conn, const struct file *filep ); + * bool XX_httplib_is_not_modified( const struct httplib_context *ctx, const struct httplib_connection *conn, const struct file *filep ); * * The function XX_httplib_is_not_modified() returns true, if a resource has * not been modified sinze a given datetime and a 304 response should therefore * be sufficient. */ -bool XX_httplib_is_not_modified( const struct httplib_connection *conn, const struct file *filep ) { +bool XX_httplib_is_not_modified( const struct httplib_context *ctx, const struct httplib_connection *conn, const struct file *filep ) { char etag[64]; const char *ims = httplib_get_header( conn, "If-Modified-Since" ); const char *inm = httplib_get_header( conn, "If-None-Match" ); - if ( conn == NULL || filep == NULL ) return false; - XX_httplib_construct_etag( etag, sizeof(etag), filep ); + if ( ctx == NULL || conn == NULL || filep == NULL ) return false; + XX_httplib_construct_etag( ctx, etag, sizeof(etag), filep ); return (inm != NULL && ! httplib_strcasecmp( etag, inm ) ) || (ims != NULL && ( filep->last_modified <= XX_httplib_parse_date_string( ims ) ) ) ; diff --git a/src/httplib_log_access.c b/src/httplib_log_access.c index 610f4b1d..63637c0a 100644 --- a/src/httplib_log_access.c +++ b/src/httplib_log_access.c @@ -32,12 +32,12 @@ static const char *header_val( const struct httplib_connection *conn, const char *header ); /* - * void XX_httplib_log_access( const struct httplib_connection *conn ); + * void XX_httplib_log_access( const struct httplib_context *ctx, const struct httplib_connection *conn ); * * The function XX_httplib_log_access() logs an access of a client. */ -void XX_httplib_log_access( const struct httplib_connection *conn ) { +void XX_httplib_log_access( const struct httplib_context *ctx, const struct httplib_connection *conn ) { const struct httplib_request_info *ri; struct file fi; @@ -48,11 +48,11 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) { const char *user_agent; char buf[4096]; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; - if ( conn->ctx->access_log_file != NULL ) { + if ( ctx->access_log_file != NULL ) { - if ( XX_httplib_fopen( conn, conn->ctx->access_log_file, "a+", &fi ) == 0 ) fi.fp = NULL; + if ( XX_httplib_fopen( ctx, conn, ctx->access_log_file, "a+", &fi ) == 0 ) fi.fp = NULL; } else fi.fp = NULL; @@ -61,7 +61,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) { * executing the rest of the function is pointless. */ - if ( fi.fp == NULL && conn->ctx->callbacks.log_access == NULL ) return; + if ( fi.fp == NULL && ctx->callbacks.log_access == NULL ) return; if ( httplib_localtime_r( &conn->conn_birth_time, &tmm ) != NULL ) strftime( date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", &tmm ); else { @@ -76,7 +76,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) { referer = header_val( conn, "Referer" ); user_agent = header_val( conn, "User-Agent" ); - XX_httplib_snprintf( conn, + XX_httplib_snprintf( ctx, conn, NULL, /* Ignore truncation in access log */ buf, sizeof(buf), @@ -94,7 +94,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) { referer, user_agent ); - if ( conn->ctx->callbacks.log_access != NULL ) conn->ctx->callbacks.log_access( conn, buf ); + if ( ctx->callbacks.log_access != NULL ) ctx->callbacks.log_access( conn, buf ); if ( fi.fp ) { diff --git a/src/httplib_main.h b/src/httplib_main.h index 9c389768..c0fc85ef 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -617,7 +617,6 @@ struct httplib_context { /****************************************************************************************/ struct httplib_connection { /* */ struct httplib_request_info request_info; /* The request info of the connection */ - struct httplib_context *ctx; /* The LibHTTP context of the connection */ SSL * ssl; /* SSL descriptor */ SSL_CTX * client_ssl_ctx; /* SSL context for client connections */ struct socket client; /* Connected client */ @@ -651,6 +650,7 @@ struct worker_thread_args { struct websocket_client_thread_data { + struct httplib_context *ctx; struct httplib_connection *conn; httplib_websocket_data_handler data_handler; httplib_websocket_close_handler close_handler; @@ -788,102 +788,102 @@ 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 ); -bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep ); +bool XX_httplib_authorize( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ); const char * XX_httplib_builtin_mime_ext( int index ); const char * XX_httplib_builtin_mime_type( int index ); int XX_httplib_check_acl( struct httplib_context *ctx, uint32_t remote_ip ); -bool XX_httplib_check_authorization( struct httplib_connection *conn, const char *path ); +bool XX_httplib_check_authorization( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); bool XX_httplib_check_password( const char *method, const char *ha1, const char *uri, const char *nonce, const char *nc, const char *cnonce, const char *qop, const char *response ); void XX_httplib_close_all_listening_sockets( struct httplib_context *ctx ); -void XX_httplib_close_connection( struct httplib_connection *conn ); -void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ); +void XX_httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn ); +void XX_httplib_close_socket_gracefully( const struct httplib_context *ctx, struct httplib_connection *conn ); int WINCDECL XX_httplib_compare_dir_entries( const void *p1, const void *p2 ); bool XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, int port, int use_ssl, SOCKET *sock, union usa *sa ); -void XX_httplib_construct_etag( char *buf, size_t buf_len, const struct file *filep ); +void XX_httplib_construct_etag( const struct httplib_context *ctx, char *buf, size_t buf_len, const struct file *filep ); int XX_httplib_consume_socket( struct httplib_context *ctx, struct socket *sp, int thread_index ); -void XX_httplib_delete_file( struct httplib_connection *conn, const char *path ); -void XX_httplib_dir_scan_callback( struct de *de, void *data ); -void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ); +void XX_httplib_delete_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); +void XX_httplib_dir_scan_callback( const struct httplib_context *ctx, struct de *de, void *data ); +void XX_httplib_discard_unread_request_data( const struct httplib_context *ctx, struct httplib_connection *conn ); int XX_httplib_fclose( struct file *filep ); -void XX_httplib_fclose_on_exec( struct file *filep, struct httplib_connection *conn ); +void XX_httplib_fclose_on_exec( const struct httplib_context *ctx, struct file *filep, struct httplib_connection *conn ); 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_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ); +bool XX_httplib_fopen( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep ); +bool XX_httplib_forward_body_data( const struct httplib_context *ctx, 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 ); 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 ); -const char * XX_httplib_get_rel_url_at_current_server( const char *uri, const struct httplib_connection *conn ); +void XX_httplib_get_mime_type( const struct httplib_context *ctx, const char *path, struct vec *vec ); +const char * XX_httplib_get_rel_url_at_current_server( const struct httplib_context *ctx, const char *uri, const struct httplib_connection *conn ); uint32_t XX_httplib_get_remote_ip( const struct httplib_connection *conn ); -int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler_type, httplib_request_handler *handler, httplib_websocket_connect_handler *connect_handler, httplib_websocket_ready_handler *ready_handler, httplib_websocket_data_handler *data_handler, httplib_websocket_close_handler *close_handler, httplib_authorization_handler *auth_handler, void **cbdata ); +int XX_httplib_get_request_handler( struct httplib_context *ctx, struct httplib_connection *conn, int handler_type, httplib_request_handler *handler, httplib_websocket_connect_handler *connect_handler, httplib_websocket_ready_handler *ready_handler, httplib_websocket_data_handler *data_handler, httplib_websocket_close_handler *close_handler, httplib_authorization_handler *auth_handler, void **cbdata ); int XX_httplib_get_request_len( const char *buf, int buflen ); void XX_httplib_get_system_name( char **sysName ); enum uri_type_t XX_httplib_get_uri_type( const char *uri ); -bool XX_httplib_getreq( struct httplib_context *ctx, struct httplib_connection *conn, int *err ); -void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char *prog ); -void XX_httplib_handle_directory_request( struct httplib_connection *conn, const char *dir ); -void XX_httplib_handle_file_based_request( struct httplib_connection *conn, const char *path, struct file *filep ); -void XX_httplib_handle_not_modified_static_file_request( struct httplib_connection *conn, struct file *filep ); -void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *path, struct file *filep ); -void XX_httplib_handle_request( struct httplib_connection *conn ); -void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const char *path, struct file *filep ); -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 ); +bool XX_httplib_getreq( const struct httplib_context *ctx, struct httplib_connection *conn, int *err ); +void XX_httplib_handle_cgi_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog ); +void XX_httplib_handle_directory_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir ); +void XX_httplib_handle_file_based_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); +void XX_httplib_handle_not_modified_static_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep ); +void XX_httplib_handle_propfind( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); +void XX_httplib_handle_request( struct httplib_context *ctx, struct httplib_connection *conn ); +void XX_httplib_handle_ssi_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); +void XX_httplib_handle_static_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep, const char *mime_type, const char *additional_headers ); +void XX_httplib_handle_websocket_request( const struct httplib_context *ctx, 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_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 ); -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 ); +void XX_httplib_interpret_uri( const struct httplib_context *ctx, 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( const struct httplib_context *ctx, struct httplib_connection *conn ); +bool XX_httplib_is_file_in_memory( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path, struct file *filep ); bool XX_httplib_is_file_opened( const struct file *filep ); -bool XX_httplib_is_not_modified( const struct httplib_connection *conn, const struct file *filep ); +bool XX_httplib_is_not_modified( const struct httplib_context *ctx, const struct httplib_connection *conn, const struct file *filep ); bool XX_httplib_is_put_or_delete_method( const struct httplib_connection *conn ); bool XX_httplib_is_valid_http_method( const char *method ); int XX_httplib_is_valid_port( unsigned long port ); bool XX_httplib_is_websocket_protocol( const struct httplib_connection *conn ); void * XX_httplib_load_dll( struct httplib_context *ctx, const char *dll_name, struct ssl_func *sw ); -void XX_httplib_log_access( const struct httplib_connection *conn ); +void XX_httplib_log_access( const struct httplib_context *ctx, const struct httplib_connection *conn ); LIBHTTP_THREAD XX_httplib_master_thread( void *thread_func_param ); int XX_httplib_match_prefix(const char *pattern, size_t pattern_len, const char *str); -void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ); -bool XX_httplib_must_hide_file( struct httplib_connection *conn, const char *path ); +void XX_httplib_mkcol( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); +bool XX_httplib_must_hide_file( const struct httplib_context *ctx, const char *path ); const char * XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val ); -void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *path, struct file *filep ); +void XX_httplib_open_auth_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); bool XX_httplib_option_value_to_bool( const char *value, bool *config ); bool XX_httplib_option_value_to_int( const char *value, int *config ); -int XX_httplib_parse_auth_header( struct httplib_connection *conn, char *buf, size_t buf_size, struct ah *ah ); +int XX_httplib_parse_auth_header( const struct httplib_context *ctx, struct httplib_connection *conn, char *buf, size_t buf_size, struct ah *ah ); time_t XX_httplib_parse_date_string( const char *datetime ); int XX_httplib_parse_http_headers( char **buf, struct httplib_request_info *ri ); int XX_httplib_parse_http_message( char *buf, int len, struct httplib_request_info *ri ); int XX_httplib_parse_net( const char *spec, uint32_t *net, uint32_t *mask ); int XX_httplib_parse_range_header( const char *header, int64_t *a, int64_t *b ); void XX_httplib_path_to_unicode( const char *path, wchar_t *wbuf, size_t wbuf_len ); -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_process_new_connection( struct httplib_connection *conn ); +void XX_httplib_prepare_cgi_environment( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, struct cgi_environment *env ); +void XX_httplib_print_dir_entry( const struct httplib_context *ctx, struct de *de ); +void XX_httplib_process_new_connection( struct httplib_context *ctx, 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 ); -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 ); -int64_t XX_httplib_push_all( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ); -int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ); -void XX_httplib_put_file( struct httplib_connection *conn, const char *path ); -bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct *workdata ); -int XX_httplib_read_request( FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ); -void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *callback_data ); -void XX_httplib_redirect_to_https_port( struct httplib_connection *conn, int ssl_index ); -int XX_httplib_refresh_trust( struct httplib_connection *conn ); -void XX_httplib_remove_bad_file( const struct httplib_connection *conn, const char *path ); -int XX_httplib_remove_directory( struct httplib_connection *conn, const char *dir ); +int XX_httplib_pull( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout ); +int XX_httplib_pull_all( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int len ); +int64_t XX_httplib_push_all( const struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ); +int XX_httplib_put_dir( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); +void XX_httplib_put_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); +bool XX_httplib_read_auth_file( const struct httplib_context *ctx, struct file *filep, struct read_auth_file_struct *workdata ); +int XX_httplib_read_request( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ); +void XX_httplib_read_websocket( const struct httplib_context *ctx, struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *callback_data ); +void XX_httplib_redirect_to_https_port( const struct httplib_context *ctx, struct httplib_connection *conn, int ssl_index ); +int XX_httplib_refresh_trust( const struct httplib_context *ctx, struct httplib_connection *conn ); +void XX_httplib_remove_bad_file( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path ); +int XX_httplib_remove_directory( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir ); void XX_httplib_remove_double_dots_and_double_slashes( char *s ); void XX_httplib_reset_per_request_attributes( struct httplib_connection *conn ); -int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, void *data, void (*cb)(struct de *, void *) ); -void XX_httplib_send_authorization_request( struct httplib_connection *conn ); -void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *filep, int64_t offset, int64_t len ); -void XX_httplib_send_http_error( struct httplib_connection *, int, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(3, 4); -int XX_httplib_send_no_cache_header( struct httplib_connection *conn ); -void XX_httplib_send_options( struct httplib_connection *conn ); -int XX_httplib_send_static_cache_header( struct httplib_connection *conn ); -int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const char *websock_key ); +int XX_httplib_scan_directory( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir, void *data, void (*cb)(const struct httplib_context *ctx, struct de *, void *) ); +void XX_httplib_send_authorization_request( struct httplib_context *ctx, struct httplib_connection *conn ); +void XX_httplib_send_file_data( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep, int64_t offset, int64_t len ); +void XX_httplib_send_http_error( const struct httplib_context *ctx, struct httplib_connection *, int, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(4, 5); +int XX_httplib_send_no_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn ); +void XX_httplib_send_options( const struct httplib_context *ctx, struct httplib_connection *conn ); +int XX_httplib_send_static_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn ); +int XX_httplib_send_websocket_handshake( const struct httplib_context *ctx, struct httplib_connection *conn, const char *websock_key ); int XX_httplib_set_acl_option( struct httplib_context *ctx ); void XX_httplib_set_close_on_exec( SOCKET sock ); bool XX_httplib_set_gpass_option( struct httplib_context *ctx ); @@ -892,21 +892,21 @@ int XX_httplib_set_non_blocking_mode( SOCKET sock ); int XX_httplib_set_ports_option( struct httplib_context *ctx ); int XX_httplib_set_sock_timeout( SOCKET sock, int milliseconds ); int XX_httplib_set_tcp_nodelay( SOCKET sock, bool nodelay_on ); -void XX_httplib_set_thread_name( const char *name ); +void XX_httplib_set_thread_name( const struct httplib_context *ctx, const char *name ); int XX_httplib_set_throttle( const char *spec, uint32_t remote_ip, const char *uri ); bool XX_httplib_set_uid_option( struct httplib_context *ctx ); -bool XX_httplib_should_decode_url( const struct httplib_connection *conn ); -bool XX_httplib_should_keep_alive( const struct httplib_connection *conn ); +bool XX_httplib_should_decode_url( const struct httplib_context *ctx ); +bool XX_httplib_should_keep_alive( const struct httplib_context *ctx, const struct httplib_connection *conn ); char * XX_httplib_skip( char **buf, const char *delimiters ); char * XX_httplib_skip_quoted( char **buf, const char *delimiters, const char *whitespace, char quotechar ); void XX_httplib_sockaddr_to_string(char *buf, size_t len, const union usa *usa ); -pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ); +pid_t XX_httplib_spawn_process( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ); int XX_httplib_start_thread_with_id( httplib_thread_func_t func, void *param, pthread_t *threadidptr ); -int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct file *filep ); -int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ); -const char * XX_httplib_suggest_connection_header( const struct httplib_connection *conn ); +int XX_httplib_stat( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ); +int XX_httplib_substitute_index_file( const struct httplib_context *ctx, struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ); +const char * XX_httplib_suggest_connection_header( const struct httplib_context *ctx, const struct httplib_connection *conn ); LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ); -int XX_httplib_websocket_write_exec( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen, uint32_t masking_key ); +int XX_httplib_websocket_write_exec( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t dataLen, uint32_t masking_key ); LIBHTTP_THREAD XX_httplib_worker_thread( void *thread_func_param ); diff --git a/src/httplib_master_thread.c b/src/httplib_master_thread.c index c64ffa36..75e3979c 100644 --- a/src/httplib_master_thread.c +++ b/src/httplib_master_thread.c @@ -65,7 +65,7 @@ static void master_thread_run(void *thread_func_param) { if ( ctx == NULL ) return; - XX_httplib_set_thread_name( "master" ); + XX_httplib_set_thread_name( ctx, "master" ); /* * Increase priority of the master thread diff --git a/src/httplib_mkcol.c b/src/httplib_mkcol.c index 563ca463..dee163c1 100644 --- a/src/httplib_mkcol.c +++ b/src/httplib_mkcol.c @@ -29,14 +29,14 @@ #include "httplib_utils.h" /* - * void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ); + * void XX_httplib_mkcol( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); * * The function XX_httplib_mkcol() handles a MKCOL command from a remote * client. The MKCOL method is used to create a new collection resource at the * location specificied by the request URI. */ -void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { +void XX_httplib_mkcol( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { int rc; int body_len; @@ -45,8 +45,8 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { time_t curtime; char error_string[ERROR_STRING_LEN]; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; + if ( ctx->document_root == NULL ) return; curtime = time( NULL ); @@ -56,9 +56,9 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { memset( & de.file, 0, sizeof(de.file) ); - if ( ! XX_httplib_stat( conn, path, & de.file ) ) { + if ( ! XX_httplib_stat( ctx, conn, path, & de.file ) ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } if ( de.file.last_modified ) { @@ -67,7 +67,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { * TODO (high): This check does not seem to make any sense ! */ - XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -75,7 +75,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { if ( body_len > 0 ) { - XX_httplib_send_http_error( conn, 415, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 415, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -85,17 +85,17 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) { conn->status_code = 201; XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - httplib_printf( conn, "HTTP/1.1 %d Created\r\n" "Date: %s\r\n", conn->status_code, date ); - XX_httplib_send_static_cache_header( conn ); - httplib_printf( conn, "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", XX_httplib_suggest_connection_header(conn) ); + httplib_printf( ctx, conn, "HTTP/1.1 %d Created\r\n" "Date: %s\r\n", conn->status_code, date ); + XX_httplib_send_static_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", XX_httplib_suggest_connection_header( ctx, conn ) ); } else if ( rc == -1 ) { - if ( errno == EEXIST ) XX_httplib_send_http_error( conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else if ( errno == EACCES ) XX_httplib_send_http_error( conn, 403, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else if ( errno == ENOENT ) XX_httplib_send_http_error( conn, 409, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else XX_httplib_send_http_error( conn, 500, "fopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + if ( errno == EEXIST ) XX_httplib_send_http_error( ctx, conn, 405, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( errno == EACCES ) XX_httplib_send_http_error( ctx, conn, 403, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( errno == ENOENT ) XX_httplib_send_http_error( ctx, conn, 409, "Error: mkcol(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else XX_httplib_send_http_error( ctx, conn, 500, "fopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } /* XX_httplib_mkcol */ diff --git a/src/httplib_must_hide_file.c b/src/httplib_must_hide_file.c index b7edadd7..681a4711 100644 --- a/src/httplib_must_hide_file.c +++ b/src/httplib_must_hide_file.c @@ -28,7 +28,7 @@ #include "httplib_main.h" /* - * bool XX_httplib_must_hide_file( struct httplib_connection *conn, const char *path ); + * bool XX_httplib_must_hide_file( const struct httplib_context *ctx, const char *path ); * * The function XX_httplib_must_hide_file() returns true, if a file must be * hidden from browsing by the remote client. A used provided list of file @@ -36,15 +36,15 @@ * the patterns defined by the user. */ -bool XX_httplib_must_hide_file( struct httplib_connection *conn, const char *path ) { +bool XX_httplib_must_hide_file( const struct httplib_context *ctx, const char *path ) { const char *pw_pattern; const char *pattern; - if ( conn == NULL || conn->ctx == NULL ) return false; + if ( ctx == NULL ) return false; pw_pattern = "**" PASSWORDS_FILE_NAME "$"; - pattern = conn->ctx->hide_file_pattern; + pattern = ctx->hide_file_pattern; return ( pw_pattern != NULL && XX_httplib_match_prefix( pw_pattern, strlen( pw_pattern ), path ) > 0 ) || ( pattern != NULL && XX_httplib_match_prefix( pattern, strlen( pattern ), path ) > 0 ); diff --git a/src/httplib_open_auth_file.c b/src/httplib_open_auth_file.c index e84c012e..7c43f0a2 100644 --- a/src/httplib_open_auth_file.c +++ b/src/httplib_open_auth_file.c @@ -33,7 +33,7 @@ * or search for .htpasswd in the requested directory. */ -void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *path, struct file *filep ) { +void XX_httplib_open_auth_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ) { char name[PATH_MAX]; char error_string[ERROR_STRING_LEN]; @@ -43,9 +43,9 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat struct file file = STRUCT_FILE_INITIALIZER; bool truncated; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; - gpass = conn->ctx->global_auth_file; + gpass = ctx->global_auth_file; if ( gpass != NULL ) { @@ -53,9 +53,9 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat * Use global passwords file */ - if ( ! XX_httplib_fopen( conn, gpass, "r", filep ) ) { + if ( ! XX_httplib_fopen( ctx, conn, gpass, "r", filep ) ) { - httplib_cry( DEBUG_LEVEL_INFO, conn->ctx, conn, "%s: fopen(%s): %s", __func__, gpass, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_INFO, ctx, conn, "%s: fopen(%s): %s", __func__, gpass, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } /* * Important: using local struct file to test path for is_directory @@ -65,13 +65,13 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat } - else if ( XX_httplib_stat( conn, path, &file ) && file.is_directory ) { + else if ( XX_httplib_stat( ctx, conn, path, &file ) && file.is_directory ) { - XX_httplib_snprintf( conn, &truncated, name, sizeof(name), "%s/%s", path, PASSWORDS_FILE_NAME ); + XX_httplib_snprintf( ctx, conn, &truncated, name, sizeof(name), "%s/%s", path, PASSWORDS_FILE_NAME ); - if ( truncated || ! XX_httplib_fopen( conn, name, "r", filep ) ) { + if ( truncated || ! XX_httplib_fopen( ctx, conn, name, "r", filep ) ) { - httplib_cry( DEBUG_LEVEL_INFO, conn->ctx, conn, "%s: fopen(%s): %s", __func__, name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_INFO, ctx, conn, "%s: fopen(%s): %s", __func__, name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } @@ -84,11 +84,11 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat if (e[0] == '/') break; } - XX_httplib_snprintf( conn, &truncated, name, sizeof(name), "%.*s/%s", (int)(e - p), p, PASSWORDS_FILE_NAME ); + XX_httplib_snprintf( ctx, conn, &truncated, name, sizeof(name), "%.*s/%s", (int)(e - p), p, PASSWORDS_FILE_NAME ); - if ( truncated || ! XX_httplib_fopen( conn, name, "r", filep ) ) { + if ( truncated || ! XX_httplib_fopen( ctx, conn, name, "r", filep ) ) { - httplib_cry( DEBUG_LEVEL_INFO, conn->ctx, conn, "%s: fopen(%s): %s", __func__, name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_INFO, ctx, conn, "%s: fopen(%s): %s", __func__, name, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_parse_auth_header.c b/src/httplib_parse_auth_header.c index 778493cb..e6eae983 100644 --- a/src/httplib_parse_auth_header.c +++ b/src/httplib_parse_auth_header.c @@ -32,7 +32,7 @@ * Return 1 on success. Always initializes the ah structure. */ -int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, size_t buf_size, struct ah *ah) { +int XX_httplib_parse_auth_header( const struct httplib_context *ctx, struct httplib_connection *conn, char *buf, size_t buf_size, struct ah *ah ) { char *name; char *value; @@ -40,7 +40,7 @@ int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, siz const char *auth_header; uint64_t nonce; - if ( ah == NULL || conn == NULL ) return 0; + if ( ctx == NULL || ah == NULL || conn == NULL ) return 0; memset( ah, 0, sizeof(*ah) ); if ( (auth_header = httplib_get_header( conn, "Authorization" )) == NULL || httplib_strncasecmp( auth_header, "Digest ", 7 ) != 0 ) return 0; @@ -103,7 +103,7 @@ int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, siz * Convert the nonce from the client to a number. */ - nonce ^= conn->ctx->auth_nonce_mask; + nonce ^= ctx->auth_nonce_mask; /* * The converted number corresponds to the time the nounce has been @@ -116,7 +116,7 @@ int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, siz * two restarts, a new login is required. */ - if ( nonce < (uint64_t)conn->ctx->start_time ) { + if ( nonce < (uint64_t)ctx->start_time ) { /* * nonce is from a previous start of the server and no longer valid @@ -130,7 +130,7 @@ int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, siz * server. */ - if ( nonce >= ( (uint64_t)conn->ctx->start_time + conn->ctx->nonce_count ) ) return 0; + if ( nonce >= ( (uint64_t)ctx->start_time + ctx->nonce_count ) ) return 0; /* * CGI needs it as REMOTE_USER diff --git a/src/httplib_path_to_unicode.c b/src/httplib_path_to_unicode.c index 4d25160c..f77c61e3 100644 --- a/src/httplib_path_to_unicode.c +++ b/src/httplib_path_to_unicode.c @@ -104,8 +104,8 @@ void XX_httplib_path_to_unicode( const char *path, wchar_t *wbuf, size_t wbuf_le */ /* - if (conn) { - if (conn->ctx->config[WINDOWS_CASE_SENSITIVE]) { + if ( ctx != NULL ) { + if (ctx->config[WINDOWS_CASE_SENSITIVE]) { fcompare = wcscmp; } } diff --git a/src/httplib_prepare_cgi_environment.c b/src/httplib_prepare_cgi_environment.c index 58c1eb13..57d13cab 100644 --- a/src/httplib_prepare_cgi_environment.c +++ b/src/httplib_prepare_cgi_environment.c @@ -31,7 +31,7 @@ #include "httplib_utils.h" /* - * void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const char *prog, struct cgi_environment *env ); + * void XX_httplib_prepare_cgi_environment( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, struct cgi_environment *env ); * * The function XX_httplib_prepare_cgi_environment() is used to prepare all * environment variables before a CGI script is called. @@ -39,7 +39,7 @@ #if !defined(NO_CGI) -void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const char *prog, struct cgi_environment *env ) { +void XX_httplib_prepare_cgi_environment( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, struct cgi_environment *env ) { const char *s; struct vec var_vec; @@ -49,7 +49,7 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const int i; bool truncated; - if ( conn == NULL || conn->ctx == NULL || prog == NULL || env == NULL || conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL || prog == NULL || env == NULL || ctx->document_root == NULL ) return; env->conn = conn; env->buflen = CGI_ENVIRONMENT_SIZE; @@ -59,48 +59,48 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const env->varused = 0; env->var = httplib_malloc( env->buflen * sizeof(char *) ); - if ( conn->ctx->authentication_domain != NULL ) XX_httplib_addenv( env, "SERVER_NAME=%s", conn->ctx->authentication_domain ); - XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->document_root ); - XX_httplib_addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->document_root ); - XX_httplib_addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() ); + if ( ctx->authentication_domain != NULL ) XX_httplib_addenv( ctx, env, "SERVER_NAME=%s", ctx->authentication_domain ); + XX_httplib_addenv( ctx, env, "SERVER_ROOT=%s", ctx->document_root ); + XX_httplib_addenv( ctx, env, "DOCUMENT_ROOT=%s", ctx->document_root ); + XX_httplib_addenv( ctx, env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() ); /* * Prepare the environment block */ - XX_httplib_addenv( env, "%s", "GATEWAY_INTERFACE=CGI/1.1" ); - XX_httplib_addenv( env, "%s", "SERVER_PROTOCOL=HTTP/1.1" ); - XX_httplib_addenv( env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */ + XX_httplib_addenv( ctx, env, "%s", "GATEWAY_INTERFACE=CGI/1.1" ); + XX_httplib_addenv( ctx, env, "%s", "SERVER_PROTOCOL=HTTP/1.1" ); + XX_httplib_addenv( ctx, env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */ - if ( conn->client.lsa.sa.sa_family == AF_INET6 ) XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin6.sin6_port ) ); - else XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin.sin_port ) ); + if ( conn->client.lsa.sa.sa_family == AF_INET6 ) XX_httplib_addenv( ctx, env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin6.sin6_port ) ); + else XX_httplib_addenv( ctx, env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin.sin_port ) ); XX_httplib_sockaddr_to_string( src_addr, sizeof(src_addr), &conn->client.rsa ); - XX_httplib_addenv( env, "REMOTE_ADDR=%s", src_addr ); - XX_httplib_addenv( env, "REQUEST_METHOD=%s", conn->request_info.request_method ); - XX_httplib_addenv( env, "REMOTE_PORT=%d", conn->request_info.remote_port ); - XX_httplib_addenv( env, "REQUEST_URI=%s", conn->request_info.request_uri ); - XX_httplib_addenv( env, "LOCAL_URI=%s", conn->request_info.local_uri ); + XX_httplib_addenv( ctx, env, "REMOTE_ADDR=%s", src_addr ); + XX_httplib_addenv( ctx, env, "REQUEST_METHOD=%s", conn->request_info.request_method ); + XX_httplib_addenv( ctx, env, "REMOTE_PORT=%d", conn->request_info.remote_port ); + XX_httplib_addenv( ctx, env, "REQUEST_URI=%s", conn->request_info.request_uri ); + XX_httplib_addenv( ctx, env, "LOCAL_URI=%s", conn->request_info.local_uri ); /* * SCRIPT_NAME */ - XX_httplib_addenv( env, "SCRIPT_NAME=%.*s", (int)strlen(conn->request_info.local_uri) - ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)), conn->request_info.local_uri); + XX_httplib_addenv( ctx, env, "SCRIPT_NAME=%.*s", (int)strlen(conn->request_info.local_uri) - ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)), conn->request_info.local_uri); - XX_httplib_addenv( env, "SCRIPT_FILENAME=%s", prog ); + XX_httplib_addenv( ctx, env, "SCRIPT_FILENAME=%s", prog ); - if ( conn->path_info == NULL ) XX_httplib_addenv( env, "PATH_TRANSLATED=%s", conn->ctx->document_root ); - else XX_httplib_addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->document_root, conn->path_info ); + if ( conn->path_info == NULL ) XX_httplib_addenv( ctx, env, "PATH_TRANSLATED=%s", ctx->document_root ); + else XX_httplib_addenv( ctx, env, "PATH_TRANSLATED=%s%s", ctx->document_root, conn->path_info ); - XX_httplib_addenv( env, "HTTPS=%s", (conn->ssl == NULL) ? "off" : "on" ); + XX_httplib_addenv( ctx, env, "HTTPS=%s", (conn->ssl == NULL) ? "off" : "on" ); - if ( (s = httplib_get_header( conn, "Content-Type" ) ) != NULL ) XX_httplib_addenv( env, "CONTENT_TYPE=%s", s ); - if ( conn->request_info.query_string != NULL ) XX_httplib_addenv( env, "QUERY_STRING=%s", conn->request_info.query_string ); - if ( (s = httplib_get_header( conn, "Content-Length" ) ) != NULL ) XX_httplib_addenv( env, "CONTENT_LENGTH=%s", s ); - if ( (s = getenv( "PATH" )) != NULL ) XX_httplib_addenv( env, "PATH=%s", s ); - if ( conn->path_info != NULL ) XX_httplib_addenv( env, "PATH_INFO=%s", conn->path_info ); + if ( (s = httplib_get_header( conn, "Content-Type" ) ) != NULL ) XX_httplib_addenv( ctx, env, "CONTENT_TYPE=%s", s ); + if ( conn->request_info.query_string != NULL ) XX_httplib_addenv( ctx, env, "QUERY_STRING=%s", conn->request_info.query_string ); + if ( (s = httplib_get_header( conn, "Content-Length" ) ) != NULL ) XX_httplib_addenv( ctx, env, "CONTENT_LENGTH=%s", s ); + if ( (s = getenv( "PATH" )) != NULL ) XX_httplib_addenv( ctx, env, "PATH=%s", s ); + if ( conn->path_info != NULL ) XX_httplib_addenv( ctx, env, "PATH_INFO=%s", conn->path_info ); if (conn->status_code > 0) { @@ -108,25 +108,25 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const * CGI error handler should show the status code */ - XX_httplib_addenv( env, "STATUS=%d", conn->status_code ); + XX_httplib_addenv( ctx, env, "STATUS=%d", conn->status_code ); } #if defined(_WIN32) - if ( (s = getenv( "COMSPEC" )) != NULL ) XX_httplib_addenv( env, "COMSPEC=%s", s ); - if ( (s = getenv( "SYSTEMROOT" )) != NULL ) XX_httplib_addenv( env, "SYSTEMROOT=%s", s ); - if ( (s = getenv( "SystemDrive" )) != NULL ) XX_httplib_addenv( env, "SystemDrive=%s", s ); - if ( (s = getenv( "ProgramFiles" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles=%s", s ); - if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles(x86)=%s", s ); + if ( (s = getenv( "COMSPEC" )) != NULL ) XX_httplib_addenv( ctx, env, "COMSPEC=%s", s ); + if ( (s = getenv( "SYSTEMROOT" )) != NULL ) XX_httplib_addenv( ctx, env, "SYSTEMROOT=%s", s ); + if ( (s = getenv( "SystemDrive" )) != NULL ) XX_httplib_addenv( ctx, env, "SystemDrive=%s", s ); + if ( (s = getenv( "ProgramFiles" )) != NULL ) XX_httplib_addenv( ctx, env, "ProgramFiles=%s", s ); + if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) XX_httplib_addenv( ctx, env, "ProgramFiles(x86)=%s", s ); #else - if ( (s = getenv("LD_LIBRARY_PATH" )) != NULL ) XX_httplib_addenv( env, "LD_LIBRARY_PATH=%s", s ); + if ( (s = getenv("LD_LIBRARY_PATH" )) != NULL ) XX_httplib_addenv( ctx, env, "LD_LIBRARY_PATH=%s", s ); #endif /* _WIN32 */ - if ( (s = getenv("PERLLIB" )) != NULL ) XX_httplib_addenv( env, "PERLLIB=%s", s ); + if ( (s = getenv("PERLLIB" )) != NULL ) XX_httplib_addenv( ctx, env, "PERLLIB=%s", s ); if (conn->request_info.remote_user != NULL) { - XX_httplib_addenv( env, "REMOTE_USER=%s", conn->request_info.remote_user ); - XX_httplib_addenv( env, "%s", "AUTH_TYPE=Digest" ); + XX_httplib_addenv( ctx, env, "REMOTE_USER=%s", conn->request_info.remote_user ); + XX_httplib_addenv( ctx, env, "%s", "AUTH_TYPE=Digest" ); } /* @@ -135,10 +135,10 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const for (i=0; irequest_info.num_headers; i++) { - XX_httplib_snprintf( conn, &truncated, http_var_name, sizeof(http_var_name), "HTTP_%s", conn->request_info.http_headers[i].name ); + XX_httplib_snprintf( ctx, conn, &truncated, http_var_name, sizeof(http_var_name), "HTTP_%s", conn->request_info.http_headers[i].name ); if ( truncated ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: HTTP header variable too long [%s]", __func__, conn->request_info.http_headers[i].name ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: HTTP header variable too long [%s]", __func__, conn->request_info.http_headers[i].name ); continue; } @@ -152,18 +152,18 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const *p = (char)toupper(*(unsigned char *)p); } - XX_httplib_addenv( env, "%s=%s", http_var_name, conn->request_info.http_headers[i].value ); + XX_httplib_addenv( ctx, env, "%s=%s", http_var_name, conn->request_info.http_headers[i].value ); } /* * Add user-specified variables */ - s = conn->ctx->cgi_environment; + s = ctx->cgi_environment; while ( (s = XX_httplib_next_option( s, &var_vec, NULL )) != NULL ) { - XX_httplib_addenv( env, "%.*s", (int)var_vec.len, var_vec.ptr ); + XX_httplib_addenv( ctx, env, "%.*s", (int)var_vec.len, var_vec.ptr ); } env->var[env->varused] = NULL; diff --git a/src/httplib_print_dir_entry.c b/src/httplib_print_dir_entry.c index 5146e728..2af6e190 100644 --- a/src/httplib_print_dir_entry.c +++ b/src/httplib_print_dir_entry.c @@ -28,24 +28,26 @@ #include "httplib_main.h" #include "httplib_string.h" -void XX_httplib_print_dir_entry( struct de *de ) { +void XX_httplib_print_dir_entry( const struct httplib_context *ctx, struct de *de ) { char size[64]; char mod[64]; char href[PATH_MAX * 3 /* worst case */]; struct tm tmm; - if ( de->file.is_directory ) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%s", "[DIRECTORY]" ); + if ( ctx == NULL ) return; + + if ( de->file.is_directory ) XX_httplib_snprintf( ctx, de->conn, NULL, size, sizeof(size), "%s", "[DIRECTORY]" ); else { /* * We use (signed) cast below because MSVC 6 compiler cannot * convert unsigned __int64 to double. Sigh. */ - if ( de->file.size < 1024) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%d", (int) de->file.size ); - else if ( de->file.size < 0x100000 ) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%.1fk", ((double)de->file.size) / 1024.0 ); - else if ( de->file.size < 0x40000000 ) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%.1fM", ((double)de->file.size) / 1048576.0 ); - else XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%.1fG", ((double)de->file.size) / 1073741824.0 ); + if ( de->file.size < 1024) XX_httplib_snprintf( ctx, de->conn, NULL, size, sizeof(size), "%d", (int) de->file.size ); + else if ( de->file.size < 0x100000 ) XX_httplib_snprintf( ctx, de->conn, NULL, size, sizeof(size), "%.1fk", ((double)de->file.size) / 1024.0 ); + else if ( de->file.size < 0x40000000 ) XX_httplib_snprintf( ctx, de->conn, NULL, size, sizeof(size), "%.1fM", ((double)de->file.size) / 1048576.0 ); + else XX_httplib_snprintf( ctx, de->conn, NULL, size, sizeof(size), "%.1fG", ((double)de->file.size) / 1073741824.0 ); } /* @@ -61,7 +63,7 @@ void XX_httplib_print_dir_entry( struct de *de ) { } httplib_url_encode( de->file_name, href, sizeof(href) ); - de->conn->num_bytes_sent += httplib_printf( de->conn, + de->conn->num_bytes_sent += httplib_printf( ctx, de->conn, "%s%s" " %s  %s\n", de->conn->request_info.local_uri, diff --git a/src/httplib_printf.c b/src/httplib_printf.c index 19117fb2..658e02c3 100644 --- a/src/httplib_printf.c +++ b/src/httplib_printf.c @@ -28,13 +28,13 @@ #include "httplib_main.h" #include "httplib_string.h" -int httplib_printf( struct httplib_connection *conn, const char *fmt, ... ) { +int httplib_printf( const struct httplib_context *ctx, struct httplib_connection *conn, const char *fmt, ... ) { va_list ap; int result; va_start( ap, fmt ); - result = XX_httplib_vprintf( conn, fmt, ap ); + result = XX_httplib_vprintf( ctx, conn, fmt, ap ); va_end( ap ); return result; diff --git a/src/httplib_process_new_connection.c b/src/httplib_process_new_connection.c index 42363d57..32b10742 100644 --- a/src/httplib_process_new_connection.c +++ b/src/httplib_process_new_connection.c @@ -29,13 +29,13 @@ #include "httplib_string.h" /* - * void XX_httplib_process_new_connection( struct httplib_connection *conn ); + * void XX_httplib_process_new_connection( struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_process_new_connection() is used to process a new * incoming connection on a socket. */ -void XX_httplib_process_new_connection( struct httplib_connection *conn ) { +void XX_httplib_process_new_connection( struct httplib_context *ctx, struct httplib_connection *conn ) { struct httplib_request_info *ri; int keep_alive; @@ -49,7 +49,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { void * var; } ptr; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; ri = & conn->request_info; @@ -62,7 +62,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { was_error = false; do { - if ( ! XX_httplib_getreq( conn->ctx, conn, &reqerr ) ) { + if ( ! XX_httplib_getreq( ctx, conn, &reqerr ) ) { /* * The request sent by the client could not be understood by @@ -70,15 +70,15 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { * error message and close the connection. */ - if ( reqerr > 0 ) XX_httplib_send_http_error( conn, reqerr, "%s", httplib_get_response_code_text( conn, reqerr ) ); + if ( reqerr > 0 ) XX_httplib_send_http_error( ctx, conn, reqerr, "%s", httplib_get_response_code_text( ctx, conn, reqerr ) ); was_error = true; } else if ( strcmp( ri->http_version, "1.0" ) && strcmp( ri->http_version, "1.1" ) ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: bad HTTP version \"%s\"", __func__, ri->http_version ); - XX_httplib_send_http_error( conn, 505, "%s", httplib_get_response_code_text( conn, 505 ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: bad HTTP version \"%s\"", __func__, ri->http_version ); + XX_httplib_send_http_error( ctx, conn, 505, "%s", httplib_get_response_code_text( ctx, conn, 505 ) ); was_error = true; } @@ -102,15 +102,15 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { case URI_TYPE_ABS_NOPORT : case URI_TYPE_ABS_PORT : - hostend = XX_httplib_get_rel_url_at_current_server( conn->request_info.request_uri, conn ); + hostend = XX_httplib_get_rel_url_at_current_server( ctx, conn->request_info.request_uri, conn ); if ( hostend != NULL ) conn->request_info.local_uri = hostend; else conn->request_info.local_uri = NULL; break; default : - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: invalid URI", __func__ ); - XX_httplib_send_http_error( conn, 400, "%s", httplib_get_response_code_text( conn, 400 ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: invalid URI", __func__ ); + XX_httplib_send_http_error( ctx, conn, 400, "%s", httplib_get_response_code_text( ctx, conn, 400 ) ); conn->request_info.local_uri = NULL; was_error = true; @@ -131,9 +131,9 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { * handle request to local server */ - XX_httplib_handle_request( conn ); - if ( conn->ctx->callbacks.end_request != NULL ) conn->ctx->callbacks.end_request( conn, conn->status_code ); - XX_httplib_log_access(conn); + XX_httplib_handle_request( ctx, conn ); + if ( ctx->callbacks.end_request != NULL ) ctx->callbacks.end_request( conn, conn->status_code ); + XX_httplib_log_access( ctx, conn ); } else { @@ -166,7 +166,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) { * in loop exit condition. */ - keep_alive = conn->ctx->status == CTX_STATUS_RUNNING && conn->ctx->enable_keep_alive && conn->content_len >= 0 && XX_httplib_should_keep_alive( conn ); + keep_alive = ctx->status == CTX_STATUS_RUNNING && ctx->enable_keep_alive && conn->content_len >= 0 && XX_httplib_should_keep_alive( ctx, conn ); /* * Discard all buffered data for this request diff --git a/src/httplib_pull.c b/src/httplib_pull.c index 129431a9..4b020523 100644 --- a/src/httplib_pull.c +++ b/src/httplib_pull.c @@ -34,7 +34,7 @@ * Return negative value on error, or number of bytes read on success. */ -int XX_httplib_pull( FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout ) { +int XX_httplib_pull( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout ) { int nread; int err; @@ -102,7 +102,7 @@ int XX_httplib_pull( FILE *fp, struct httplib_connection *conn, char *buf, int l if (nread == 0) return -1; /* shutdown of the socket at client side */ } - if ( conn->ctx->status != CTX_STATUS_RUNNING ) return -1; + if ( ctx->status != CTX_STATUS_RUNNING ) return -1; if ( nread > 0 || (nread == 0 && len == 0) ) { diff --git a/src/httplib_pull_all.c b/src/httplib_pull_all.c index d0743964..7de4ded3 100644 --- a/src/httplib_pull_all.c +++ b/src/httplib_pull_all.c @@ -27,20 +27,20 @@ #include "httplib_main.h" -int XX_httplib_pull_all( FILE *fp, struct httplib_connection *conn, char *buf, int len ) { +int XX_httplib_pull_all( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int len ) { int n; int nread; double timeout; - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; nread = 0; - timeout = ((double)conn->ctx->request_timeout) / 1000.0; + timeout = ((double)ctx->request_timeout) / 1000.0; - while ( len > 0 && conn->ctx->status == CTX_STATUS_RUNNING ) { + while ( len > 0 && ctx->status == CTX_STATUS_RUNNING ) { - n = XX_httplib_pull( fp, conn, buf + nread, len, timeout ); + n = XX_httplib_pull( ctx, fp, conn, buf + nread, len, timeout ); if ( n < 0 ) { diff --git a/src/httplib_push_all.c b/src/httplib_push_all.c index f510aff7..d407884c 100644 --- a/src/httplib_push_all.c +++ b/src/httplib_push_all.c @@ -36,7 +36,7 @@ #endif /* - * static int64_t push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout ); + * static int64_t push( const struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout ); * * The function push() writes data to the I/O channel, opened file descriptor, * socket or SSL descriptor. The function returns the number of bytes which @@ -50,7 +50,7 @@ * been written. */ -static int64_t push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout ) { +static int64_t push( const struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout ) { struct timespec start; struct timespec now; @@ -146,13 +146,13 @@ static int64_t push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ss /* - * int64_t XX_httplib_push_all( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ); + * int64_t XX_httplib_push_all( const struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ); * * The function XX_httplib_push_all() pushes all data in a buffer to a socket. * The number of bytes written is returned. */ -int64_t XX_httplib_push_all( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ) { +int64_t XX_httplib_push_all( const struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len ) { double timeout; int64_t n; diff --git a/src/httplib_put_dir.c b/src/httplib_put_dir.c index 349d34ca..e76183d8 100644 --- a/src/httplib_put_dir.c +++ b/src/httplib_put_dir.c @@ -39,7 +39,7 @@ * Return -2 if path can not be created. */ -int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ) { +int XX_httplib_put_dir( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { char buf[PATH_MAX]; const char *s; @@ -48,6 +48,8 @@ int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ) { size_t len; int res; + if ( ctx == NULL ) return -2; + res = 1; s = path+2; @@ -73,7 +75,7 @@ int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ) { * Try to create intermediate directory */ - if ( ! XX_httplib_stat( conn, buf, &file ) && httplib_mkdir( buf, 0755 ) != 0 ) { + if ( ! XX_httplib_stat( ctx, conn, buf, &file ) && httplib_mkdir( buf, 0755 ) != 0 ) { /* * path does not exixt and can not be created diff --git a/src/httplib_put_file.c b/src/httplib_put_file.c index e107a5b6..665bbd35 100644 --- a/src/httplib_put_file.c +++ b/src/httplib_put_file.c @@ -29,13 +29,13 @@ #include "httplib_utils.h" /* - * void XX_httplib_put_file( struct httplib_connection *conn, const char *path ); + * void XX_httplib_put_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ); * * The function XX_httplib_put_file() processes a file PUT request coming from * a remote client. */ -void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { +void XX_httplib_put_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { struct file file = STRUCT_FILE_INITIALIZER; const char *range; @@ -46,12 +46,12 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { char error_string[ERROR_STRING_LEN]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; + if ( ctx->document_root == NULL ) return; curtime = time( NULL ); - if ( XX_httplib_stat( conn, path, &file ) ) { + if ( XX_httplib_stat( ctx, conn, path, &file ) ) { /* * File already exists @@ -82,7 +82,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * This is an "in-memory" file, that can not be replaced */ - XX_httplib_send_http_error( conn, 405, "Error: Put not possible\nReplacing %s is not supported", path ); + XX_httplib_send_http_error( ctx, conn, 405, "Error: Put not possible\nReplacing %s is not supported", path ); return; } @@ -101,7 +101,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { } else { - XX_httplib_send_http_error( conn, 403, "Error: Put not possible\nReplacing %s is not allowed", path ); + XX_httplib_send_http_error( ctx, conn, 403, "Error: Put not possible\nReplacing %s is not allowed", path ); return; } } @@ -113,7 +113,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { */ conn->status_code = 201; - rc = XX_httplib_put_dir( conn, path ); + rc = XX_httplib_put_dir( ctx, conn, path ); } if ( rc == 0 ) { @@ -123,9 +123,9 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { */ XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - httplib_printf( conn, "HTTP/1.1 %d %s\r\n", conn->status_code, httplib_get_response_code_text( NULL, conn->status_code ) ); - XX_httplib_send_no_cache_header( conn ); - httplib_printf( conn, "Date: %s\r\n" "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", date, XX_httplib_suggest_connection_header( conn ) ); + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n", conn->status_code, httplib_get_response_code_text( ctx, NULL, conn->status_code ) ); + XX_httplib_send_no_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Date: %s\r\n" "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", date, XX_httplib_suggest_connection_header( ctx, conn ) ); /* * Request to create a directory has been fulfilled successfully. @@ -141,7 +141,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * XX_httplib_put_dir returns -1 if the path is too long */ - XX_httplib_send_http_error( conn, 414, "Error: Path too long\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 414, "Error: Path too long\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -151,7 +151,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * XX_httplib_put_dir returns -2 if the directory can not be created */ - XX_httplib_send_http_error( conn, 500, "Error: Can not create directory\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Can not create directory\nput_dir(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } @@ -159,14 +159,14 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { * A file should be created or overwritten. */ - if ( ! XX_httplib_fopen( conn, path, "wb+", &file) || file.fp == NULL ) { + if ( ! XX_httplib_fopen( ctx, conn, path, "wb+", &file) || file.fp == NULL ) { XX_httplib_fclose( & file ); - XX_httplib_send_http_error( conn, 500, "Error: Can not create file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Can not create file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } - XX_httplib_fclose_on_exec( & file, conn ); + XX_httplib_fclose_on_exec( ctx, &file, conn ); range = httplib_get_header( conn, "Content-Range" ); r1 = 0; @@ -178,7 +178,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { fseeko( file.fp, r1, SEEK_SET ); } - if ( ! XX_httplib_forward_body_data( conn, file.fp, INVALID_SOCKET, NULL ) ) { + if ( ! XX_httplib_forward_body_data( ctx, conn, file.fp, INVALID_SOCKET, NULL ) ) { /* * XX_httplib_forward_body_data failed. @@ -191,9 +191,9 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) { } XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - httplib_printf( conn, "HTTP/1.1 %d %s\r\n", conn->status_code, httplib_get_response_code_text( NULL, conn->status_code ) ); - XX_httplib_send_no_cache_header( conn ); - httplib_printf( conn, "Date: %s\r\n" "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", date, XX_httplib_suggest_connection_header( conn ) ); + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n", conn->status_code, httplib_get_response_code_text( ctx, NULL, conn->status_code ) ); + XX_httplib_send_no_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Date: %s\r\n" "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", date, XX_httplib_suggest_connection_header( ctx, conn ) ); XX_httplib_fclose( & file ); diff --git a/src/httplib_read.c b/src/httplib_read.c index afc6ed1b..e3caf298 100644 --- a/src/httplib_read.c +++ b/src/httplib_read.c @@ -27,7 +27,7 @@ #include "httplib_main.h" -static int httplib_read_inner( struct httplib_connection *conn, void *buffie, size_t len ) { +static int httplib_read_inner( const struct httplib_context *ctx, struct httplib_connection *conn, void *buffie, size_t len ) { int64_t n; int64_t buffered_len; @@ -36,7 +36,7 @@ static int httplib_read_inner( struct httplib_connection *conn, void *buffie, si const char *body; char *buf; - if ( conn == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; buf = buffie; @@ -90,7 +90,7 @@ static int httplib_read_inner( struct httplib_connection *conn, void *buffie, si * socket. */ - n = XX_httplib_pull_all( NULL, conn, buf, (int)len64 ); + n = XX_httplib_pull_all( ctx, NULL, conn, buf, (int)len64 ); if ( n >= 0 ) nread += n; else nread = (nread > 0) ? nread : n; @@ -101,21 +101,21 @@ static int httplib_read_inner( struct httplib_connection *conn, void *buffie, si } /* httplib_read_inner */ -static char httplib_getc(struct httplib_connection *conn) { +static char httplib_getc( const struct httplib_context *ctx, struct httplib_connection *conn ) { char c; if ( conn == NULL ) return 0; conn->content_len++; - if ( httplib_read_inner( conn, &c, 1 ) <= 0 ) return '\0'; + if ( httplib_read_inner( ctx, conn, &c, 1 ) <= 0 ) return '\0'; return c; } /* httplib_getc */ -int httplib_read( struct httplib_connection *conn, void *buf, size_t len ) { +int httplib_read( const struct httplib_context *ctx, struct httplib_connection *conn, void *buf, size_t len ) { if ( len > INT_MAX ) len = INT_MAX; @@ -142,7 +142,7 @@ int httplib_read( struct httplib_connection *conn, void *buf, size_t len ) { size_t read_now = ((conn->chunk_remainder > len) ? (len) : (conn->chunk_remainder)); conn->content_len += (int)read_now; - read_ret = httplib_read_inner(conn, (char *)buf + all_read, read_now); + read_ret = httplib_read_inner( ctx, conn, (char *)buf + all_read, read_now ); all_read += (size_t)read_ret; conn->chunk_remainder -= read_now; @@ -154,7 +154,7 @@ int httplib_read( struct httplib_connection *conn, void *buf, size_t len ) { * the rest of the data in the current chunk has been read */ - if ( httplib_getc(conn) != '\r' || httplib_getc(conn) != '\n' ) { + if ( httplib_getc( ctx, conn ) != '\r' || httplib_getc( ctx, conn ) != '\n' ) { /* * Protocol violation @@ -181,7 +181,7 @@ int httplib_read( struct httplib_connection *conn, void *buf, size_t len ) { for (i=0; i < ((int)sizeof(lenbuf)-1); i++) { - lenbuf[i] = httplib_getc( conn ); + lenbuf[i] = httplib_getc( ctx, conn ); if ( i > 0 && lenbuf[i] == '\r' && lenbuf[i-1] != '\r' ) continue; @@ -220,6 +220,6 @@ int httplib_read( struct httplib_connection *conn, void *buf, size_t len ) { return (int)all_read; } - return httplib_read_inner( conn, buf, len ); + return httplib_read_inner( ctx, conn, buf, len ); } /* httplib_read */ diff --git a/src/httplib_read_auth_file.c b/src/httplib_read_auth_file.c index 827a5468..24aef83b 100644 --- a/src/httplib_read_auth_file.c +++ b/src/httplib_read_auth_file.c @@ -28,14 +28,14 @@ #include "httplib_main.h" /* - * bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct *workdata ); + * bool XX_httplib_read_auth_file( const struct httplib_context *ctx, struct file *filep, struct read_auth_file_struct *workdata ); * * The function XX_httpib_read_auth_file() loops over the password file to * read its contents. Include statements are honored which lets the routine * also open and scan child files. */ -bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct *workdata ) { +bool XX_httplib_read_auth_file( const struct httplib_context *ctx, struct file *filep, struct read_auth_file_struct *workdata ) { int is_authorized; struct file fp; @@ -45,7 +45,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct char * var; } ptr; - if ( filep == NULL || workdata == NULL ) return false; + if ( ctx == NULL || filep == NULL || workdata == NULL ) return false; is_authorized = false; @@ -85,13 +85,13 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct else if ( ! strncmp( workdata->f_user + 1, "include=", 8 ) ) { - if ( XX_httplib_fopen( workdata->conn, workdata->f_user + 9, "r", &fp ) ) { + if ( XX_httplib_fopen( ctx, workdata->conn, workdata->f_user + 9, "r", &fp ) ) { - is_authorized = XX_httplib_read_auth_file( &fp, workdata ); + is_authorized = XX_httplib_read_auth_file( ctx, &fp, workdata ); XX_httplib_fclose( &fp ); } - else httplib_cry( DEBUG_LEVEL_ERROR, workdata->conn->ctx, workdata->conn, "%s: cannot open authorization file: %s", __func__, workdata->buf ); + else httplib_cry( DEBUG_LEVEL_ERROR, ctx, workdata->conn, "%s: cannot open authorization file: %s", __func__, workdata->buf ); continue; } @@ -100,7 +100,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct * future) */ - httplib_cry( DEBUG_LEVEL_ERROR, workdata->conn->ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); continue; } @@ -108,7 +108,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct if ( workdata->f_domain == NULL ) { - httplib_cry( DEBUG_LEVEL_ERROR, workdata->conn->ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); continue; } @@ -119,7 +119,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct if ( workdata->f_ha1 == NULL ) { - httplib_cry( DEBUG_LEVEL_ERROR, workdata->conn->ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, workdata->conn, "%s: syntax error in authorization file: %s", __func__, workdata->buf ); continue; } diff --git a/src/httplib_read_request.c b/src/httplib_read_request.c index ef82280a..dcab62af 100644 --- a/src/httplib_read_request.c +++ b/src/httplib_read_request.c @@ -29,7 +29,7 @@ #include "httplib_utils.h" /* - * int XX_httplib_read_request( FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ); + * int XX_httplib_read_request( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ); * * The function XX_httplib_read_request() keeps reading the input (which can * either be an opened file descriptor, a socket sock or an SSL descriptor ssl) @@ -39,20 +39,20 @@ * is incremented by the number of bytes read. */ -int XX_httplib_read_request( FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ) { +int XX_httplib_read_request( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int bufsiz, int *nread ) { int request_len; int n; struct timespec last_action_time; double request_timeout; - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; n = 0; memset( & last_action_time, 0, sizeof(last_action_time) ); - request_timeout = ((double)conn->ctx->request_timeout) / 1000.0; + request_timeout = ((double)ctx->request_timeout) / 1000.0; request_len = XX_httplib_get_request_len( buf, *nread ); /* @@ -61,11 +61,11 @@ int XX_httplib_read_request( FILE *fp, struct httplib_connection *conn, char *bu clock_gettime( CLOCK_MONOTONIC, & last_action_time ); - while ( conn->ctx->status == CTX_STATUS_RUNNING && - *nread < bufsiz && - request_len == 0 && + while ( ctx->status == CTX_STATUS_RUNNING && + *nread < bufsiz && + request_len == 0 && ((XX_httplib_difftimespec(&last_action_time, &(conn->req_time)) <= request_timeout) || (request_timeout < 0)) && - ((n = XX_httplib_pull(fp, conn, buf + *nread, bufsiz - *nread, request_timeout)) > 0)) { + ( (n = XX_httplib_pull( ctx, fp, conn, buf + *nread, bufsiz - *nread, request_timeout )) > 0 ) ) { *nread += n; if ( *nread > bufsiz ) return -2; diff --git a/src/httplib_read_websocket.c b/src/httplib_read_websocket.c index a1dcbd8c..f466f277 100644 --- a/src/httplib_read_websocket.c +++ b/src/httplib_read_websocket.c @@ -28,12 +28,12 @@ #include "httplib_main.h" /* - * void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *calback_data ); + * void XX_httplib_read_websocket( const struct httplib_context *ctx, struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *calback_data ); * * The function XX_httplib_read_websocket() reads from a websocket connection. */ -void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *callback_data ) { +void XX_httplib_read_websocket( const struct httplib_context *ctx, struct httplib_connection *conn, httplib_websocket_data_handler ws_data_handler, void *callback_data ) { /* Pointer to the beginning of the portion of the incoming websocket * message queue. @@ -76,27 +76,27 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock unsigned char mop; /* mask flag and opcode */ double timeout; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; data = mem; - timeout = ((double)conn->ctx->websocket_timeout) / 1000.0; - if ( timeout <= 0.0 ) timeout = ((double)conn->ctx->request_timeout) / 1000.0; + timeout = ((double)ctx->websocket_timeout) / 1000.0; + if ( timeout <= 0.0 ) timeout = ((double)ctx->request_timeout ) / 1000.0; - XX_httplib_set_thread_name( "wsock" ); + XX_httplib_set_thread_name( ctx, "wsock" ); /* * Loop continuously, reading messages from the socket, invoking the * callback, and waiting repeatedly until an error occurs. */ - while ( conn->ctx->status == CTX_STATUS_RUNNING ) { + while ( ctx->status == CTX_STATUS_RUNNING ) { header_len = 0; if ( conn->data_len < conn->request_len ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: websocket error: data len less than request len, closing connection", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: websocket error: data len less than request len, closing connection", __func__ ); break; } @@ -145,7 +145,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock * connection */ - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: websocket out of memory; closing connection", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: websocket out of memory; closing connection", __func__ ); break; } } @@ -161,7 +161,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock if ( body_len < header_len ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: websocket error: body len less than header len, closing connection", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: websocket error: body len less than header len, closing connection", __func__ ); break; } @@ -183,7 +183,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock while ( len < data_len ) { - n = XX_httplib_pull( NULL, conn, data + len, (int)(data_len - len), timeout ); + n = XX_httplib_pull( ctx, NULL, conn, data + len, (int)(data_len - len), timeout ); if ( n <= 0 ) { error = 1; @@ -195,7 +195,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock if (error) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: websocket pull failed; closing connection", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: websocket pull failed; closing connection", __func__ ); break; } @@ -270,7 +270,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock * message queue. */ - n = XX_httplib_pull( NULL, conn, conn->buf + conn->data_len, conn->buf_size - conn->data_len, timeout ); + n = XX_httplib_pull( ctx, NULL, conn, conn->buf + conn->data_len, conn->buf_size - conn->data_len, timeout ); /* * Error, no bytes read @@ -282,6 +282,6 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock } } - XX_httplib_set_thread_name( "worker" ); + XX_httplib_set_thread_name( ctx, "worker" ); } /* XX_httplib_read_websocket */ diff --git a/src/httplib_redirect_to_https_port.c b/src/httplib_redirect_to_https_port.c index 0b4c72d9..f9b1ae6a 100644 --- a/src/httplib_redirect_to_https_port.c +++ b/src/httplib_redirect_to_https_port.c @@ -29,20 +29,20 @@ #include "httplib_string.h" /* - * void XX_httplib_redirect_to_https_port( struct httplib_connection *conn, int ssl_index ); + * void XX_httplib_redirect_to_https_port( const struct httplib_context *ctx, struct httplib_connection *conn, int ssl_index ); * * The function XX_httplib_redirect_to_https_port() redirects a request to an * encrypted connection over HTTPS. */ -void XX_httplib_redirect_to_https_port( struct httplib_connection *conn, int ssl_index ) { +void XX_httplib_redirect_to_https_port( const struct httplib_context *ctx, struct httplib_connection *conn, int ssl_index ) { char host[1024+1]; const char *host_header; size_t hostlen; char *pos; - if ( conn == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; host_header = httplib_get_header(conn, "Host"); hostlen = sizeof( host ); @@ -68,11 +68,11 @@ void XX_httplib_redirect_to_https_port( struct httplib_connection *conn, int ssl * Send host, port, uri and (if it exists) ?query_string */ - httplib_printf( conn, "HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s%s%s\r\n\r\n", + httplib_printf( ctx, conn, "HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s%s%s\r\n\r\n", host, - (conn->ctx->listening_sockets[ssl_index].lsa.sa.sa_family == AF_INET6) - ? (int)ntohs( conn->ctx->listening_sockets[ssl_index].lsa.sin6.sin6_port ) - : (int)ntohs( conn->ctx->listening_sockets[ssl_index].lsa.sin.sin_port ), + (ctx->listening_sockets[ssl_index].lsa.sa.sa_family == AF_INET6) + ? (int)ntohs( ctx->listening_sockets[ssl_index].lsa.sin6.sin6_port ) + : (int)ntohs( ctx->listening_sockets[ssl_index].lsa.sin.sin_port ), conn->request_info.local_uri, (conn->request_info.query_string == NULL) ? "" : "?", (conn->request_info.query_string == NULL) ? "" : conn->request_info.query_string); diff --git a/src/httplib_refresh_trust.c b/src/httplib_refresh_trust.c index dea5883b..ae795bb6 100644 --- a/src/httplib_refresh_trust.c +++ b/src/httplib_refresh_trust.c @@ -41,19 +41,19 @@ static long int data_check = 0; #if !defined(NO_SSL) -int XX_httplib_refresh_trust( struct httplib_connection *conn ) { +int XX_httplib_refresh_trust( const struct httplib_context *ctx, struct httplib_connection *conn ) { volatile int *p_reload_lock; struct stat cert_buf; long int t; char *pem; - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; p_reload_lock = & reload_lock; - pem = conn->ctx->ssl_certificate; + pem = ctx->ssl_certificate; - if ( pem == NULL && conn->ctx->callbacks.init_ssl == NULL ) return 0; + if ( pem == NULL && ctx->callbacks.init_ssl == NULL ) return 0; if ( stat( pem, &cert_buf ) != -1 ) t = (long int)cert_buf.st_mtime; else t = data_check; @@ -62,11 +62,11 @@ int XX_httplib_refresh_trust( struct httplib_connection *conn ) { data_check = t; - if ( conn->ctx->ssl_verify_peer ) { + if ( ctx->ssl_verify_peer ) { - if ( SSL_CTX_load_verify_locations( conn->ctx->ssl_ctx, conn->ctx->ssl_ca_file, conn->ctx->ssl_ca_path ) != 1 ) { + if ( SSL_CTX_load_verify_locations( ctx->ssl_ctx, ctx->ssl_ca_file, ctx->ssl_ca_path ) != 1 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: SSL_CTX_load_verify_locations error: %s ssl_verify_peer requires setting either ssl_ca_path or ssl_ca_file. Is any of them present in the .conf file?", __func__, XX_httplib_ssl_error() ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: SSL_CTX_load_verify_locations error: %s ssl_verify_peer requires setting either ssl_ca_path or ssl_ca_file. Is any of them present in the .conf file?", __func__, XX_httplib_ssl_error() ); return 0; } @@ -74,7 +74,7 @@ int XX_httplib_refresh_trust( struct httplib_connection *conn ) { if ( httplib_atomic_inc( p_reload_lock ) == 1 ) { - if ( XX_httplib_ssl_use_pem_file( conn->ctx, pem ) == 0 ) return 0; + if ( XX_httplib_ssl_use_pem_file( ctx, pem ) == 0 ) return 0; *p_reload_lock = 0; } } diff --git a/src/httplib_remove_bad_file.c b/src/httplib_remove_bad_file.c index 039c9c12..47f6d7d0 100644 --- a/src/httplib_remove_bad_file.c +++ b/src/httplib_remove_bad_file.c @@ -28,16 +28,16 @@ #include "httplib_main.h" /* - * void XX_httplib_remove_bad_file( const struct httplib_connection *conn, const char *path ); + * void XX_httplib_remove_bad_file( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path ); * * The function XX_httplib_remove_bad_file() removes an invalid file and throws * an error message if this does not succeed. */ -void XX_httplib_remove_bad_file( const struct httplib_connection *conn, const char *path ) { +void XX_httplib_remove_bad_file( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path ) { int r = httplib_remove( path ); - if ( r != 0 && conn != NULL && conn->ctx != NULL ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Cannot remove invalid file %s", __func__, path ); + if ( r != 0 && ctx != NULL && conn != NULL ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Cannot remove invalid file %s", __func__, path ); } /* XX_httplib_remove_bad_file */ diff --git a/src/httplib_remove_directory.c b/src/httplib_remove_directory.c index d204d329..c330e119 100644 --- a/src/httplib_remove_directory.c +++ b/src/httplib_remove_directory.c @@ -29,13 +29,13 @@ #include "httplib_string.h" /* - * int XX_httplib_remove_directory( struct httplib_connection *conn, const char *dir ); + * int XX_httplib_remove_directory( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir ); * - * The function XX_httplib_remove_directory() removes recirsively a directory + * The function XX_httplib_remove_directory() removes recursively a directory * tree. */ -int XX_httplib_remove_directory( struct httplib_connection *conn, const char *dir ) { +int XX_httplib_remove_directory( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir ) { char path[PATH_MAX]; char error_string[ERROR_STRING_LEN]; @@ -45,6 +45,8 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di bool truncated; int ok; + if ( ctx == NULL || dir == NULL ) return 0; + ok = 1; dirp = httplib_opendir( dir ); @@ -61,7 +63,7 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di if ( ! strcmp( dp->d_name, "." ) || ! strcmp( dp->d_name, ".." ) ) continue; - XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name ); + XX_httplib_snprintf( ctx, conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name ); /* * If we don't memset stat structure to zero, mtime will have @@ -83,9 +85,9 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di continue; } - if ( ! XX_httplib_stat( conn, path, & de.file ) ) { + if ( ! XX_httplib_stat( ctx, conn, path, & de.file ) ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); ok = 0; } if ( de.file.membuf == NULL ) { @@ -96,7 +98,7 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di if ( de.file.is_directory ) { - if ( XX_httplib_remove_directory( conn, path ) == 0 ) ok = 0; + if ( XX_httplib_remove_directory( ctx, conn, path ) == 0 ) ok = 0; } else if ( httplib_remove( path ) == 0 ) ok = 0; diff --git a/src/httplib_scan_directory.c b/src/httplib_scan_directory.c index 36d9e0c6..53dc45cd 100644 --- a/src/httplib_scan_directory.c +++ b/src/httplib_scan_directory.c @@ -28,7 +28,7 @@ #include "httplib_main.h" #include "httplib_string.h" -int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, void *data, void (*cb)(struct de *, void *) ) { +int XX_httplib_scan_directory( const struct httplib_context *ctx, struct httplib_connection *conn, const char *dir, void *data, void (*cb)(const struct httplib_context *ctx, struct de *, void *) ) { char path[PATH_MAX]; char error_string[ERROR_STRING_LEN]; @@ -37,6 +37,8 @@ int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, struct de de; bool truncated; + if ( ctx == NULL ) return 0; + dirp = httplib_opendir( dir ); if ( dirp == NULL ) return 0; @@ -48,9 +50,9 @@ int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, * Do not show current dir and hidden files */ - if ( ! strcmp( dp->d_name, "." ) || ! strcmp(dp->d_name, "..") || XX_httplib_must_hide_file( conn, dp->d_name ) ) continue; + if ( ! strcmp( dp->d_name, "." ) || ! strcmp(dp->d_name, "..") || XX_httplib_must_hide_file( ctx, dp->d_name ) ) continue; - XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name ); + XX_httplib_snprintf( ctx, conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name ); /* * If we don't memset stat structure to zero, mtime will have @@ -64,13 +66,13 @@ int XX_httplib_scan_directory( struct httplib_connection *conn, const char *dir, if ( truncated ) continue; /* If the path is not complete, skip processing. */ - if ( ! XX_httplib_stat( conn, path, &de.file ) ) { + if ( ! XX_httplib_stat( ctx, conn, path, &de.file ) ) { - httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: XX_httplib_stat(%s) failed: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } de.file_name = dp->d_name; - cb( &de, data ); + cb( ctx, &de, data ); } httplib_closedir( dirp ); diff --git a/src/httplib_send_authorization_request.c b/src/httplib_send_authorization_request.c index fa93d985..bbdc3677 100644 --- a/src/httplib_send_authorization_request.c +++ b/src/httplib_send_authorization_request.c @@ -29,43 +29,43 @@ #include "httplib_pthread.h" #include "httplib_utils.h" -void XX_httplib_send_authorization_request( struct httplib_connection *conn ) { +void XX_httplib_send_authorization_request( struct httplib_context *ctx, struct httplib_connection *conn ) { char date[64]; time_t curtime; uint64_t nonce; const char *auth_domain; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; curtime = time( NULL ); - nonce = (uint64_t)conn->ctx->start_time; + nonce = (uint64_t)ctx->start_time; - httplib_pthread_mutex_lock( & conn->ctx->nonce_mutex ); - nonce += conn->ctx->nonce_count; - ++conn->ctx->nonce_count; - httplib_pthread_mutex_unlock( & conn->ctx->nonce_mutex ); + httplib_pthread_mutex_lock( & ctx->nonce_mutex ); + nonce += ctx->nonce_count; + ++ctx->nonce_count; + httplib_pthread_mutex_unlock( & ctx->nonce_mutex ); - nonce ^= conn->ctx->auth_nonce_mask; + nonce ^= ctx->auth_nonce_mask; conn->status_code = 401; conn->must_close = true; XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - if ( conn->ctx->authentication_domain != NULL ) auth_domain = conn->ctx->authentication_domain; - else auth_domain = "example.com"; + if ( ctx->authentication_domain != NULL ) auth_domain = ctx->authentication_domain; + else auth_domain = "example.com"; - httplib_printf( conn, "HTTP/1.1 401 Unauthorized\r\n" ); - XX_httplib_send_no_cache_header( conn ); - httplib_printf( conn, + httplib_printf( ctx, conn, "HTTP/1.1 401 Unauthorized\r\n" ); + XX_httplib_send_no_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "Date: %s\r\n" "Connection: %s\r\n" "Content-Length: 0\r\n" "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", " "nonce=\"%" UINT64_FMT "\"\r\n\r\n", date, - XX_httplib_suggest_connection_header(conn), + XX_httplib_suggest_connection_header( ctx, conn ), auth_domain, nonce ); diff --git a/src/httplib_send_file.c b/src/httplib_send_file.c index 515a5925..198d0d30 100644 --- a/src/httplib_send_file.c +++ b/src/httplib_send_file.c @@ -28,29 +28,29 @@ #include "httplib_main.h" /* - * void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); + * void httplib_send_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); * * The function httplib_send_file() sends a file to the other peer. Optionally * the MIME type and additional headers can be specified. */ -void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ) { +void httplib_send_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ) { struct file file = STRUCT_FILE_INITIALIZER; - if ( XX_httplib_stat( conn, path, &file ) ) { + if ( ctx == NULL || conn == NULL ) return; + + if ( XX_httplib_stat( ctx, conn, path, &file ) ) { if ( file.is_directory ) { - if ( conn == NULL || conn->ctx == NULL ) return; - - if ( conn->ctx->enable_directory_listing ) XX_httplib_handle_directory_request( conn, path ); - else XX_httplib_send_http_error( conn, 403, "%s", "Error: Directory listing denied" ); + if ( ctx->enable_directory_listing ) XX_httplib_handle_directory_request( ctx, conn, path ); + else XX_httplib_send_http_error( ctx, conn, 403, "%s", "Error: Directory listing denied" ); } - else XX_httplib_handle_static_file_request( conn, path, &file, mime_type, additional_headers ); + else XX_httplib_handle_static_file_request( ctx, conn, path, &file, mime_type, additional_headers ); } - else XX_httplib_send_http_error( conn, 404, "%s", "Error: File not found" ); + else XX_httplib_send_http_error( ctx, conn, 404, "%s", "Error: File not found" ); } /* httplib_send_file */ diff --git a/src/httplib_send_file_data.c b/src/httplib_send_file_data.c index f5e8916d..7a6ff51d 100644 --- a/src/httplib_send_file_data.c +++ b/src/httplib_send_file_data.c @@ -34,7 +34,7 @@ * Send len bytes from the opened file to the client. */ -void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *filep, int64_t offset, int64_t len ) { +void XX_httplib_send_file_data( const struct httplib_context *ctx, struct httplib_connection *conn, struct file *filep, int64_t offset, int64_t len ) { char buf[MG_BUF_LEN]; char error_string[ERROR_STRING_LEN]; @@ -49,7 +49,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi int loop_cnt; #endif /* __linux__ */ - if ( filep == NULL || conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || filep == NULL || conn == NULL ) return; /* * Sanity check the offset @@ -68,7 +68,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi */ if (len > size - offset) len = size - offset; - httplib_write( conn, filep->membuf + offset, (size_t)len ); + httplib_write( ctx, conn, filep->membuf + offset, (size_t)len ); } @@ -81,7 +81,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi * sendfile is only available for Linux */ - if ( conn->ctx->allow_sendfile_call && conn->ssl == 0 && conn->throttle == 0 ) { + if ( ctx->allow_sendfile_call && conn->ssl == 0 && conn->throttle == 0 ) { sf_offs = (off_t)offset; sf_file = fileno( filep->fp ); @@ -140,8 +140,8 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi #endif if ( offset > 0 && fseeko( filep->fp, offset, SEEK_SET ) != 0 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: fseeko() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - XX_httplib_send_http_error( conn, 500, "%s", "Error: Unable to access file at requested position." ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: fseeko() failed: %s", __func__, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "%s", "Error: Unable to access file at requested position." ); } else { @@ -164,7 +164,7 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi * Send read bytes to the client, exit the loop on error */ - if ( (num_written = httplib_write( conn, buf, (size_t)num_read )) != num_read ) break; + if ( (num_written = httplib_write( ctx, conn, buf, (size_t)num_read )) != num_read ) break; /* * Both read and were successful, adjust counters diff --git a/src/httplib_send_http_error.c b/src/httplib_send_http_error.c index 6845503d..10e142f3 100644 --- a/src/httplib_send_http_error.c +++ b/src/httplib_send_http_error.c @@ -29,7 +29,7 @@ #include "httplib_string.h" #include "httplib_utils.h" -void XX_httplib_send_http_error( struct httplib_connection *conn, int status, const char *fmt, ... ) { +void XX_httplib_send_http_error( const struct httplib_context *ctx, struct httplib_connection *conn, int status, const char *fmt, ... ) { char buf[MG_BUF_LEN]; va_list ap; @@ -47,15 +47,15 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co const char *tstr; const char *status_text; - if ( conn == NULL || conn->ctx == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; curtime = time( NULL ); error_handler = NULL; - status_text = httplib_get_response_code_text( conn, status ); + status_text = httplib_get_response_code_text( ctx, conn, status ); conn->status_code = status; - if ( conn->in_error_handler || conn->ctx->callbacks.http_error == NULL || conn->ctx->callbacks.http_error( conn, status ) ) { + if ( conn->in_error_handler || ctx->callbacks.http_error == NULL || ctx->callbacks.http_error( conn, status ) ) { if ( ! conn->in_error_handler ) { @@ -63,8 +63,8 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co * Send user defined error pages, if defined */ - error_handler = conn->ctx->error_pages; - error_page_file_ext = conn->ctx->index_files; + error_handler = ctx->error_pages; + error_page_file_ext = ctx->index_files; page_handler_found = 0; if ( error_handler != NULL ) { @@ -78,7 +78,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co * Handler for specific error, e.g. 404 error */ - XX_httplib_snprintf( conn, &truncated, buf, sizeof(buf) - 32, "%serror%03u.", error_handler, status ); + XX_httplib_snprintf( ctx, conn, &truncated, buf, sizeof(buf) - 32, "%serror%03u.", error_handler, status ); break; case 2 : @@ -87,7 +87,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co * for all server errors (500-599) */ - XX_httplib_snprintf( conn, &truncated, buf, sizeof(buf) - 32, "%serror%01uxx.", error_handler, status / 100 ); + XX_httplib_snprintf( ctx, conn, &truncated, buf, sizeof(buf) - 32, "%serror%01uxx.", error_handler, status / 100 ); break; default : @@ -95,7 +95,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co * Handler for all errors */ - XX_httplib_snprintf( conn, &truncated, buf, sizeof(buf) - 32, "%serror.", error_handler ); + XX_httplib_snprintf( ctx, conn, &truncated, buf, sizeof(buf) - 32, "%serror.", error_handler ); break; } @@ -115,7 +115,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co for (i=1; i<32 && tstr[i] != 0 && tstr[i] != ','; i++) buf[len + i - 1] = tstr[i]; buf[len + i - 1] = 0; - if ( XX_httplib_stat( conn, buf, &error_page_file ) ) { + if ( XX_httplib_stat( ctx, conn, buf, &error_page_file ) ) { page_handler_found = 1; break; @@ -128,7 +128,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co if ( page_handler_found ) { conn->in_error_handler = true; - XX_httplib_handle_file_based_request( conn, buf, &error_page_file ); + XX_httplib_handle_file_based_request( ctx, conn, buf, &error_page_file ); conn->in_error_handler = false; return; @@ -149,11 +149,11 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co conn->must_close = true; - httplib_printf( conn, "HTTP/1.1 %d %s\r\n", status, status_text ); - XX_httplib_send_no_cache_header( conn ); + httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n", status, status_text ); + XX_httplib_send_no_cache_header( ctx, conn ); - if ( has_body ) httplib_printf( conn, "%s", "Content-Type: text/plain; charset=utf-8\r\n" ); - httplib_printf( conn, "Date: %s\r\n" "Connection: close\r\n\r\n", date ); + if ( has_body ) httplib_printf( ctx, conn, "%s", "Content-Type: text/plain; charset=utf-8\r\n" ); + httplib_printf( ctx, conn, "Date: %s\r\n" "Connection: close\r\n\r\n", date ); /* * Errors 1xx, 204 and 304 MUST NOT send a body @@ -161,14 +161,14 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co if ( has_body ) { - httplib_printf( conn, "Error %d: %s\n", status, status_text ); + httplib_printf( ctx, conn, "Error %d: %s\n", status, status_text ); if ( fmt != NULL ) { va_start( ap, fmt ); - XX_httplib_vsnprintf( conn, NULL, buf, sizeof(buf), fmt, ap ); + XX_httplib_vsnprintf( ctx, conn, NULL, buf, sizeof(buf), fmt, ap ); va_end( ap ); - httplib_write( conn, buf, strlen(buf) ); + httplib_write( ctx, conn, buf, strlen(buf) ); } } diff --git a/src/httplib_send_no_cache_header.c b/src/httplib_send_no_cache_header.c index 11eda5bf..be6016ae 100644 --- a/src/httplib_send_no_cache_header.c +++ b/src/httplib_send_no_cache_header.c @@ -27,13 +27,13 @@ #include "httplib_main.h" -int XX_httplib_send_no_cache_header( struct httplib_connection *conn ) { +int XX_httplib_send_no_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn ) { /* * Send all current and obsolete cache opt-out directives. */ - return httplib_printf( conn, + return httplib_printf( ctx, conn, "Cache-Control: no-cache, no-store, " "must-revalidate, private, max-age=0\r\n" "Pragma: no-cache\r\n" diff --git a/src/httplib_send_options.c b/src/httplib_send_options.c index 2d1f2145..f82f2b7d 100644 --- a/src/httplib_send_options.c +++ b/src/httplib_send_options.c @@ -29,19 +29,19 @@ #include "httplib_utils.h" /* - * void XX_httplib_send_options( struct httplib_connection *conn ); + * void XX_httplib_send_options( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_send_options() sends a list of allowed options a * client can use to connect to the server. */ -void XX_httplib_send_options( struct httplib_connection *conn ) { +void XX_httplib_send_options( const struct httplib_context *ctx, struct httplib_connection *conn ) { char date[64]; time_t curtime; - if ( conn == NULL || conn->ctx == NULL ) return; - if ( conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL ) return; + if ( ctx->document_root == NULL ) return; curtime = time( NULL ); conn->status_code = 200; @@ -49,7 +49,7 @@ void XX_httplib_send_options( struct httplib_connection *conn ) { XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - httplib_printf( conn, + httplib_printf( ctx, conn, "HTTP/1.1 200 OK\r\n" "Date: %s\r\n" /* TODO: "Cache-Control" (?) */ @@ -58,6 +58,6 @@ void XX_httplib_send_options( struct httplib_connection *conn ) { "PROPFIND, MKCOL\r\n" "DAV: 1\r\n\r\n", date, - XX_httplib_suggest_connection_header( conn ) ); + XX_httplib_suggest_connection_header( ctx, conn ) ); } /* XX_httplib_send_options */ diff --git a/src/httplib_send_static_cache_header.c b/src/httplib_send_static_cache_header.c index 49e5a51b..90aa3faa 100644 --- a/src/httplib_send_static_cache_header.c +++ b/src/httplib_send_static_cache_header.c @@ -28,22 +28,22 @@ #include "httplib_main.h" /* - * int XX_httlib_send_static_cache_header( struct httplib_connection *conn ); + * int XX_httlib_send_static_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn ); * * The function XX_httplib_send_static_cache_header() sends cache headers * depending on the cache setting of the current context. */ -int XX_httplib_send_static_cache_header( struct httplib_connection *conn ) { +int XX_httplib_send_static_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn ) { - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; /* * Read the server config to check how long a file may be cached. * The configuration is in seconds. */ - if ( conn->ctx->static_file_max_age <= 0 ) { + if ( ctx->static_file_max_age <= 0 ) { /* * 0 means "do not cache". All values <0 are reserved @@ -52,7 +52,7 @@ int XX_httplib_send_static_cache_header( struct httplib_connection *conn ) { * max-age=0, but also pragmas and Expires headers. */ - return XX_httplib_send_no_cache_header( conn ); + return XX_httplib_send_no_cache_header( ctx, conn ); } /* @@ -66,6 +66,6 @@ int XX_httplib_send_static_cache_header( struct httplib_connection *conn ) { * as undefined. */ - return httplib_printf( conn, "Cache-Control: max-age=%d\r\n", conn->ctx->static_file_max_age ); + return httplib_printf( ctx, conn, "Cache-Control: max-age=%d\r\n", ctx->static_file_max_age ); } /* XX_httplib_send_static_cache_header */ diff --git a/src/httplib_send_websocket_handshake.c b/src/httplib_send_websocket_handshake.c index 6c668558..e3646a89 100644 --- a/src/httplib_send_websocket_handshake.c +++ b/src/httplib_send_websocket_handshake.c @@ -32,13 +32,13 @@ #define B64_SHA_LEN (sizeof(sha)*2) /* - * int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const char *websock_key ); + * int XX_httplib_send_websocket_handshake( const struct httplib_context *ctx, struct httplib_connection *conn, const char *websock_key ); * * The function XX_httplib_send_websocket_handshake() sends a handshake over * a websocket connection. */ -int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const char *websock_key ) { +int XX_httplib_send_websocket_handshake( const struct httplib_context *ctx, struct httplib_connection *conn, const char *websock_key ) { static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const char *protocol; @@ -48,13 +48,15 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const SHA1_CTX sha_ctx; bool truncated; + if ( ctx == NULL ) return 0; + protocol = NULL; /* * Calculate Sec-WebSocket-Accept reply from Sec-WebSocket-Key. */ - XX_httplib_snprintf( conn, &truncated, buf, sizeof(buf), "%s%s", websock_key, magic ); + XX_httplib_snprintf( ctx, conn, &truncated, buf, sizeof(buf), "%s%s", websock_key, magic ); if ( truncated ) { conn->must_close = true; @@ -66,7 +68,7 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const SHA1Final( (unsigned char *)sha, &sha_ctx ); httplib_base64_encode( (unsigned char *)sha, sizeof(sha), b64_sha, B64_SHA_LEN ); - httplib_printf( conn, + httplib_printf( ctx, conn, "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" @@ -87,7 +89,7 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const * Just a single protocol -> accept it. */ - httplib_printf(conn, "Sec-WebSocket-Protocol: %s\r\n\r\n", protocol); + httplib_printf( ctx, conn, "Sec-WebSocket-Protocol: %s\r\n\r\n", protocol ); } else { @@ -103,14 +105,14 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const * no subprotocol is acceptable. */ - httplib_printf( conn, "Sec-WebSocket-Protocol: %.*s\r\n\r\n", (int)(sep - protocol), protocol ); + httplib_printf( ctx, conn, "Sec-WebSocket-Protocol: %.*s\r\n\r\n", (int)(sep - protocol), protocol ); } /* * TODO: Real subprotocol negotiation instead of just taking the first * websocket subprotocol suggested by the client. */ } - else httplib_printf( conn, "%s", "\r\n" ); + else httplib_printf( ctx, conn, "%s", "\r\n" ); return 1; diff --git a/src/httplib_set_gpass_option.c b/src/httplib_set_gpass_option.c index cf58d383..20394aaa 100644 --- a/src/httplib_set_gpass_option.c +++ b/src/httplib_set_gpass_option.c @@ -45,7 +45,7 @@ bool XX_httplib_set_gpass_option( struct httplib_context *ctx ) { path = ctx->global_auth_file; - if ( path != NULL && ! XX_httplib_stat( NULL, path, &file ) ) { + if ( path != NULL && ! XX_httplib_stat( ctx, NULL, path, &file ) ) { httplib_cry( DEBUG_LEVEL_ERROR, ctx, NULL, "%s: cannot open %s: %s", __func__, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return false; diff --git a/src/httplib_set_thread_name.c b/src/httplib_set_thread_name.c index f12626dd..72dc15ff 100644 --- a/src/httplib_set_thread_name.c +++ b/src/httplib_set_thread_name.c @@ -54,11 +54,11 @@ typedef struct tagTHREADNAME_INFO { #endif /* __linux__ */ -void XX_httplib_set_thread_name( const char *name ) { +void XX_httplib_set_thread_name( const struct httplib_context *ctx, const char *name ) { char thread_name[16+1]; /* 16 = Max. thread length in Linux/OSX/.. */ - XX_httplib_snprintf( NULL, NULL, thread_name, sizeof(thread_name), "libhttp-%s", name ); + XX_httplib_snprintf( ctx, NULL, NULL, thread_name, sizeof(thread_name), "libhttp-%s", name ); #if defined(_WIN32) diff --git a/src/httplib_should_decode_url.c b/src/httplib_should_decode_url.c index 8930dcac..56db98b9 100644 --- a/src/httplib_should_decode_url.c +++ b/src/httplib_should_decode_url.c @@ -24,8 +24,8 @@ #include "httplib_main.h" -bool XX_httplib_should_decode_url( const struct httplib_connection *conn ) { +bool XX_httplib_should_decode_url( const struct httplib_context *ctx ) { - return ( conn != NULL && conn->ctx != NULL && conn->ctx->decode_url ); + return ( ctx != NULL && ctx->decode_url ); } /* XX_httplib_should_decode_url */ diff --git a/src/httplib_should_keep_alive.c b/src/httplib_should_keep_alive.c index e08950f5..930a21c8 100644 --- a/src/httplib_should_keep_alive.c +++ b/src/httplib_should_keep_alive.c @@ -25,7 +25,7 @@ #include "httplib_main.h" /* - * bool XX_httplib_should_keep_alive( const struct httplib_connection *conn ); + * bool XX_httplib_should_keep_alive( const struct httplib_context *ctx, const struct httplib_connection *conn ); * * The function XX_httplib_should_keep_alive() returns true if the connection * should be kept alive and false if it should be closed. @@ -35,19 +35,19 @@ * request parsing failed. */ -bool XX_httplib_should_keep_alive( const struct httplib_connection *conn ) { +bool XX_httplib_should_keep_alive( const struct httplib_context *ctx, const struct httplib_connection *conn ) { const char *http_version; const char *header; - if ( conn == NULL || conn->ctx == NULL ) return false; + if ( ctx == NULL || conn == NULL ) return false; http_version = conn->request_info.http_version; header = httplib_get_header( conn, "Connection" ); if ( conn->must_close ) return false; if ( conn->status_code == 401 ) return false; - if ( ! conn->ctx->enable_keep_alive ) return false; + if ( ! ctx->enable_keep_alive ) return false; if ( header != NULL && ! XX_httplib_header_has_option( header, "keep-alive" ) ) return false; if ( header == NULL && http_version != NULL && strcmp( http_version, "1.1" ) ) return false; diff --git a/src/httplib_snprintf.c b/src/httplib_snprintf.c index fe62e3d9..1533b805 100644 --- a/src/httplib_snprintf.c +++ b/src/httplib_snprintf.c @@ -29,19 +29,19 @@ #include "httplib_string.h" /* - * void XX_httplib_snprintf( const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, ... ); + * void XX_httplib_snprintf( const struct httplib_context *ctx, const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, ... ); * * The function XX_httplib_snprintf() is an internal function to send a string * to a connection. The string can be formated with a format string and * parameters in the same way as the snprintf function works. */ -void XX_httplib_snprintf( const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, ... ) { +void XX_httplib_snprintf( const struct httplib_context *ctx, const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, ... ) { va_list ap; va_start( ap, fmt ); - XX_httplib_vsnprintf( conn, truncated, buf, buflen, fmt, ap ); + XX_httplib_vsnprintf( ctx, conn, truncated, buf, buflen, fmt, ap ); va_end( ap ); } /* XX_httplib_snprintf */ diff --git a/src/httplib_spawn_process.c b/src/httplib_spawn_process.c index 224e5f89..4c14f221 100644 --- a/src/httplib_spawn_process.c +++ b/src/httplib_spawn_process.c @@ -40,7 +40,7 @@ static void trim_trailing_whitespaces( char *s ) { } /* trim_trailing_whitespaces */ -pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ) { +pid_t XX_httplib_spawn_process( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ) { HANDLE me; char *p; @@ -56,7 +56,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro UNUSED_PARAMETER(envp); - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; memset( &si, 0, sizeof(si) ); si.cb = sizeof(si); @@ -82,7 +82,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro * If CGI file is a script, try to read the interpreter line */ - interp = conn->ctx->cgi_interpreter; + interp = ctx->cgi_interpreter; if ( interp == NULL ) { @@ -133,7 +133,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro if ( CreateProcessA( NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi ) == 0 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CreateProcess(%s): %ld", __func__, cmdline, (long)ERRNO); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CreateProcess(%s): %ld", __func__, cmdline, (long)ERRNO); pi.hProcess = (pid_t)-1; /* @@ -157,7 +157,7 @@ spawn_cleanup: #else /* _WIN32 */ #ifndef NO_CGI -pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ) { +pid_t XX_httplib_spawn_process( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ) { pid_t pid; const char *interp; @@ -165,7 +165,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro UNUSED_PARAMETER(envblk); - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; if ( (pid = fork()) == -1 ) { @@ -173,7 +173,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro * Parent */ - XX_httplib_send_http_error( conn, 500, "Error: Creating CGI process\nfork(): %s", httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Creating CGI process\nfork(): %s", httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else if ( pid == 0 ) { @@ -182,10 +182,10 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro * Child */ - if ( chdir( dir ) != 0 ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: chdir(%s): %s", __func__, dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else if ( dup2( fdin[0], 0 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: dup2(%d, 0): %s", __func__, fdin[0], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else if ( dup2( fdout[1], 1 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: dup2(%d, 1): %s", __func__, fdout[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); - else if ( dup2( fderr[1], 2 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: dup2(%d, 2): %s", __func__, fderr[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + if ( chdir( dir ) != 0 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: chdir(%s): %s", __func__, dir, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fdin[0], 0 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: dup2(%d, 0): %s", __func__, fdin[0], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fdout[1], 1 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: dup2(%d, 1): %s", __func__, fdout[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + else if ( dup2( fderr[1], 2 ) == -1 ) httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: dup2(%d, 2): %s", __func__, fderr[1], httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); else { /* * Keep stderr and stdout in two different pipes. @@ -215,17 +215,17 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro signal( SIGCHLD, SIG_DFL ); - interp = conn->ctx->cgi_interpreter; + interp = ctx->cgi_interpreter; if ( interp == NULL ) { execle( prog, prog, NULL, envp ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: execle(%s): %s", __func__, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: execle(%s): %s", __func__, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { execle( interp, interp, prog, NULL, envp ); - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: execle(%s %s): %s", __func__, interp, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: execle(%s %s): %s", __func__, interp, prog, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } } diff --git a/src/httplib_ssi.c b/src/httplib_ssi.c index 02a7a079..315ed9fe 100644 --- a/src/httplib_ssi.c +++ b/src/httplib_ssi.c @@ -29,10 +29,10 @@ #include "httplib_string.h" #include "httplib_utils.h" -static void send_ssi_file(struct httplib_connection *, const char *, struct file *, int); +static void send_ssi_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *, struct file *, int ); -static void do_ssi_include( struct httplib_connection *conn, const char *ssi, char *tag, int include_level ) { +static void do_ssi_include( const struct httplib_context *ctx, struct httplib_connection *conn, const char *ssi, char *tag, int include_level ) { char file_name[MG_BUF_LEN]; char path[512]; @@ -44,7 +44,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch size_t len; bool truncated; - if ( conn == NULL || conn->ctx == NULL || conn->ctx->document_root == NULL ) return; + if ( ctx == NULL || conn == NULL || ctx->document_root == NULL ) return; truncated = false; @@ -61,9 +61,9 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch */ file_name[511] = 0; - doc_root = conn->ctx->document_root; + doc_root = ctx->document_root; - XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s/%s", doc_root, file_name ); + XX_httplib_snprintf( ctx, conn, &truncated, path, sizeof(path), "%s/%s", doc_root, file_name ); } @@ -75,7 +75,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch */ file_name[511] = 0; - XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s", file_name ); + XX_httplib_snprintf( ctx, conn, &truncated, path, sizeof(path), "%s", file_name ); } @@ -86,40 +86,40 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch */ file_name[511] = 0; - XX_httplib_snprintf( conn, &truncated, path, sizeof(path), "%s", ssi ); + XX_httplib_snprintf( ctx, conn, &truncated, path, sizeof(path), "%s", ssi ); if ( ! truncated ) { if ( (p = strrchr( path, '/' )) != NULL) p[1] = '\0'; len = strlen( path ); - XX_httplib_snprintf( conn, &truncated, path + len, sizeof(path) - len, "%s", file_name ); + XX_httplib_snprintf( ctx, conn, &truncated, path + len, sizeof(path) - len, "%s", file_name ); } } else { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: bad SSI #include: [%s]", __func__, tag ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: bad SSI #include: [%s]", __func__, tag ); return; } if ( truncated ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: SSI #include path length overflow: [%s]", __func__, tag ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: SSI #include path length overflow: [%s]", __func__, tag ); return; } - if ( ! XX_httplib_fopen( conn, path, "rb", &file ) ) { + if ( ! XX_httplib_fopen( ctx, conn, path, "rb", &file ) ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: cannot open SSI #include: [%s]: fopen(%s): %s", __func__, tag, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: cannot open SSI #include: [%s]: fopen(%s): %s", __func__, tag, path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); return; } - XX_httplib_fclose_on_exec( & file, conn ); + XX_httplib_fclose_on_exec( ctx, &file, conn ); - ssi_ext = conn->ctx->ssi_pattern; + ssi_ext = ctx->ssi_pattern; - if ( ssi_ext != NULL && XX_httplib_match_prefix( ssi_ext, strlen( ssi_ext ), path ) > 0 ) send_ssi_file( conn, path, &file, include_level+1 ); - else XX_httplib_send_file_data( conn, &file, 0, INT64_MAX ); + if ( ssi_ext != NULL && XX_httplib_match_prefix( ssi_ext, strlen( ssi_ext ), path ) > 0 ) send_ssi_file( ctx, conn, path, &file, include_level+1 ); + else XX_httplib_send_file_data( ctx, conn, &file, 0, INT64_MAX ); XX_httplib_fclose( & file ); @@ -127,7 +127,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch #if !defined(NO_POPEN) -static void do_ssi_exec( struct httplib_connection *conn, char *tag ) { +static void do_ssi_exec( const struct httplib_context *ctx, struct httplib_connection *conn, char *tag ) { char cmd[1024] = ""; char error_string[ERROR_STRING_LEN]; @@ -135,18 +135,18 @@ static void do_ssi_exec( struct httplib_connection *conn, char *tag ) { if ( sscanf(tag, " \"%1023[^\"]\"", cmd) != 1 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: bad SSI #exec: [%s]", __func__, tag ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: bad SSI #exec: [%s]", __func__, tag ); } else { cmd[1023] = 0; if ( (file.fp = popen( cmd, "r" ) ) == NULL ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: cannot SSI #exec: [%s]: %s", __func__, cmd, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: cannot SSI #exec: [%s]: %s", __func__, cmd, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { - XX_httplib_send_file_data( conn, &file, 0, INT64_MAX ); + XX_httplib_send_file_data( ctx, conn, &file, 0, INT64_MAX ); pclose( file.fp ); } } @@ -165,7 +165,7 @@ static int httplib_fgetc( struct file *filep, int offset ) { } /* httplib_fgetc */ -static void send_ssi_file( struct httplib_connection *conn, const char *path, struct file *filep, int include_level ) { +static void send_ssi_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep, int include_level ) { char buf[MG_BUF_LEN]; int ch; @@ -173,9 +173,9 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st int len; int in_ssi_tag; - if ( include_level > conn->ctx->ssi_include_depth ) { + if ( include_level > ctx->ssi_include_depth ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: SSI #include level is too deep (%s)", __func__, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: SSI #include level is too deep (%s)", __func__, path ); return; } @@ -199,21 +199,21 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st * Not an SSI tag, pass it */ - httplib_write( conn, buf, (size_t)len ); + httplib_write( ctx, conn, buf, (size_t)len ); } else { if ( ! memcmp( buf + 5, "include", 7 ) ) { - do_ssi_include( conn, path, buf + 12, include_level ); + do_ssi_include( ctx, conn, path, buf+12, include_level ); + } #if !defined(NO_POPEN) - } - else if (!memcmp(buf + 5, "exec", 4)) { + else if ( ! memcmp( buf+5, "exec", 4 ) ) { - do_ssi_exec(conn, buf + 9); -#endif /* !NO_POPEN */ + do_ssi_exec( ctx, conn, buf+9 ); } - else httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: %s: unknown SSI command: \"%s\"", __func__, path, buf ); +#endif /* !NO_POPEN */ + else httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: %s: unknown SSI command: \"%s\"", __func__, path, buf ); } len = 0; @@ -232,7 +232,7 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st else if ( len == (int)sizeof(buf) - 2 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: %s: SSI tag is too large", __func__, path ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: %s: SSI tag is too large", __func__, path ); len = 0; } @@ -243,7 +243,7 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st in_ssi_tag = 1; - if ( len > 0 ) httplib_write( conn, buf, (size_t)len ); + if ( len > 0 ) httplib_write( ctx, conn, buf, (size_t)len ); len = 0; buf[len++] = (char)(ch & 0xff); @@ -254,7 +254,7 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st if (len == (int)sizeof(buf)) { - httplib_write(conn, buf, (size_t)len); + httplib_write( ctx, conn, buf, (size_t)len ); len = 0; } } @@ -264,12 +264,12 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st * Send the rest of buffered data */ - if (len > 0) httplib_write( conn, buf, (size_t)len ); + if (len > 0) httplib_write( ctx, conn, buf, (size_t)len ); } /* send_ssi_file */ -void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const char *path, struct file *filep ) { +void XX_httplib_handle_ssi_file_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ) { char date[64]; char error_string[ERROR_STRING_LEN]; @@ -278,7 +278,7 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const const char *cors2; const char *cors3; - if ( conn == NULL || conn->ctx == NULL || path == NULL || filep == NULL ) return; + if ( ctx == NULL || conn == NULL || path == NULL || filep == NULL ) return; curtime = time( NULL ); @@ -289,7 +289,7 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const */ cors1 = "Access-Control-Allow-Origin: "; - cors2 = ( conn->ctx->access_control_allow_origin != NULL ) ? conn->ctx->access_control_allow_origin : ""; + cors2 = ( ctx->access_control_allow_origin != NULL ) ? ctx->access_control_allow_origin : ""; cors3 = "\r\n"; } @@ -299,25 +299,25 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const cors3 = ""; } - if ( ! XX_httplib_fopen( conn, path, "rb", filep ) ) { + if ( ! XX_httplib_fopen( ctx, conn, path, "rb", filep ) ) { /* * File exists (precondition for calling this function), * but can not be opened by the server. */ - XX_httplib_send_http_error(conn, 500, "Error: Cannot read file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); + XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot read file\nfopen(%s): %s", path, httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ) ); } else { conn->must_close = true; XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); - XX_httplib_fclose_on_exec( filep, conn ); - httplib_printf(conn, "HTTP/1.1 200 OK\r\n"); - XX_httplib_send_no_cache_header( conn ); - httplib_printf( conn, "%s%s%s" "Date: %s\r\n" "Content-Type: text/html\r\n" "Connection: %s\r\n\r\n", cors1, cors2, cors3, date, XX_httplib_suggest_connection_header( conn ) ); - send_ssi_file( conn, path, filep, 0 ); + XX_httplib_fclose_on_exec( ctx, filep, conn ); + httplib_printf( ctx, conn, "HTTP/1.1 200 OK\r\n" ); + XX_httplib_send_no_cache_header( ctx, conn ); + httplib_printf( ctx, conn, "%s%s%s" "Date: %s\r\n" "Content-Type: text/html\r\n" "Connection: %s\r\n\r\n", cors1, cors2, cors3, date, XX_httplib_suggest_connection_header( ctx, conn ) ); + send_ssi_file( ctx, conn, path, filep, 0 ); XX_httplib_fclose( filep ); } diff --git a/src/httplib_ssl.h b/src/httplib_ssl.h index f0dbfe96..818b9206 100644 --- a/src/httplib_ssl.h +++ b/src/httplib_ssl.h @@ -140,8 +140,8 @@ void XX_httplib_ssl_get_client_cert_info( struct httplib_connection *conn ); long XX_httplib_ssl_get_protocol( int version_id ); unsigned long XX_httplib_ssl_id_callback( void ); void XX_httplib_ssl_locking_callback( int mode, int mutex_num, const char *file, int line ); -int XX_httplib_ssl_use_pem_file( struct httplib_context *ctx, const char *pem ); -int XX_httplib_sslize( struct httplib_connection *conn, SSL_CTX *s, int (*func)(SSL *) ); +int XX_httplib_ssl_use_pem_file( const struct httplib_context *ctx, const char *pem ); +int XX_httplib_sslize( const struct httplib_context *ctx, struct httplib_connection *conn, SSL_CTX *s, int (*func)(SSL *) ); void XX_httplib_tls_dtor( void *key ); void XX_httplib_uninitialize_ssl( struct httplib_context *ctx ); diff --git a/src/httplib_ssl_use_pem_file.c b/src/httplib_ssl_use_pem_file.c index 9c0ee76b..7608b50d 100644 --- a/src/httplib_ssl_use_pem_file.c +++ b/src/httplib_ssl_use_pem_file.c @@ -29,7 +29,7 @@ #include "httplib_ssl.h" /* - * int XX_httplib_ssl_use_pem_file( struct httplib_context *ctx, const char *pem ); + * int XX_httplib_ssl_use_pem_file( const struct httplib_context *ctx, const char *pem ); * * The function XX_httplib_ssl_use_pem_file() tries to use a certificate which * is passed as a parameter with the filename of the certificate. @@ -37,7 +37,7 @@ #if ! defined(NO_SSL) -int XX_httplib_ssl_use_pem_file( struct httplib_context *ctx, const char *pem ) { +int XX_httplib_ssl_use_pem_file( const struct httplib_context *ctx, const char *pem ) { if ( ctx == NULL || pem == NULL ) return 0; diff --git a/src/httplib_sslize.c b/src/httplib_sslize.c index 4f21d03f..3e0ff392 100644 --- a/src/httplib_sslize.c +++ b/src/httplib_sslize.c @@ -36,17 +36,17 @@ #if !defined(NO_SSL) -int XX_httplib_sslize( struct httplib_connection *conn, SSL_CTX *s, int (*func)(SSL *) ) { +int XX_httplib_sslize( const struct httplib_context *ctx, struct httplib_connection *conn, SSL_CTX *s, int (*func)(SSL *) ) { int ret; int err; unsigned i; - if ( conn == NULL || conn->ctx == NULL ) return 0; + if ( ctx == NULL || conn == NULL ) return 0; - if ( conn->ctx->ssl_short_trust ) { + if ( ctx->ssl_short_trust ) { - int trust_ret = XX_httplib_refresh_trust( conn ); + int trust_ret = XX_httplib_refresh_trust( ctx, conn ); if ( ! trust_ret ) return trust_ret; } diff --git a/src/httplib_stat.c b/src/httplib_stat.c index f1b547ed..85142e8a 100644 --- a/src/httplib_stat.c +++ b/src/httplib_stat.c @@ -48,7 +48,7 @@ static bool path_cannot_disclose_cgi( const char *path ) { } -int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct file *filep ) { +int XX_httplib_stat( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ) { wchar_t wbuf[PATH_MAX]; WIN32_FILE_ATTRIBUTE_DATA info; @@ -71,7 +71,7 @@ int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct f * last_modified = now ... assumes the file may change during runtime, * so every XX_httplib_fopen call may return different data * - * last_modified = conn->ctx.start_time; + * last_modified = ctx.start_time; * May be used it the data does not change during runtime. This allows * browser caching. Since we do not know, we have to assume the file * in memory may change. @@ -121,7 +121,7 @@ int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct f #else -int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct file *filep ) { +int XX_httplib_stat( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path, struct file *filep ) { struct stat st; @@ -129,7 +129,7 @@ int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct f memset( filep, 0, sizeof(*filep) ); - if ( conn != NULL && XX_httplib_is_file_in_memory( conn, path, filep ) ) return 1; + if ( conn != NULL && ctx != NULL && XX_httplib_is_file_in_memory( ctx, conn, path, filep ) ) return 1; if ( stat( path, &st ) == 0 ) { diff --git a/src/httplib_store_body.c b/src/httplib_store_body.c index 951da953..a9fa6382 100644 --- a/src/httplib_store_body.c +++ b/src/httplib_store_body.c @@ -35,7 +35,7 @@ * negative number to indicate a failure. */ -int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) { +int64_t httplib_store_body( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path ) { char buf[MG_BUF_LEN]; int64_t len; @@ -43,15 +43,17 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) int n; struct file fi; + if ( ctx == NULL ) return -1; + len = 0; if ( conn->consumed_content != 0 ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Contents already consumed", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Contents already consumed", __func__ ); return -11; } - ret = XX_httplib_put_dir( conn, path ); + ret = XX_httplib_put_dir( ctx, conn, path ); if ( ret < 0 ) { /* @@ -71,9 +73,9 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) return 0; } - if ( XX_httplib_fopen( conn, path, "w", & fi ) == 0 ) return -12; + if ( XX_httplib_fopen( ctx, conn, path, "w", & fi ) == 0 ) return -12; - ret = httplib_read( conn, buf, sizeof(buf) ); + ret = httplib_read( ctx, conn, buf, sizeof(buf) ); while ( ret > 0 ) { @@ -81,15 +83,15 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) if ( n != ret ) { XX_httplib_fclose( & fi ); - XX_httplib_remove_bad_file( conn, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); return -13; } - ret = httplib_read( conn, buf, sizeof(buf) ); + ret = httplib_read( ctx, conn, buf, sizeof(buf) ); } if ( XX_httplib_fclose( & fi ) != 0 ) { - XX_httplib_remove_bad_file( conn, path ); + XX_httplib_remove_bad_file( ctx, conn, path ); return -14; } diff --git a/src/httplib_string.h b/src/httplib_string.h index cff1f514..6d91f809 100644 --- a/src/httplib_string.h +++ b/src/httplib_string.h @@ -22,6 +22,6 @@ -void XX_httplib_snprintf( const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(5, 6); -int XX_httplib_vprintf( struct httplib_connection *conn, const char *fmt, va_list ap ); -void XX_httplib_vsnprintf( const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ); +void XX_httplib_snprintf( const struct httplib_context *ctx, const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(6, 7); +int XX_httplib_vprintf( const struct httplib_context *ctx, struct httplib_connection *conn, const char *fmt, va_list ap ); +void XX_httplib_vsnprintf( const struct httplib_context *ctx, const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ); diff --git a/src/httplib_substitute_index_file.c b/src/httplib_substitute_index_file.c index 68f1d88e..e8d7a784 100644 --- a/src/httplib_substitute_index_file.c +++ b/src/httplib_substitute_index_file.c @@ -29,7 +29,7 @@ #include "httplib_string.h" /* - * bool XX_httplib_substitute_index_file( struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ); + * bool XX_httplib_substitute_index_file( const struct httplib_context *ctx, struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ); * * The function XX_httplib_substiture_index_file() tries to find an index file * matching a given directory path. The function returns true of an index file @@ -37,7 +37,7 @@ * located, it's stats are returnd in stp. */ -int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ) { +int XX_httplib_substitute_index_file( const struct httplib_context *ctx, struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ) { const char *list; struct file file = STRUCT_FILE_INITIALIZER; @@ -45,10 +45,10 @@ int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *pat size_t n; bool found; - if ( conn == NULL || conn->ctx == NULL || path == NULL ) return 0; - if ( conn->ctx->document_root == NULL ) return 0; + if ( ctx == NULL || conn == NULL || path == NULL ) return 0; + if ( ctx->document_root == NULL ) return 0; - list = conn->ctx->index_files; + list = ctx->index_files; n = strlen( path ); found = false; @@ -84,7 +84,7 @@ int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *pat * Does it exist? */ - if ( XX_httplib_stat( conn, path, &file ) ) { + if ( XX_httplib_stat( ctx, conn, path, &file ) ) { /* * Yes it does, break the loop diff --git a/src/httplib_suggest_connection_header.c b/src/httplib_suggest_connection_header.c index 208d2dda..01d9452c 100644 --- a/src/httplib_suggest_connection_header.c +++ b/src/httplib_suggest_connection_header.c @@ -28,15 +28,15 @@ #include "httplib_main.h" /* - * const char *XX_httplib_suggest_connection_header( const struct httlib_connection *conn ); + * const char *XX_httplib_suggest_connection_header( const struct httplib_context *ctx, const struct httlib_connection *conn ); * * Based on the connection type, the function XX_httplib_connection_header() * returns a string to be used in the header which suggests the connection to * be either closed, or kept alive for further requests. */ -const char *XX_httplib_suggest_connection_header( const struct httplib_connection *conn ) { +const char *XX_httplib_suggest_connection_header( const struct httplib_context *ctx, const struct httplib_connection *conn ) { - return XX_httplib_should_keep_alive( conn ) ? "keep-alive" : "close"; + return XX_httplib_should_keep_alive( ctx, conn ) ? "keep-alive" : "close"; } /* XX_httplib_suggest_connection_header */ diff --git a/src/httplib_utils.h b/src/httplib_utils.h index a0515af0..fa6dd3be 100644 --- a/src/httplib_utils.h +++ b/src/httplib_utils.h @@ -22,7 +22,7 @@ #define LEAP_YEAR(x) ( ((x)%4) == 0 && ( ((x)%100) != 0 || ((x)%400) == 0 ) ) -void XX_httplib_addenv( struct cgi_environment *env, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(2, 3); +void XX_httplib_addenv( const struct httplib_context *ctx, struct cgi_environment *env, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(3, 4); double XX_httplib_difftimespec( const struct timespec *ts_now, const struct timespec *ts_before ); void XX_httplib_gmt_time_string( char *buf, size_t buf_len, time_t *t ); int XX_httplib_inet_pton( int af, const char *src, void *dst, size_t dstlen ); diff --git a/src/httplib_vprintf.c b/src/httplib_vprintf.c index 650c8e2c..c1dbffe0 100644 --- a/src/httplib_vprintf.c +++ b/src/httplib_vprintf.c @@ -145,7 +145,7 @@ static int alloc_vprintf( char **out_buf, char *prealloc_buf, size_t prealloc_si } /* alloc_vprintf */ -int XX_httplib_vprintf( struct httplib_connection *conn, const char *fmt, va_list ap ) { +int XX_httplib_vprintf( const struct httplib_context *ctx, struct httplib_connection *conn, const char *fmt, va_list ap ) { char mem[MG_BUF_LEN]; char *buf; @@ -153,7 +153,7 @@ int XX_httplib_vprintf( struct httplib_connection *conn, const char *fmt, va_lis buf = NULL; - if ( (len = alloc_vprintf( &buf, mem, sizeof(mem), fmt, ap )) > 0 ) len = httplib_write( conn, buf, (size_t)len ); + if ( (len = alloc_vprintf( &buf, mem, sizeof(mem), fmt, ap )) > 0 ) len = httplib_write( ctx, conn, buf, (size_t)len ); if ( buf != mem ) buf = httplib_free( buf ); return len; diff --git a/src/httplib_vsnprintf.c b/src/httplib_vsnprintf.c index aebc3dcd..2c063870 100644 --- a/src/httplib_vsnprintf.c +++ b/src/httplib_vsnprintf.c @@ -33,7 +33,7 @@ * Report errors if length is exceeded. */ -void XX_httplib_vsnprintf( const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ) { +void XX_httplib_vsnprintf( const struct httplib_context *ctx, const struct httplib_connection *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ) { int n; bool ok; @@ -60,7 +60,7 @@ void XX_httplib_vsnprintf( const struct httplib_connection *conn, bool *truncate else { if ( truncated != NULL ) *truncated = true; - if ( conn != NULL && conn->ctx != NULL ) httplib_cry( DEBUG_LEVEL_WARNING, conn->ctx, conn, "%s: truncating vsnprintf buffer: [%.*s]", __func__, (int)((buflen > 200) ? 200 : (buflen - 1)), buf ); + if ( ctx != NULL && conn != NULL) httplib_cry( DEBUG_LEVEL_WARNING, ctx, conn, "%s: truncating vsnprintf buffer: [%.*s]", __func__, (int)((buflen > 200) ? 200 : (buflen - 1)), buf ); n = (int)buflen - 1; } buf[n] = '\0'; diff --git a/src/httplib_websocket_client_thread.c b/src/httplib_websocket_client_thread.c index 0dca836d..a0351350 100644 --- a/src/httplib_websocket_client_thread.c +++ b/src/httplib_websocket_client_thread.c @@ -20,9 +20,6 @@ * 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. - * - * ============ - * Release: 2.0 */ #include "httplib_main.h" @@ -31,32 +28,41 @@ * LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ); * * The function XX_httplib_websocket_client_thread() is the worker thread which - * connects as a client to a remote websocket server. + * connects as a client to a remote websocket server. When finished, the + * function frees the memory associated with the thread and the connection, but + * it does not free any context data, because the context can be reused for + * another connection. + * + * To signal the calling application that the context is in use or can be + * reused, a status flag is set to the appropriate value. */ LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ) { struct websocket_client_thread_data *cdata; + struct httplib_context *ctx; + struct httplib_connection *conn; - cdata = data; - if ( cdata == NULL || cdata->conn == NULL || cdata->conn->ctx == NULL ) return LIBHTTP_THREAD_RETNULL; + if ( (cdata = data ) == NULL ) return LIBHTTP_THREAD_RETNULL; + if ( (conn = cdata->conn) == NULL ) return LIBHTTP_THREAD_RETNULL; + if ( (ctx = cdata->ctx ) == NULL ) return LIBHTTP_THREAD_RETNULL; - cdata->conn->ctx->status = CTX_STATUS_RUNNING; + ctx->status = CTX_STATUS_RUNNING; - XX_httplib_set_thread_name( "ws-client" ); + XX_httplib_set_thread_name( ctx, "ws-client" ); - if ( cdata->conn->ctx->callbacks.init_thread != NULL ) cdata->conn->ctx->callbacks.init_thread( cdata->conn->ctx, 3 ); + if ( ctx->callbacks.init_thread != NULL ) ctx->callbacks.init_thread( ctx, 3 ); - XX_httplib_read_websocket( cdata->conn, cdata->data_handler, cdata->callback_data ); + XX_httplib_read_websocket( ctx, conn, cdata->data_handler, cdata->callback_data ); - if ( cdata->close_handler != NULL ) cdata->close_handler( cdata->conn, cdata->callback_data ); + if ( cdata->close_handler != NULL ) cdata->close_handler( conn, cdata->callback_data ); - cdata->conn->ctx->workerthreadids = httplib_free( cdata->conn->ctx->workerthreadids ); - cdata->conn = httplib_free( cdata->conn ); - cdata = httplib_free( cdata ); - cdata->conn->ctx->user_data = NULL; - cdata->conn->ctx->num_threads = 0; - cdata->conn->ctx->status = CTX_STATUS_TERMINATED; + ctx->workerthreadids = httplib_free( ctx->workerthreadids ); + conn = httplib_free( conn ); + cdata = httplib_free( cdata ); + ctx->user_data = NULL; + ctx->num_threads = 0; + ctx->status = CTX_STATUS_TERMINATED; return LIBHTTP_THREAD_RETNULL; diff --git a/src/httplib_websocket_client_write.c b/src/httplib_websocket_client_write.c index 05c62abe..f522cdc1 100644 --- a/src/httplib_websocket_client_write.c +++ b/src/httplib_websocket_client_write.c @@ -38,13 +38,13 @@ static void mask_data( const char *in, size_t in_len, uint32_t masking_key, char * otherwise the amount of bytes written. */ -int httplib_websocket_client_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ) { +int httplib_websocket_client_write( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ) { int retval; char *masked_data; uint32_t masking_key; - if ( conn == NULL || conn->ctx == NULL ) return -1; + if ( ctx == NULL || conn == NULL ) return -1; retval = -1; masked_data = httplib_malloc( ((dataLen + 7) / 4) * 4 ); @@ -52,13 +52,13 @@ int httplib_websocket_client_write( struct httplib_connection *conn, int opcode, if ( masked_data == NULL ) { - httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: cannot allocate buffer for masked websocket response: Out of memory", __func__ ); + httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: cannot allocate buffer for masked websocket response: Out of memory", __func__ ); return -1; } mask_data( data, dataLen, masking_key, masked_data ); - retval = XX_httplib_websocket_write_exec( conn, opcode, masked_data, dataLen, masking_key ); + retval = XX_httplib_websocket_write_exec( ctx, conn, opcode, masked_data, dataLen, masking_key ); masked_data = httplib_free( masked_data ); return retval; diff --git a/src/httplib_websocket_write.c b/src/httplib_websocket_write.c index 64eb6c50..ee6296cf 100644 --- a/src/httplib_websocket_write.c +++ b/src/httplib_websocket_write.c @@ -20,22 +20,19 @@ * 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. - * - * ============ - * Release: 2.0 */ #include "httplib_main.h" /* - * int httplib_websocket_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ); + * int httplib_websocket_write( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ); * * The function httplib_websocket_write() writes data over a websocket * connection. */ -int httplib_websocket_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ) { +int httplib_websocket_write( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ) { - return XX_httplib_websocket_write_exec( conn, opcode, data, dataLen, 0 ); + return XX_httplib_websocket_write_exec( ctx, conn, opcode, data, dataLen, 0 ); } /* httplib_websocket_write */ diff --git a/src/httplib_websocket_write_exec.c b/src/httplib_websocket_write_exec.c index ab93b3d3..bae57a2c 100644 --- a/src/httplib_websocket_write_exec.c +++ b/src/httplib_websocket_write_exec.c @@ -28,13 +28,13 @@ #include "httplib_main.h" /* - * int XX_httplib_websocket_write_exec( struct httplib_connection *conn, int opcode, const char *data, size_t data_len, uint32_t masking_key ); + * int XX_httplib_websocket_write_exec( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t data_len, uint32_t masking_key ); * * The function XX_httplib_websocket_write_exec() does the heavy lifting in * writing data over a websocket connectin to a remote peer. */ -int XX_httplib_websocket_write_exec( struct httplib_connection *conn, int opcode, const char *data, size_t data_len, uint32_t masking_key ) { +int XX_httplib_websocket_write_exec( const struct httplib_context *ctx, struct httplib_connection *conn, int opcode, const char *data, size_t data_len, uint32_t masking_key ) { unsigned char header[14]; size_t header_len; @@ -43,6 +43,8 @@ int XX_httplib_websocket_write_exec( struct httplib_connection *conn, int opcode uint32_t len1; uint32_t len2; + if ( ctx == NULL ) return -1; + retval = -1; header_len = 1; header[0] = 0x80 + (opcode & 0xF); @@ -108,8 +110,8 @@ int XX_httplib_websocket_write_exec( struct httplib_connection *conn, int opcode httplib_lock_connection( conn ); - retval = httplib_write( conn, header, header_len ); - if ( data_len > 0 ) retval = httplib_write( conn, data, data_len ); + retval = httplib_write( ctx, conn, header, header_len ); + if ( data_len > 0 ) retval = httplib_write( ctx, conn, data, data_len ); httplib_unlock_connection( conn ); diff --git a/src/httplib_worker_thread.c b/src/httplib_worker_thread.c index f3ac0350..a70e48fc 100644 --- a/src/httplib_worker_thread.c +++ b/src/httplib_worker_thread.c @@ -67,7 +67,7 @@ LIBHTTP_THREAD XX_httplib_worker_thread( void *thread_func_param ) { static void *worker_thread_run( struct worker_thread_args *thread_args ) { - struct httplib_context *ctx = thread_args->ctx; + struct httplib_context *ctx; struct httplib_connection *conn; struct httplib_workerTLS tls; union { @@ -79,7 +79,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { ctx = thread_args->ctx; - XX_httplib_set_thread_name( "worker" ); + XX_httplib_set_thread_name( ctx, "worker" ); tls.thread_idx = (unsigned)httplib_atomic_inc( & XX_httplib_thread_idx_max ); #if defined(_WIN32) @@ -96,7 +96,6 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { conn->buf_size = MAX_REQUEST_SIZE; conn->buf = (char *)(conn+1); - conn->ctx = ctx; conn->thread_index = thread_args->index; conn->request_info.user_data = ctx->user_data; @@ -137,7 +136,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { * HTTPS connection */ - if ( XX_httplib_sslize( conn, conn->ctx->ssl_ctx, SSL_accept ) ) { + if ( XX_httplib_sslize( ctx, conn, ctx->ssl_ctx, SSL_accept ) ) { /* * Get SSL client certificate information (if set) @@ -149,7 +148,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { * process HTTPS connection */ - XX_httplib_process_new_connection( conn ); + XX_httplib_process_new_connection( ctx, conn ); /* * Free client certificate info @@ -167,9 +166,9 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { #endif } - else XX_httplib_process_new_connection( conn ); + else XX_httplib_process_new_connection( ctx, conn ); - XX_httplib_close_connection( conn ); + XX_httplib_close_connection( ctx, conn ); } } diff --git a/src/httplib_write.c b/src/httplib_write.c index 2a2c64a5..dc366c94 100644 --- a/src/httplib_write.c +++ b/src/httplib_write.c @@ -25,6 +25,8 @@ #include "httplib_main.h" /* + * int httplib_write( const struct httplib_context *ctx, struct httplib_connection *conn, const void *buffie, size_t lennie ); + * * The function httplib_write() writes a number of bytes over a connection. * The amount of characters written is returned. If an error occurs * the value 0 is returned. @@ -37,7 +39,7 @@ * case a monotonic clock with guaranteed increase would be a better choice. */ -int httplib_write( struct httplib_connection *conn, const void *buffie, size_t lennie ) { +int httplib_write( const struct httplib_context *ctx, struct httplib_connection *conn, const void *buffie, size_t lennie ) { time_t now; int64_t n; @@ -46,7 +48,7 @@ int httplib_write( struct httplib_connection *conn, const void *buffie, size_t l int64_t allowed; const char *buf; - if ( conn == NULL || buffie == NULL || lennie == 0 ) return 0; + if ( ctx == NULL || conn == NULL || buffie == NULL || lennie == 0 ) return 0; buf = buffie; len = lennie; @@ -64,19 +66,19 @@ int httplib_write( struct httplib_connection *conn, const void *buffie, size_t l allowed = conn->throttle - conn->last_throttle_bytes; if ( allowed > len ) allowed = len; - total = XX_httplib_push_all( conn->ctx, NULL, conn->client.sock, conn->ssl, buf, allowed ); + total = XX_httplib_push_all( ctx, NULL, conn->client.sock, conn->ssl, buf, allowed ); if ( total == allowed ) { buf = buf + total; conn->last_throttle_bytes += total; - while ( total < len && conn->ctx->status == CTX_STATUS_RUNNING ) { + while ( total < len && ctx->status == CTX_STATUS_RUNNING ) { if ( conn->throttle > len-total ) allowed = len-total; else allowed = conn->throttle; - n = XX_httplib_push_all( conn->ctx, NULL, conn->client.sock, conn->ssl, buf, allowed ); + n = XX_httplib_push_all( ctx, NULL, conn->client.sock, conn->ssl, buf, allowed ); if ( n != allowed ) { if ( n > 0 ) total += n; @@ -93,7 +95,7 @@ int httplib_write( struct httplib_connection *conn, const void *buffie, size_t l } } - else total = XX_httplib_push_all( conn->ctx, NULL, conn->client.sock, conn->ssl, buf, len ); + else total = XX_httplib_push_all( ctx, NULL, conn->client.sock, conn->ssl, buf, len ); return (int)total; diff --git a/test/testmime.c b/test/testmime.c index 9038560d..28487998 100644 --- a/test/testmime.c +++ b/test/testmime.c @@ -72,7 +72,7 @@ int main( void ) { for (a=0; a