1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-06 05:02:40 +03:00

Removed context field from connection

This commit is contained in:
Lammert Bies
2017-01-01 21:14:31 +01:00
parent 7c57adf9a1
commit 4678bea572
97 changed files with 865 additions and 935 deletions

View File

@@ -228,7 +228,6 @@ OBJLIST = \
${OBJDIR}httplib_free_config_options${OBJEXT} \ ${OBJDIR}httplib_free_config_options${OBJEXT} \
${OBJDIR}httplib_free_context${OBJEXT} \ ${OBJDIR}httplib_free_context${OBJEXT} \
${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} \ ${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} \
${OBJDIR}httplib_get_context${OBJEXT} \
${OBJDIR}httplib_get_cookie${OBJEXT} \ ${OBJDIR}httplib_get_cookie${OBJEXT} \
${OBJDIR}httplib_get_debug_level${OBJEXT} \ ${OBJDIR}httplib_get_debug_level${OBJEXT} \
${OBJDIR}httplib_get_first_ssl_listener_index${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 \ ${SRCDIR}httplib_main.h \
${INCDIR}libhttp.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 \ ${OBJDIR}httplib_get_cookie${OBJEXT} : ${SRCDIR}httplib_get_cookie.c \
${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_string.h \
${SRCDIR}httplib_main.h \ ${SRCDIR}httplib_main.h \

View File

@@ -431,10 +431,6 @@ LIBHTTP_API void httplib_set_auth_handler(struct httplib_context *ctx, const cha
set, zero-length string is returned. */ 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. */ /* Get user data passed to httplib_start from context. */
LIBHTTP_API void *httplib_get_user_data(const struct httplib_context *ctx); 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 0 when the connection has been closed
-1 on error -1 on error
>0 number of bytes written on success */ >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 /* 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 0 when the connection has been closed
-1 on error -1 on error
>0 number of bytes written on success */ >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 /* 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 0 when the connection has been closed
-1 on error -1 on error
>0 number of bytes written on success */ >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 /* 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. /* Send data to the client using printf() semantics.
Works exactly like httplib_write(), but allows to do message formatting. */ 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. */ /* 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". /* Read entire request body and store it in a file "path".
Return: Return:
< 0 Error < 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 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 read error. No more data could be read from the connection.
> 0 number of bytes read into the buffer. */ > 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. /* 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(). */ /* 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. /* 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. * 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 * In any case, it is the duty of the caller to remove files once they are
* no longer required. */ * no longer required. */
LIBHTTP_API int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_form_data_handler *fdh);
#ifndef LIBHTTP_THREAD #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. */ /* 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 success, >= 0
On error/timeout, < 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_atomic_inc( volatile int *addr );
LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, char *dst, int dst_len ); LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, char *dst, int dst_len );
LIBHTTP_API unsigned httplib_check_feature( unsigned feature ); LIBHTTP_API unsigned httplib_check_feature( unsigned feature );
LIBHTTP_API void httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn );
LIBHTTP_API int httplib_closedir( DIR *dir ); LIBHTTP_API int httplib_closedir( DIR *dir );
LIBHTTP_API struct httplib_connection * httplib_connect_client( struct httplib_context *ctx, const char *host, int port, int use_ssl ); 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 ); 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 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 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 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 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 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 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 struct tm * httplib_localtime_r( const time_t *clock, struct tm *result );
LIBHTTP_API int httplib_mkdir( const char *path, int mode ); LIBHTTP_API int httplib_mkdir( const char *path, int mode );
LIBHTTP_API DIR * httplib_opendir( const char *name ); 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_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_broadcast( pthread_cond_t *cv );
LIBHTTP_API int httplib_pthread_cond_destroy( 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 ); 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 int httplib_pthread_mutex_unlock( pthread_mutex_t *mutex );
LIBHTTP_API pthread_t httplib_pthread_self( void ); LIBHTTP_API pthread_t httplib_pthread_self( void );
LIBHTTP_API int httplib_pthread_setspecific( pthread_key_t key, void *value ); 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 struct dirent * httplib_readdir( DIR *dir );
LIBHTTP_API int httplib_remove( const char *path ); 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 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 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 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 struct httplib_context * httplib_start(const struct httplib_callbacks *callbacks, void *user_data, const struct httplib_option_t *options );
LIBHTTP_API void httplib_stop( struct httplib_context *ctx ); LIBHTTP_API void httplib_stop( struct httplib_context *ctx );
LIBHTTP_API 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 int httplib_strcasecmp( const char *s1, const char *s2 );
LIBHTTP_API const char * httplib_strcasestr( const char *big_str, const char *small_str ); LIBHTTP_API const char * httplib_strcasestr( const char *big_str, const char *small_str );
LIBHTTP_API char * httplib_strdup( const char *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_exit( void );
LIBHTTP_API int httplib_system_init( void ); LIBHTTP_API int httplib_system_init( void );
LIBHTTP_API const char * httplib_version( 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 #ifdef __cplusplus
} }

View File

@@ -30,7 +30,7 @@
#include "httplib_utils.h" #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 * The function XX_httplib_addenv() adds one item to the environment before
* a CGI script is called. The environment variable has the form * a CGI script is called. The environment variable has the form
@@ -44,7 +44,7 @@
#if !defined(NO_CGI) #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 n;
size_t space; size_t space;
@@ -52,7 +52,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) {
char *added; char *added;
va_list ap; 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 * 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 * 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; return;
} }
@@ -99,7 +99,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) {
*/ */
va_start( ap, 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 ); va_end( ap );
/* /*
@@ -133,7 +133,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) {
if ( space < 2 ) { 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; return;
} }

View File

@@ -28,25 +28,25 @@
#include "httplib_main.h" #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 * The function XX_httplib_authorize() authorizes agains the open passwords
* file. It returns 1 if authorized. * 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; struct read_auth_file_struct workdata;
char buf[MG_BUF_LEN]; 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) ); memset( & workdata, 0, sizeof(workdata) );
workdata.conn = conn; workdata.conn = conn;
if ( ! XX_httplib_parse_auth_header( conn, buf, sizeof(buf), &workdata.ah ) ) return false; if ( ! XX_httplib_parse_auth_header( ctx, conn, buf, sizeof(buf), &workdata.ah ) ) return false;
workdata.domain = conn->ctx->authentication_domain; 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 */ } /* XX_httplib_authorize */

View File

@@ -29,7 +29,7 @@
#include "httplib_string.h" #include "httplib_string.h"
/* Return 1 if request is authorised, 0 otherwise. */ /* 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 fname[PATH_MAX];
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
@@ -40,31 +40,31 @@ bool XX_httplib_check_authorization( struct httplib_connection *conn, const char
bool authorized; bool authorized;
bool truncated; bool truncated;
if ( conn == NULL || conn->ctx == NULL ) return false; if ( ctx == NULL || conn == NULL ) return false;
authorized = true; authorized = true;
list = conn->ctx->protect_uri; list = ctx->protect_uri;
while ( (list = XX_httplib_next_option( list, &uri_vec, &filename_vec )) != NULL ) { 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 ) ) { 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; 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 ) ) { if ( XX_httplib_is_file_opened( & file ) ) {
authorized = XX_httplib_authorize( conn, & file ); authorized = XX_httplib_authorize( ctx, conn, & file );
XX_httplib_fclose( & file ); XX_httplib_fclose( & file );
} }

View File

@@ -30,21 +30,21 @@
#include "httplib_ssl.h" #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 * The function XX_httplib_close_connection() is the internal function which
* does the heavy lifting to close a connection. * 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 * 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 ); httplib_lock_connection( conn );
@@ -71,7 +71,7 @@ void XX_httplib_close_connection( struct httplib_connection *conn ) {
#endif #endif
if ( conn->client.sock != INVALID_SOCKET ) { if ( conn->client.sock != INVALID_SOCKET ) {
XX_httplib_close_socket_gracefully( conn ); XX_httplib_close_socket_gracefully( ctx, conn );
conn->client.sock = INVALID_SOCKET; 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 * The function httplib_close_connection() closes the connection passed as a
* parameter to this function. The function does not return a success or * parameter to this function. The function does not return a success or
* failure value. * 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; struct httplib_context *client_ctx;
int i; 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; client_ctx = ctx;
conn->ctx->status = CTX_STATUS_STOPPING; ctx->status = CTX_STATUS_STOPPING;
} }
else client_ctx = NULL; else client_ctx = NULL;
@@ -111,7 +111,7 @@ void httplib_close_connection( struct httplib_connection *conn ) {
conn->client_ssl_ctx = NULL; conn->client_ssl_ctx = NULL;
} }
#endif #endif
XX_httplib_close_connection( conn ); XX_httplib_close_connection( ctx, conn );
if ( client_ctx != NULL ) { if ( client_ctx != NULL ) {

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #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 * The function XX_httplib_close_socket_gracefully() closes a socket in a
* graceful way. * 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) #if defined(_WIN32)
char buf[MG_BUF_LEN]; char buf[MG_BUF_LEN];
@@ -45,7 +45,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) {
int error_code; int error_code;
socklen_t opt_len; socklen_t opt_len;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
error_code = 0; error_code = 0;
opt_len = sizeof(error_code); opt_len = sizeof(error_code);
@@ -67,7 +67,7 @@ void XX_httplib_close_socket_gracefully( struct httplib_connection *conn ) {
else { else {
if ( setsockopt( conn->client.sock, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) ) != 0 ) { 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 ) );
} }
} }

View File

@@ -109,7 +109,6 @@ static struct httplib_connection *httplib_connect_client_impl( struct httplib_co
conn->buf_size = MAX_REQUEST_SIZE; conn->buf_size = MAX_REQUEST_SIZE;
conn->buf = (char *)(conn + 1); conn->buf = (char *)(conn + 1);
conn->ctx = ctx;
conn->client.sock = sock; conn->client.sock = sock;
conn->client.lsa = sa; 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 ); 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__ ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: SSL connection error", __func__ );
SSL_CTX_free( conn->client_ssl_ctx ); SSL_CTX_free( conn->client_ssl_ctx );

View File

@@ -117,6 +117,7 @@ struct httplib_connection *httplib_connect_websocket_client( struct httplib_cont
return NULL; return NULL;
} }
thread_data->ctx = ctx;
thread_data->conn = conn; thread_data->conn = conn;
thread_data->data_handler = data_func; thread_data->data_handler = data_func;
thread_data->close_handler = close_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__ ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: thread failed to start", __func__ );
thread_data = httplib_free( thread_data ); thread_data = httplib_free( thread_data );
ctx->workerthreadids = httplib_free( ctx->workerthreadids );
conn = httplib_free( conn ); conn = httplib_free( conn );
ctx->workerthreadids = httplib_free( ctx->workerthreadids );
ctx->num_threads = 0; ctx->num_threads = 0;
ctx->user_data = NULL; ctx->user_data = NULL;

View File

@@ -29,17 +29,17 @@
#include "httplib_string.h" #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 * The function XX_httplib_construct_etag() is used to construct an etag which
* can be used to identify a file on a specific moment. * 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 ) { 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 */ } /* XX_httplib_construct_etag */

View File

@@ -84,7 +84,7 @@ void httplib_cry( enum debug_level_t debug_level, const struct httplib_context *
*/ */
if ( ctx->error_log_file == NULL ) return; if ( ctx->error_log_file == NULL ) return;
if ( ! XX_httplib_fopen( conn, ctx->error_log_file, "a+", &fi ) ) 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 * We now have an open FILE stream pointer in fi.fp and can dump the

View File

@@ -28,33 +28,33 @@
#include "httplib_main.h" #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 * The function XX_httplib_delete_file() deletes a file after a request over a
* connection. * 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; struct de de;
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
if ( conn->ctx->document_root == NULL ) { 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; return;
} }
memset( &de.file, 0, sizeof(de.file) ); 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_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; return;
} }
@@ -64,19 +64,19 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path )
* the file is cached in memory * 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; return;
} }
if ( de.file.is_directory ) { 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. * 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 { 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). * 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; return;
} }
@@ -100,7 +100,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path )
* File is read only * 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; return;
} }
@@ -108,7 +108,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path )
* Try to delete it * Try to delete it
*/ */
if ( httplib_remove( path ) == 0 ) XX_httplib_send_http_error( conn, 204, "%s", "" ); if ( httplib_remove( path ) == 0 ) XX_httplib_send_http_error( ctx, 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 ) ); 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 */ } /* XX_httplib_delete_file */

View File

@@ -28,11 +28,13 @@
#include "httplib_main.h" #include "httplib_main.h"
#include "httplib_string.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 dir_scan_data *dsd;
struct de* old_entries; struct de* old_entries;
UNUSED_PARAMETER(ctx);
dsd = data; dsd = data;
if ( dsd->entries == NULL || dsd->num_entries >= dsd->arr_size ) { if ( dsd->entries == NULL || dsd->num_entries >= dsd->arr_size ) {

View File

@@ -28,20 +28,20 @@
#include "httplib_main.h" #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 * The function XX_httplib_discard_unread_request_data() discards any request
* data on a connection which is not further needed but has alread been * data on a connection which is not further needed but has alread been
* received. * 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]; char buf[MG_BUF_LEN];
size_t to_read; size_t to_read;
int nread; int nread;
if ( conn == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
to_read = sizeof(buf); to_read = sizeof(buf);
@@ -54,7 +54,7 @@ void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ) {
while ( conn->is_chunked == 1 ) { while ( conn->is_chunked == 1 ) {
nread = httplib_read( conn, buf, to_read ); nread = httplib_read( ctx, conn, buf, to_read );
if ( nread <= 0 ) break; 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); 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; if (nread <= 0) break;
} }
} }

View File

@@ -50,7 +50,7 @@ struct httplib_connection * httplib_download( struct httplib_context *ctx, const
if ( conn != NULL ) { 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__ ); 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 ) { if ( i <= 0 && conn != NULL ) {
httplib_close_connection( conn ); httplib_close_connection( ctx, conn );
conn = NULL; conn = NULL;
} }

View File

@@ -27,9 +27,9 @@
#include "httplib_main.h" #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 #ifdef _WIN32
UNUSED_PARAMETER(conn); 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 ( 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 #endif

View File

@@ -28,7 +28,7 @@
#include "httplib_main.h" #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 * 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 * 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). * 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; struct stat st;
if ( filep == NULL ) return false; if ( ctx == NULL || filep == NULL ) return false;
memset( filep, 0, sizeof(*filep) ); memset( filep, 0, sizeof(*filep) );
if ( stat( path, &st ) == 0 ) filep->size = (uint64_t)st.st_size; 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 #ifdef _WIN32
wchar_t wbuf[PATH_MAX]; wchar_t wbuf[PATH_MAX];
wchar_t wmode[20]; wchar_t wmode[20];

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #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 * The function XX_httplib_forward_body_data() forwards body data to the
* client. The function returns true if successful, and false otherwise. * 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 *expect;
const char *body; const char *body;
@@ -45,15 +45,15 @@ bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SO
int64_t buffered_len; int64_t buffered_len;
double timeout; double timeout;
if ( conn == NULL || conn->ctx == NULL ) return false; if ( ctx == NULL || conn == NULL ) return false;
success = false; success = false;
timeout = ((double)conn->ctx->request_timeout) / 1000.0; timeout = ((double)ctx->request_timeout) / 1000.0;
expect = httplib_get_header( conn, "Expect" ); expect = httplib_get_header( conn, "Expect" );
if ( fp == NULL ) { 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; 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. * 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. * 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 { else {
if ( expect != NULL ) { 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; 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 ) { 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; 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; if ((int64_t)buffered_len > conn->content_len) buffered_len = (int)conn->content_len;
body = conn->buf + conn->request_len + conn->consumed_content; 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; 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); to_read = sizeof(buf);
if ( (int64_t)to_read > conn->content_len - conn->consumed_content ) to_read = (int)(conn->content_len - conn->consumed_content); 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 ); nread = XX_httplib_pull( ctx, NULL, conn, buf, to_read, timeout );
if ( nread <= 0 || XX_httplib_push_all( conn->ctx, fp, sock, ssl, buf, nread ) != nread ) break; if ( nread <= 0 || XX_httplib_push_all( ctx, fp, sock, ssl, buf, nread ) != nread ) break;
conn->consumed_content += nread; 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 * 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", "" );
} }
} }

View File

@@ -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 */

View File

@@ -30,7 +30,7 @@
/* Look at the "path" extension and figure what mime type it has. /* Look at the "path" extension and figure what mime type it has.
* Store mime type in the vector. */ * 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 ext_vec;
struct vec mime_vec; struct vec mime_vec;

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #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 * The function XX_httplib_get_rel_url_at_current_server() returns the relative
* uri at the current server. * 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; const char *server_domain;
size_t server_domain_len; 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; const char *portbegin;
char *portend; char *portend;
if ( conn == NULL || conn->ctx == NULL ) return NULL; if ( ctx == NULL || conn == NULL ) return NULL;
request_domain_len = 0; request_domain_len = 0;
port = 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 * 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; if ( server_domain == NULL ) return NULL;
server_domain_len = strlen( server_domain ); server_domain_len = strlen( server_domain );

View File

@@ -35,14 +35,14 @@
* and 0 otherwise. * 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 struct httplib_request_info *request_info;
const char *uri; const char *uri;
size_t urilen; size_t urilen;
struct httplib_handler_info *tmp_rh; 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 ); request_info = httplib_get_request_info( conn );
if ( request_info == NULL ) return 0; 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; uri = request_info->local_uri;
urilen = strlen( uri ); urilen = strlen( uri );
httplib_lock_context( conn->ctx ); httplib_lock_context( ctx );
/* /*
* first try for an exact match * 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 ) { 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; else *auth_handler = tmp_rh->auth_handler;
*cbdata = tmp_rh->cbdata; *cbdata = tmp_rh->cbdata;
httplib_unlock_context( conn->ctx ); httplib_unlock_context( ctx );
return 1; 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 * 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 ) { 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; else *auth_handler = tmp_rh->auth_handler;
*cbdata = tmp_rh->cbdata; *cbdata = tmp_rh->cbdata;
httplib_unlock_context( conn->ctx ); httplib_unlock_context( ctx );
return 1; return 1;
} }
@@ -113,7 +113,7 @@ int XX_httplib_get_request_handler( struct httplib_connection *conn, int handler
* finally try for pattern match * 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 ) { 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; else *auth_handler = tmp_rh->auth_handler;
*cbdata = tmp_rh->cbdata; *cbdata = tmp_rh->cbdata;
httplib_unlock_context( conn->ctx ); httplib_unlock_context( ctx );
return 1; return 1;
} }
} }
} }
httplib_unlock_context( conn->ctx ); httplib_unlock_context( ctx );
return 0; /* none found */ return 0; /* none found */

View File

@@ -29,7 +29,7 @@
#include "httplib_string.h" #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 * The function httplib_get_response() tries to get a response from a remote
* peer. This function does some dirty action by temporarily replacing the * peer. This function does some dirty action by temporarily replacing the
@@ -40,22 +40,20 @@
* place. * 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 err;
int ret; int ret;
struct httplib_context *octx;
struct httplib_context rctx; 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 * Replace the connection context with a copy of it where the timeout
* value is changed to a parameter passed value. * value is changed to a parameter passed value.
*/ */
octx = conn->ctx; rctx = *ctx;
rctx = *(conn->ctx);
if ( timeout >= 0 ) { if ( timeout >= 0 ) {
@@ -65,9 +63,7 @@ int httplib_get_response( struct httplib_connection *conn, int timeout ) {
else rctx.request_timeout = 0; else rctx.request_timeout = 0;
conn->ctx = &rctx; ret = XX_httplib_getreq( &rctx, conn, &err );
ret = XX_httplib_getreq( conn->ctx, conn, &err );
conn->ctx = octx;
/* /*
* End of dirty context swap code. * End of dirty context swap code.

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #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 * The function httplib_get_response_code_text() returns a text associated with an
* HTTP response code. * 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: * 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. * 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. * Return at least a category according to RFC 2616 Section 10.

View File

@@ -29,12 +29,12 @@
#include "httplib_string.h" #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. * 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; 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 ); 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); * assert(conn->request_len < 0 || conn->data_len >= conn->request_len);

View File

@@ -29,7 +29,7 @@
#include "httplib_string.h" #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 * The function XX_httplib_handle_cgi_request() handles a request for a CGI
* resource. * resource.
@@ -37,7 +37,7 @@
#if !defined(NO_CGI) #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; char *buf;
size_t buflen; 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; struct file fout = STRUCT_FILE_INITIALIZER;
pid_t pid = (pid_t)-1; pid_t pid = (pid_t)-1;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
in = NULL; in = NULL;
out = NULL; out = NULL;
@@ -73,7 +73,7 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char
buf = NULL; buf = NULL;
buflen = 16384; 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 * 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'. * 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 ) { if ( truncated ) {
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\": Path too long", __func__, prog ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: CGI program \"%s\": Path too long", __func__, prog );
XX_httplib_send_http_error( conn, 500, "Error: %s", "CGI path too long" ); XX_httplib_send_http_error( ctx, conn, 500, "Error: %s", "CGI path too long" );
goto done; 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 ) { if ( pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0 ) {
status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); 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 ); 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( conn, 500, "Error: Cannot create CGI pipe: %s", status ); XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot create CGI pipe: %s", status );
goto done; 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 ) { if ( pid == (pid_t)-1 ) {
status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); 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 ); 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( conn, 500, "Error: Cannot spawn CGI process [%s]: %s", prog, status ); XX_httplib_send_http_error( ctx, conn, 500, "Error: Cannot spawn CGI process [%s]: %s", prog, status );
goto done; 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 ) { if ( (in = fdopen( fdin[1], "wb" )) == NULL ) {
status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); 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 ); httplib_cry( DEBUG_LEVEL_ERROR, 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 ); XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdin\nfopen: %s", status );
goto done; 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 ) { if ( (out = fdopen( fdout[0], "rb" )) == NULL ) {
status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); 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 ); httplib_cry( DEBUG_LEVEL_ERROR, 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 ); XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdout\nfopen: %s", status );
goto done; 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 ) { if ( (err = fdopen( fderr[0], "rb" )) == NULL ) {
status = httplib_error_string( ERRNO, error_string, ERROR_STRING_LEN ); 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 ); httplib_cry( DEBUG_LEVEL_ERROR, 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 ); XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI can not open fdout\nfopen: %s", status );
goto done; 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. * 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 * 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; goto done;
} }
@@ -221,13 +221,13 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char
if ( buf == NULL ) { if ( buf == NULL ) {
XX_httplib_send_http_error( conn, 500, "Error: Not enough memory for CGI buffer (%u bytes)", (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, conn->ctx, conn, "%s: CGI program \"%s\": Not enough memory for buffer (%u " "bytes)", __func__, prog, (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; 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 ) { if ( headers_len <= 0 ) {
/* /*
@@ -235,18 +235,18 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char
* stderr. * 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 ) { if ( i > 0 ) {
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: CGI program \"%s\" sent error " "message: [%.*s]", __func__, 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( conn, 500, "Error: CGI program \"%s\" sent error " "message: [%.*s]", prog, i, buf ); XX_httplib_send_http_error( ctx, conn, 500, "Error: CGI program \"%s\" sent error " "message: [%.*s]", prog, i, buf );
} }
else { 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, 500,
"Error: CGI program sent malformed or too big " "Error: CGI program sent malformed or too big "
"(>%u bytes) HTTP headers: [%.*s]", "(>%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" ); connection_state = XX_httplib_get_header( &ri, "Connection" );
if ( ! XX_httplib_header_has_option( connection_state, "keep-alive" ) ) conn->must_close = true; 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 * Send headers
*/ */
for (i=0; i<ri.num_headers; i++) httplib_printf( conn, "%s: %s\r\n", ri.http_headers[i].name, ri.http_headers[i].value ); for (i=0; i<ri.num_headers; i++) httplib_printf( ctx, conn, "%s: %s\r\n", ri.http_headers[i].name, ri.http_headers[i].value );
httplib_write( conn, "\r\n", 2 ); httplib_write( ctx, conn, "\r\n", 2 );
/* /*
* Send chunk of data that may have been read after the headers * Send chunk of data that may have been read after the headers
*/ */
conn->num_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 * 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: done:
blk.var = httplib_free( blk.var ); blk.var = httplib_free( blk.var );

View File

@@ -28,7 +28,7 @@
#include "httplib_main.h" #include "httplib_main.h"
#include "httplib_utils.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; unsigned int i;
int sort_direction; int sort_direction;
@@ -37,12 +37,12 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
time_t curtime; time_t curtime;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
if ( dir == NULL ) { XX_httplib_send_http_error( conn, 500, "Internal server error\nOpening NULL directory" ); 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; return;
} }
@@ -53,11 +53,11 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
conn->must_close = true; conn->must_close = true;
httplib_printf( conn, "HTTP/1.1 200 OK\r\n" ); httplib_printf( ctx, conn, "HTTP/1.1 200 OK\r\n" );
XX_httplib_send_static_cache_header( conn ); XX_httplib_send_static_cache_header( ctx, 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, "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,
"<html><head><title>Index of %s</title>" "<html><head><title>Index of %s</title>"
"<style>th {text-align: left;}</style></head>" "<style>th {text-align: left;}</style></head>"
"<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">" "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
@@ -75,7 +75,7 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
* Print first entry - link to a parent directory * Print first entry - link to a parent directory
*/ */
conn->num_bytes_sent += httplib_printf(conn, conn->num_bytes_sent += httplib_printf( ctx, conn,
"<tr><td><a href=\"%s%s\">%s</a></td>" "<tr><td><a href=\"%s%s\">%s</a></td>"
"<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n", "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
conn->request_info.local_uri, conn->request_info.local_uri,
@@ -94,14 +94,14 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
for (i=0; i<data.num_entries; i++) { for (i=0; i<data.num_entries; i++) {
XX_httplib_print_dir_entry( & data.entries[i] ); XX_httplib_print_dir_entry( ctx, & data.entries[i] );
data.entries[i].file_name = httplib_free( data.entries[i].file_name ); data.entries[i].file_name = httplib_free( data.entries[i].file_name );
} }
data.entries = httplib_free( data.entries ); data.entries = httplib_free( data.entries );
} }
conn->num_bytes_sent += httplib_printf( conn, "%s", "</table></body></html>" ); conn->num_bytes_sent += httplib_printf( ctx, conn, "%s", "</table></body></html>" );
conn->status_code = 200; conn->status_code = 200;
} /* XX_httplib_handle_directory_request */ } /* XX_httplib_handle_directory_request */

View File

@@ -28,26 +28,26 @@
#include "httplib_main.h" #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 * 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 * involves a file. This can either be a CGI request, an SSI request of a
* request for a static file. * 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) #if !defined(NO_CGI)
const char *cgi_ext; const char *cgi_ext;
#endif /* ! NO_CGI */ #endif /* ! NO_CGI */
const char *ssi_ext; const char *ssi_ext;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
#if !defined(NO_CGI) #if !defined(NO_CGI)
cgi_ext = conn->ctx->cgi_pattern; cgi_ext = ctx->cgi_pattern;
#endif /* ! NO_CGI */ #endif /* ! NO_CGI */
ssi_ext = conn->ctx->ssi_pattern; ssi_ext = ctx->ssi_pattern;
if (0) { if (0) {
#if !defined(NO_CGI) #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 * 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 */ #endif /* !NO_CGI */
} }
else if ( ssi_ext != NULL && XX_httplib_match_prefix( ssi_ext, strlen( ssi_ext ), path ) > 0 ) { 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 */ } /* XX_httplib_handle_file_based_request */

View File

@@ -26,14 +26,7 @@
#include "httplib_main.h" #include "httplib_main.h"
static int url_encoded_field_found(const struct httplib_connection *conn, 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 ) {
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 key_dec[1024];
char filename_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. * 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; 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 ) { 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; 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 ) { 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; 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, 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 ) {
const char *key,
size_t key_len,
const char *value,
size_t value_len,
struct httplib_form_data_handler *fdh) {
char key_dec[1024]; 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. * 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; 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; const char *content_type;
char path[512]; char path[512];
@@ -245,7 +233,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
memset( path, 0, sizeof(path) ); memset( path, 0, sizeof(path) );
field_count++; 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++; val++;
next = strchr( val, '&' ); next = strchr( val, '&' );
@@ -266,7 +254,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
* Call callback * 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 ) { 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 * 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; file_size = 0;
if ( fstore.fp != NULL ) { if ( fstore.fp != NULL ) {
size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp); size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
if ((n != (size_t)vallen) || (ferror(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 ); fclose( fstore.fp );
fstore.fp = NULL; fstore.fp = NULL;
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
file_size += (int64_t)n; file_size += (int64_t)n;
@@ -302,14 +290,14 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
} }
else { else {
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path );
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
fstore.fp = NULL; 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)) { if ((size_t)buf_fill < (sizeof(buf) - 1)) {
size_t to_read = sizeof(buf) - 1 - (size_t)buf_fill; 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 < 0 ) return -1; /* read error */
if ( r != (int)to_read ) { 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) ); memset( path, 0, sizeof(path) );
field_count++; 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_ABORT) == FORM_FIELD_STORAGE_ABORT ) break; /* Stop parsing the request */
if ( field_storage == FORM_FIELD_STORAGE_STORE ) { 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; 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; get_block = 0;
@@ -444,7 +432,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
#endif #endif
/* Call callback */ /* Call callback */
url_encoded_field_get(conn, url_encoded_field_get( ctx, conn,
((get_block > 0) ? NULL : buf), ((get_block > 0) ? NULL : buf),
((get_block > 0) ? 0 : (size_t)keylen), ((get_block > 0) ? 0 : (size_t)keylen),
val, val,
@@ -455,10 +443,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
if ( fstore.fp ) { if ( fstore.fp ) {
size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp); size_t n = (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
if ((n != (size_t)vallen) || (ferror(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); fclose(fstore.fp);
fstore.fp = NULL; fstore.fp = NULL;
XX_httplib_remove_bad_file(conn, path); XX_httplib_remove_bad_file( ctx, conn, path );
} }
file_size += (int64_t)n; 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)) { if ((size_t)buf_fill < (sizeof(buf) - 1)) {
size_t to_read = sizeof(buf) - 1 - (size_t)buf_fill; 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 < 0 ) return -1; /* read error */
if (r != (int)to_read) { if (r != (int)to_read) {
@@ -506,8 +494,8 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
} }
else { else {
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path );
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
fstore.fp = NULL; fstore.fp = NULL;
@@ -593,7 +581,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
size_t n; size_t n;
int get_block; 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 */ if ( r < 0 ) return -1; /* read error */
buf_fill += r; buf_fill += r;
@@ -690,7 +678,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
memset( path, 0, sizeof(path) ); memset( path, 0, sizeof(path) );
field_count++; 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, * 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 * 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; 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; get_block = 0;
@@ -752,10 +740,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
if ( n != towrite || ferror( fstore.fp ) ) { 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 ); fclose( fstore.fp );
fstore.fp = NULL; fstore.fp = NULL;
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
file_size += (int64_t)n; file_size += (int64_t)n;
@@ -770,7 +758,7 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
* Read new data * 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 */ if ( r < 0 ) return -1; /* read error */
buf_fill += r; buf_fill += r;
@@ -808,10 +796,10 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
if ( n != towrite || ferror( fstore.fp ) ) { 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 ); fclose( fstore.fp );
fstore.fp = NULL; fstore.fp = NULL;
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
file_size += (int64_t)n; file_size += (int64_t)n;
} }
@@ -832,8 +820,8 @@ int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_
} }
else { else {
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: Error saving file %s", __func__, path ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: Error saving file %s", __func__, path );
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
} }
fstore.fp = NULL; fstore.fp = NULL;
} }

View File

@@ -29,31 +29,31 @@
#include "httplib_utils.h" #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 * 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 * send a 304 response to a client to indicate that the requested resource has
* not been changed. * 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 date[64];
char lm[64]; char lm[64];
char etag[64]; char etag[64];
time_t curtime; time_t curtime;
if ( conn == NULL || filep == NULL ) return; if ( ctx == NULL || conn == NULL || filep == NULL ) return;
curtime = time( NULL ); curtime = time( NULL );
conn->status_code = 304; conn->status_code = 304;
XX_httplib_gmt_time_string( date, sizeof(date), & curtime ); XX_httplib_gmt_time_string( date, sizeof(date), & curtime );
XX_httplib_gmt_time_string( lm, sizeof(lm), & filep->last_modified ); 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 ); 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( conn ); XX_httplib_send_static_cache_header( ctx, 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, "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 */ } /* XX_httplib_handle_not_modified_static_file_request */

View File

@@ -30,20 +30,20 @@
#include "httplib_utils.h" #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 * The function print_props() writes the PROPFIND properties for a collection
* event. * 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]; char mtime[64];
if ( conn == NULL || uri == NULL || filep == NULL ) return; if ( conn == NULL || uri == NULL || filep == NULL ) return;
XX_httplib_gmt_time_string( mtime, sizeof(mtime), &filep->last_modified ); 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,
"<d:response>" "<d:response>"
"<d:href>%s</d:href>" "<d:href>%s</d:href>"
"<d:propstat>" "<d:propstat>"
@@ -63,13 +63,13 @@ static void print_props( struct httplib_connection *conn, const char *uri, struc
} /* print_props */ } /* 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 * The function print_dav_dir_entry() is used to send the properties of a
* webdav directory to the remote client. * 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[PATH_MAX];
char href_encoded[PATH_MAX * 3 /* worst case */]; 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; 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 ) { if ( ! truncated ) {
httplib_url_encode( href, href_encoded, PATH_MAX * 3 ); 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 */ } /* 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. * 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; const char *depth;
char date[64]; char date[64];
time_t curtime; time_t curtime;
if ( conn == NULL || conn->ctx == NULL || path == NULL || filep == NULL ) return; if ( ctx == NULL || conn == NULL || path == NULL || filep == NULL ) return;
if ( conn->ctx->document_root == NULL ) return; if ( ctx->document_root == NULL ) return;
depth = httplib_get_header( conn, "Depth" ); depth = httplib_get_header( conn, "Depth" );
curtime = time( NULL ); curtime = time( NULL );
@@ -112,27 +112,27 @@ void XX_httplib_handle_propfind( struct httplib_connection *conn, const char *pa
conn->must_close = true; conn->must_close = true;
conn->status_code = 207; conn->status_code = 207;
httplib_printf( conn, "HTTP/1.1 207 Multi-Status\r\n" "Date: %s\r\n", date ); httplib_printf( ctx, conn, "HTTP/1.1 207 Multi-Status\r\n" "Date: %s\r\n", date );
XX_httplib_send_static_cache_header( conn ); XX_httplib_send_static_cache_header( ctx, 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, "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, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<d:multistatus xmlns:d='DAV:'>\n" ); conn->num_bytes_sent += httplib_printf( ctx, conn, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<d:multistatus xmlns:d='DAV:'>\n" );
/* /*
* Print properties for the requested resource itself * 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 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", "</d:multistatus>" ); conn->num_bytes_sent += httplib_printf( ctx, conn, "%s\n", "</d:multistatus>" );
} /* XX_httplib_handle_propfind */ } /* XX_httplib_handle_propfind */

View File

@@ -30,7 +30,7 @@
#include "httplib_utils.h" #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 * 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 * 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. * 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; struct httplib_request_info *ri;
char path[PATH_MAX]; char path[PATH_MAX];
@@ -66,7 +66,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) {
char * var; char * var;
} ptr; } ptr;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
ri = & conn->request_info; ri = & conn->request_info;
is_found = false; 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 ) { 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 { else {
/* /*
@@ -115,8 +115,8 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) {
* but no https port to forward to. * but no https port to forward to.
*/ */
XX_httplib_send_http_error( conn, 503, "%s", "Error: SSL forward not configured properly" ); XX_httplib_send_http_error( ctx, 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__ ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: can not redirect to SSL, no SSL port available", __func__ );
} }
return; return;
@@ -129,7 +129,7 @@ void XX_httplib_handle_request( struct httplib_connection *conn ) {
*/ */
ptr.con = ri->local_uri; 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 * 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 * 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 * 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 * 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. * required, use a request_handler instead.
*/ */
i = conn->ctx->callbacks.begin_request( conn ); i = ctx->callbacks.begin_request( conn );
if ( i > 0 ) { 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 * 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, is_websocket_request ? WEBSOCKET_HANDLER : REQUEST_HANDLER,
&callback_handler, &callback_handler,
&ws_connect_handler, &ws_connect_handler,
@@ -242,14 +242,7 @@ no_callback_resource:
*/ */
is_callback_resource = false; is_callback_resource = false;
XX_httplib_interpret_uri( conn, XX_httplib_interpret_uri( ctx, conn, path, sizeof(path), &file, &is_found, &is_script_resource, &is_websocket_request, &is_put_or_delete_request );
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 * 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; 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 * 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 * This server does not have any real files, thus the
* PUT/DELETE methods are not valid. * 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; return;
} }
@@ -285,9 +278,9 @@ no_callback_resource:
* 6.2.2. Check if put authorization for static files is * 6.2.2. Check if put authorization for static files is
* available. * 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; return;
} }
} }
@@ -299,9 +292,9 @@ no_callback_resource:
* correspond to a file. Check authorization. * 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; return;
} }
} }
@@ -328,7 +321,7 @@ no_callback_resource:
*/ */
conn->status_code = i; conn->status_code = i;
XX_httplib_discard_unread_request_data( conn ); XX_httplib_discard_unread_request_data( ctx, conn );
} }
else { else {
@@ -338,14 +331,7 @@ no_callback_resource:
* the authorization check might be different * the authorization check might be different
*/ */
XX_httplib_interpret_uri( conn, XX_httplib_interpret_uri( ctx, conn, path, sizeof(path), &file, &is_found, &is_script_resource, &is_websocket_request, &is_put_or_delete_request );
path,
sizeof(path),
&file,
&is_found,
&is_script_resource,
&is_websocket_request,
&is_put_or_delete_request );
callback_handler = NULL; callback_handler = NULL;
goto no_callback_resource; goto no_callback_resource;
@@ -353,14 +339,7 @@ no_callback_resource:
} }
else { else {
XX_httplib_handle_websocket_request( conn, 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 );
path,
is_callback_resource,
ws_connect_handler,
ws_ready_handler,
ws_data_handler,
ws_close_handler,
callback_data );
} }
return; return;
@@ -378,10 +357,10 @@ no_callback_resource:
* Websocket Lua script, the 0 in the third parameter indicates Lua * 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; return;
} }
@@ -391,9 +370,9 @@ no_callback_resource:
* by a script file. Thus, a DOCUMENT_ROOT must exist. * 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; return;
} }
@@ -403,7 +382,7 @@ no_callback_resource:
if ( is_script_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; return;
} }
@@ -413,9 +392,9 @@ no_callback_resource:
if ( is_put_or_delete_request ) { if ( is_put_or_delete_request ) {
if ( ! strcmp( ri->request_method, "PUT" ) ) { XX_httplib_put_file( 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( 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( conn, path ); return; } if ( ! strcmp( ri->request_method, "MKCOL" ) ) { XX_httplib_mkcol( ctx, conn, path ); return; }
/* /*
* 11.4. PATCH method * 11.4. PATCH method
@@ -423,7 +402,7 @@ no_callback_resource:
* only for scripts (Lua, CGI) and callbacks. * 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; return;
} }
@@ -432,9 +411,9 @@ no_callback_resource:
* hidden * 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; return;
} }
@@ -445,7 +424,7 @@ no_callback_resource:
if ( file.is_directory && uri_len > 0 && ri->local_uri[uri_len - 1] != '/' ) { if ( file.is_directory && uri_len > 0 && ri->local_uri[uri_len - 1] != '/' ) {
XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); XX_httplib_gmt_time_string( date, sizeof(date), &curtime );
httplib_printf( conn, httplib_printf( ctx, conn,
"HTTP/1.1 301 Moved Permanently\r\n" "HTTP/1.1 301 Moved Permanently\r\n"
"Location: %s/\r\n" "Location: %s/\r\n"
"Date: %s\r\n" "Date: %s\r\n"
@@ -454,7 +433,7 @@ no_callback_resource:
"Connection: %s\r\n\r\n", "Connection: %s\r\n\r\n",
ri->request_uri, ri->request_uri,
date, date,
XX_httplib_suggest_connection_header( conn ) ); XX_httplib_suggest_connection_header( ctx, conn ) );
return; return;
} }
@@ -465,7 +444,7 @@ no_callback_resource:
if ( ! strcmp( ri->request_method, "PROPFIND" ) ) { if ( ! strcmp( ri->request_method, "PROPFIND" ) ) {
XX_httplib_handle_propfind( conn, path, & file ); XX_httplib_handle_propfind( ctx, conn, path, & file );
return; return;
} }
@@ -483,7 +462,7 @@ no_callback_resource:
* preflights). * preflights).
*/ */
XX_httplib_send_options( conn ); XX_httplib_send_options( ctx, conn );
return; return;
} }
@@ -493,7 +472,7 @@ no_callback_resource:
if ( strcmp( ri->request_method, "GET" ) && strcmp( ri->request_method, "HEAD" ) ) { 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; return;
} }
@@ -503,7 +482,7 @@ no_callback_resource:
if ( file.is_directory ) { 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 * 14.1. use a substitute file
@@ -517,14 +496,14 @@ no_callback_resource:
* 14.2. no substitute file * 14.2. no substitute file
*/ */
if ( conn->ctx->enable_directory_listing ) XX_httplib_handle_directory_request( conn, path ); if ( ctx->enable_directory_listing ) XX_httplib_handle_directory_request( ctx, conn, path );
else XX_httplib_send_http_error( conn, 403, "%s", "Error: Directory listing denied" ); else XX_httplib_send_http_error( ctx, conn, 403, "%s", "Error: Directory listing denied" );
return; return;
} }
} }
XX_httplib_handle_file_based_request( conn, path, &file ); XX_httplib_handle_file_based_request( ctx, conn, path, &file );
#if 0 #if 0
/* /*

View File

@@ -36,7 +36,7 @@
* request for a static file. * 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 date[64];
char lm[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 *cors2;
const char *cors3; const char *cors3;
if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return; if ( ctx == NULL || conn == NULL || filep == NULL ) return;
msg = "OK"; msg = "OK";
curtime = time( NULL ); curtime = time( NULL );
encoding = ""; 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 { else {
mime_vec.ptr = mime_type; mime_vec.ptr = mime_type;
mime_vec.len = strlen( 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; cl = (int64_t)filep->size;
conn->status_code = 200; conn->status_code = 200;
@@ -85,11 +85,11 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con
if ( filep->gzipped ) { 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 ) { 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; return;
} }
@@ -97,13 +97,13 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con
encoding = "Content-Encoding: gzip\r\n"; 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; return;
} }
XX_httplib_fclose_on_exec( filep, conn ); XX_httplib_fclose_on_exec( ctx, filep, conn );
/* /*
* If Range: header specified, act accordingly * 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 ) { 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; return;
} }
conn->status_code = 206; conn->status_code = 206;
cl = (n == 2) ? (((r2 > cl) ? cl : r2) - r1 + 1) : (cl - r1); 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 */ NULL, /* range buffer is big enough */
range, range,
sizeof(range), sizeof(range),
@@ -152,7 +152,7 @@ void XX_httplib_handle_static_file_request( struct httplib_connection *conn, con
*/ */
cors1 = "Access-Control-Allow-Origin: "; 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"; cors3 = "\r\n";
} }
else { 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( date, sizeof(date), & curtime );
XX_httplib_gmt_time_string( lm, sizeof(lm), & filep->last_modified ); 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 ); 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( conn ); XX_httplib_send_static_cache_header( ctx, conn );
httplib_printf( conn, httplib_printf( ctx, conn,
"Last-Modified: %s\r\n" "Last-Modified: %s\r\n"
"Etag: %s\r\n" "Etag: %s\r\n"
"Content-Type: %.*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, (int)mime_vec.len,
mime_vec.ptr, mime_vec.ptr,
cl, cl,
XX_httplib_suggest_connection_header(conn), XX_httplib_suggest_connection_header( ctx, conn ),
range, range,
encoding ); 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 * 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 ); if ( additional_headers != NULL ) httplib_printf( ctx, conn, "%.*s\r\n\r\n", (int)strlen( additional_headers ), additional_headers );
else httplib_printf( conn, "\r\n" ); 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 ); XX_httplib_fclose( filep );

View File

@@ -34,7 +34,7 @@
* request on a connection. * 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 *websock_key;
const char *version; const char *version;
@@ -45,7 +45,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
UNUSED_PARAMETER(path); UNUSED_PARAMETER(path);
if ( conn == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
websock_key = httplib_get_header( conn, "Sec-WebSocket-Key" ); websock_key = httplib_get_header( conn, "Sec-WebSocket-Key" );
version = httplib_get_header( conn, "Sec-WebSocket-Version" ); 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; conn->content_len = 8;
if ( httplib_read( conn, key3, 8 ) == 8 ) { if ( httplib_read( ctx, conn, key3, 8 ) == 8 ) {
/* /*
* This is the hixie version * 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; return;
} }
} }
@@ -92,7 +92,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
* This is an unknown version * 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; return;
} }
@@ -107,7 +107,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
* Reject wrong versions * 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; return;
} }
@@ -149,7 +149,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
* requests to invalid websocket addresses. * 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; return;
} }
@@ -157,9 +157,9 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
* Step 5: The websocket connection has been accepted * 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; return;
} }
@@ -176,7 +176,7 @@ void XX_httplib_handle_websocket_request( struct httplib_connection *conn, const
* Step 7: Enter the read loop * 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 * Step 8: Call the close handler

View File

@@ -44,7 +44,7 @@
* is_put_or_delete_request: out: put/delete file? * 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 */ /* TODO (high): Restructure this function */
@@ -62,10 +62,10 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename,
const char *cgi_ext; const char *cgi_ext;
#endif /* !NO_CGI */ #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; uri = conn->request_info.local_uri;
root = conn->ctx->document_root; root = ctx->document_root;
memset( filep, 0, sizeof(*filep) ); 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 ); *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, * 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. * 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; 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 ) { 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 ) { 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; break;
} }
} }
@@ -123,14 +123,14 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename,
* is now stored in "filename" variable. * 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) #if !defined(NO_CGI)
/* /*
* File exists. Check if it is a script type. * 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 * 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 ) { 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 ( truncated ) goto interpret_cleanup;
if ( XX_httplib_stat( conn, gz_path, filep ) ) { if ( XX_httplib_stat( ctx, conn, gz_path, filep ) ) {
if ( filep ) { if ( filep ) {
@@ -199,9 +199,9 @@ void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename,
if ( *p == '/' ) { if ( *p == '/' ) {
*p = '\0'; *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. * Shift PATH_INFO block one character right, e.g.

View File

@@ -25,27 +25,27 @@
#include "httplib_main.h" #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 * 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 * on the connection has authorization to use put and equivalent methods to
* write information to the server. * 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; struct file file = STRUCT_FILE_INITIALIZER;
const char *passfile; const char *passfile;
bool ret; bool ret;
if ( conn == NULL || conn->ctx == NULL ) return false; if ( ctx == NULL || conn == NULL ) return false;
if ( conn->ctx->document_root == 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 ); XX_httplib_fclose( & file );
return ret; return ret;

View File

@@ -28,23 +28,23 @@
#include "httplib_main.h" #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 * The function XX_httplib_is_file_in_memory() returns true, if a file defined
* by a specific path is located in memory. * 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; size_t size;
if ( conn == NULL || conn->ctx == NULL || filep == NULL ) return false; if ( ctx == NULL || conn == NULL || filep == NULL ) return false;
size = 0; 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 /* NOTE: override filep->size only on success. Otherwise, it might
* break constructs like if (!XX_httplib_stat() || !XX_httplib_fopen()) ... */ * break constructs like if (!XX_httplib_stat() || !XX_httplib_fopen()) ... */

View File

@@ -28,21 +28,21 @@
#include "httplib_main.h" #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 * 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 * not been modified sinze a given datetime and a 304 response should therefore
* be sufficient. * 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]; char etag[64];
const char *ims = httplib_get_header( conn, "If-Modified-Since" ); const char *ims = httplib_get_header( conn, "If-Modified-Since" );
const char *inm = httplib_get_header( conn, "If-None-Match" ); const char *inm = httplib_get_header( conn, "If-None-Match" );
if ( conn == NULL || filep == NULL ) return false; if ( ctx == NULL || conn == NULL || filep == NULL ) return false;
XX_httplib_construct_etag( etag, sizeof(etag), filep ); XX_httplib_construct_etag( ctx, etag, sizeof(etag), filep );
return (inm != NULL && ! httplib_strcasecmp( etag, inm ) ) || return (inm != NULL && ! httplib_strcasecmp( etag, inm ) ) ||
(ims != NULL && ( filep->last_modified <= XX_httplib_parse_date_string( ims ) ) ) ; (ims != NULL && ( filep->last_modified <= XX_httplib_parse_date_string( ims ) ) ) ;

View File

@@ -32,12 +32,12 @@
static const char *header_val( const struct httplib_connection *conn, const char *header ); 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. * 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; const struct httplib_request_info *ri;
struct file fi; struct file fi;
@@ -48,11 +48,11 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) {
const char *user_agent; const char *user_agent;
char buf[4096]; 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; 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. * 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 ); if ( httplib_localtime_r( &conn->conn_birth_time, &tmm ) != NULL ) strftime( date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", &tmm );
else { else {
@@ -76,7 +76,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) {
referer = header_val( conn, "Referer" ); referer = header_val( conn, "Referer" );
user_agent = header_val( conn, "User-Agent" ); user_agent = header_val( conn, "User-Agent" );
XX_httplib_snprintf( conn, XX_httplib_snprintf( ctx, conn,
NULL, /* Ignore truncation in access log */ NULL, /* Ignore truncation in access log */
buf, buf,
sizeof(buf), sizeof(buf),
@@ -94,7 +94,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) {
referer, referer,
user_agent ); 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 ) { if ( fi.fp ) {

View File

@@ -617,7 +617,6 @@ struct httplib_context {
/****************************************************************************************/ /****************************************************************************************/
struct httplib_connection { /* */ struct httplib_connection { /* */
struct httplib_request_info request_info; /* The request info of the 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 * ssl; /* SSL descriptor */
SSL_CTX * client_ssl_ctx; /* SSL context for client connections */ SSL_CTX * client_ssl_ctx; /* SSL context for client connections */
struct socket client; /* Connected client */ struct socket client; /* Connected client */
@@ -651,6 +650,7 @@ struct worker_thread_args {
struct websocket_client_thread_data { struct websocket_client_thread_data {
struct httplib_context *ctx;
struct httplib_connection *conn; struct httplib_connection *conn;
httplib_websocket_data_handler data_handler; httplib_websocket_data_handler data_handler;
httplib_websocket_close_handler close_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); struct httplib_context *XX_httplib_abort_start( struct httplib_context *ctx, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
void XX_httplib_accept_new_connection( const struct socket *listener, struct httplib_context *ctx ); void XX_httplib_accept_new_connection( const struct socket *listener, struct httplib_context *ctx );
bool XX_httplib_authorize( struct httplib_connection *conn, struct file *filep ); bool XX_httplib_authorize( 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_ext( int index );
const char * XX_httplib_builtin_mime_type( int index ); const char * XX_httplib_builtin_mime_type( int index );
int XX_httplib_check_acl( struct httplib_context *ctx, uint32_t remote_ip ); 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 ); 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_all_listening_sockets( struct httplib_context *ctx );
void XX_httplib_close_connection( struct httplib_connection *conn ); void XX_httplib_close_connection( struct httplib_context *ctx, struct httplib_connection *conn );
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 );
int WINCDECL XX_httplib_compare_dir_entries( const void *p1, const void *p2 ); 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 ); 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 ); 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_delete_file( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path );
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 );
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 );
int XX_httplib_fclose( struct file *filep ); 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 ); const char * XX_httplib_fgets( char *buf, size_t size, struct file *filep, char **p );
bool XX_httplib_fopen( const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep ); bool XX_httplib_fopen( const struct httplib_context *ctx, const struct httplib_connection *conn, const char *path, const char *mode, struct file *filep );
bool XX_httplib_forward_body_data( struct httplib_connection *conn, FILE *fp, SOCKET sock, SSL *ssl ); bool XX_httplib_forward_body_data( 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_config_options( struct httplib_context *ctx );
void XX_httplib_free_context( struct httplib_context *ctx ); void XX_httplib_free_context( struct httplib_context *ctx );
const char * XX_httplib_get_header( const struct httplib_request_info *ri, const char *name ); const char * XX_httplib_get_header( const struct httplib_request_info *ri, const char *name );
void XX_httplib_get_mime_type( struct httplib_context *ctx, const char *path, struct vec *vec ); void XX_httplib_get_mime_type( const 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 ); 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 ); 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 ); int XX_httplib_get_request_len( const char *buf, int buflen );
void XX_httplib_get_system_name( char **sysName ); void XX_httplib_get_system_name( char **sysName );
enum uri_type_t XX_httplib_get_uri_type( const char *uri ); 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 ); bool XX_httplib_getreq( const 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_cgi_request( const struct httplib_context *ctx, struct httplib_connection *conn, const char *prog );
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 );
void XX_httplib_handle_file_based_request( struct httplib_connection *conn, const char *path, struct file *filep ); 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( 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 );
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 );
void XX_httplib_handle_request( struct httplib_connection *conn ); void XX_httplib_handle_request( struct httplib_context *ctx, 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_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( 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 );
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 );
bool XX_httplib_header_has_option( const char *header, const char *option ); bool XX_httplib_header_has_option( const char *header, const char *option );
bool XX_httplib_init_options( struct httplib_context *ctx ); bool XX_httplib_init_options( struct httplib_context *ctx );
void XX_httplib_interpret_uri( struct httplib_connection *conn, char *filename, size_t filename_buf_len, struct file *filep, bool *is_found, bool *is_script_resource, bool *is_websocket_request, bool *is_put_or_delete_request ); void XX_httplib_interpret_uri( 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( struct httplib_connection *conn ); 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_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 );
bool XX_httplib_is_file_opened( const 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_put_or_delete_method( const struct httplib_connection *conn );
bool XX_httplib_is_valid_http_method( const char *method ); bool XX_httplib_is_valid_http_method( const char *method );
int XX_httplib_is_valid_port( unsigned long port ); int XX_httplib_is_valid_port( unsigned long port );
bool XX_httplib_is_websocket_protocol( const struct httplib_connection *conn ); 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_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 ); 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); 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 ); void XX_httplib_mkcol( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path );
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 * XX_httplib_next_option( const char *list, struct vec *val, struct vec *eq_val ); 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_bool( const char *value, bool *config );
bool XX_httplib_option_value_to_int( const char *value, int *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 ); 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_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_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_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 ); 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_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_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( struct de *de ); void XX_httplib_print_dir_entry( const struct httplib_context *ctx, struct de *de );
void XX_httplib_process_new_connection( struct httplib_connection *conn ); 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 ); bool XX_httplib_process_options( struct httplib_context *ctx, const struct httplib_option_t *options );
void XX_httplib_produce_socket( struct httplib_context *ctx, const struct socket *sp ); void XX_httplib_produce_socket( struct httplib_context *ctx, const struct socket *sp );
int XX_httplib_pull( FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout ); int XX_httplib_pull( const struct httplib_context *ctx, FILE *fp, struct httplib_connection *conn, char *buf, int len, double timeout );
int XX_httplib_pull_all( FILE *fp, struct httplib_connection *conn, char *buf, int len ); int XX_httplib_pull_all( const struct httplib_context *ctx, 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 ); 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( struct httplib_connection *conn, const char *path ); int XX_httplib_put_dir( const struct httplib_context *ctx, struct httplib_connection *conn, const char *path );
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 );
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 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 );
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 );
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 );
int XX_httplib_refresh_trust( struct httplib_connection *conn ); int XX_httplib_refresh_trust( const struct httplib_context *ctx, struct httplib_connection *conn );
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 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 );
void XX_httplib_remove_double_dots_and_double_slashes( char *s ); void XX_httplib_remove_double_dots_and_double_slashes( char *s );
void XX_httplib_reset_per_request_attributes( struct httplib_connection *conn ); 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 *) ); 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_connection *conn ); void XX_httplib_send_authorization_request( struct httplib_context *ctx, 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_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( struct httplib_connection *, int, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(3, 4); 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( struct httplib_connection *conn ); int XX_httplib_send_no_cache_header( const struct httplib_context *ctx, struct httplib_connection *conn );
void XX_httplib_send_options( 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( 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( 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 );
int XX_httplib_set_acl_option( struct httplib_context *ctx ); int XX_httplib_set_acl_option( struct httplib_context *ctx );
void XX_httplib_set_close_on_exec( SOCKET sock ); void XX_httplib_set_close_on_exec( SOCKET sock );
bool XX_httplib_set_gpass_option( struct httplib_context *ctx ); 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_ports_option( struct httplib_context *ctx );
int XX_httplib_set_sock_timeout( SOCKET sock, int milliseconds ); int XX_httplib_set_sock_timeout( SOCKET sock, int milliseconds );
int XX_httplib_set_tcp_nodelay( SOCKET sock, bool nodelay_on ); 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 ); 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_set_uid_option( struct httplib_context *ctx );
bool XX_httplib_should_decode_url( 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_connection *conn ); 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( char **buf, const char *delimiters );
char * XX_httplib_skip_quoted( char **buf, const char *delimiters, const char *whitespace, char quotechar ); 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 ); 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_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_stat( const struct httplib_context *ctx, 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 ); 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_connection *conn ); 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 ); 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 ); LIBHTTP_THREAD XX_httplib_worker_thread( void *thread_func_param );

View File

@@ -65,7 +65,7 @@ static void master_thread_run(void *thread_func_param) {
if ( ctx == NULL ) return; if ( ctx == NULL ) return;
XX_httplib_set_thread_name( "master" ); XX_httplib_set_thread_name( ctx, "master" );
/* /*
* Increase priority of the master thread * Increase priority of the master thread

View File

@@ -29,14 +29,14 @@
#include "httplib_utils.h" #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 * 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 * client. The MKCOL method is used to create a new collection resource at the
* location specificied by the request URI. * 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 rc;
int body_len; int body_len;
@@ -45,8 +45,8 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) {
time_t curtime; time_t curtime;
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
if ( conn->ctx->document_root == NULL ) return; if ( ctx->document_root == NULL ) return;
curtime = time( NULL ); 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) ); 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 ) { 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 ! * 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; return;
} }
@@ -75,7 +75,7 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) {
if ( body_len > 0 ) { 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; return;
} }
@@ -85,17 +85,17 @@ void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ) {
conn->status_code = 201; conn->status_code = 201;
XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); 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 ); 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( conn ); XX_httplib_send_static_cache_header( ctx, 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, "Content-Length: 0\r\n" "Connection: %s\r\n\r\n", XX_httplib_suggest_connection_header( ctx, conn ) );
} }
else if ( rc == -1 ) { 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 ) ); 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( conn, 403, "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( conn, 409, "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( conn, 500, "fopen(%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 */ } /* XX_httplib_mkcol */

View File

@@ -28,7 +28,7 @@
#include "httplib_main.h" #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 * 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 * hidden from browsing by the remote client. A used provided list of file
@@ -36,15 +36,15 @@
* the patterns defined by the user. * 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 *pw_pattern;
const char *pattern; const char *pattern;
if ( conn == NULL || conn->ctx == NULL ) return false; if ( ctx == NULL ) return false;
pw_pattern = "**" PASSWORDS_FILE_NAME "$"; 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 ) || 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 ); ( pattern != NULL && XX_httplib_match_prefix( pattern, strlen( pattern ), path ) > 0 );

View File

@@ -33,7 +33,7 @@
* or search for .htpasswd in the requested directory. * 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 name[PATH_MAX];
char error_string[ERROR_STRING_LEN]; 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; struct file file = STRUCT_FILE_INITIALIZER;
bool truncated; 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 ) { if ( gpass != NULL ) {
@@ -53,9 +53,9 @@ void XX_httplib_open_auth_file( struct httplib_connection *conn, const char *pat
* Use global passwords file * 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 * 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; 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 ) );
} }
} }

View File

@@ -32,7 +32,7 @@
* Return 1 on success. Always initializes the ah structure. * 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 *name;
char *value; char *value;
@@ -40,7 +40,7 @@ int XX_httplib_parse_auth_header(struct httplib_connection *conn, char *buf, siz
const char *auth_header; const char *auth_header;
uint64_t nonce; uint64_t nonce;
if ( ah == NULL || conn == NULL ) return 0; if ( ctx == NULL || ah == NULL || conn == NULL ) return 0;
memset( ah, 0, sizeof(*ah) ); memset( ah, 0, sizeof(*ah) );
if ( (auth_header = httplib_get_header( conn, "Authorization" )) == NULL || httplib_strncasecmp( auth_header, "Digest ", 7 ) != 0 ) return 0; 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. * 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 * 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. * 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 * 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. * 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 * CGI needs it as REMOTE_USER

View File

@@ -104,8 +104,8 @@ void XX_httplib_path_to_unicode( const char *path, wchar_t *wbuf, size_t wbuf_le
*/ */
/* /*
if (conn) { if ( ctx != NULL ) {
if (conn->ctx->config[WINDOWS_CASE_SENSITIVE]) { if (ctx->config[WINDOWS_CASE_SENSITIVE]) {
fcompare = wcscmp; fcompare = wcscmp;
} }
} }

View File

@@ -31,7 +31,7 @@
#include "httplib_utils.h" #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 * The function XX_httplib_prepare_cgi_environment() is used to prepare all
* environment variables before a CGI script is called. * environment variables before a CGI script is called.
@@ -39,7 +39,7 @@
#if !defined(NO_CGI) #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; const char *s;
struct vec var_vec; struct vec var_vec;
@@ -49,7 +49,7 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const
int i; int i;
bool truncated; 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->conn = conn;
env->buflen = CGI_ENVIRONMENT_SIZE; env->buflen = CGI_ENVIRONMENT_SIZE;
@@ -59,48 +59,48 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const
env->varused = 0; env->varused = 0;
env->var = httplib_malloc( env->buflen * sizeof(char *) ); 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 ); if ( ctx->authentication_domain != NULL ) XX_httplib_addenv( ctx, env, "SERVER_NAME=%s", ctx->authentication_domain );
XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->document_root ); XX_httplib_addenv( ctx, env, "SERVER_ROOT=%s", ctx->document_root );
XX_httplib_addenv( env, "DOCUMENT_ROOT=%s", conn->ctx->document_root ); XX_httplib_addenv( ctx, env, "DOCUMENT_ROOT=%s", ctx->document_root );
XX_httplib_addenv( env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() ); XX_httplib_addenv( ctx, env, "SERVER_SOFTWARE=%s/%s", "LibHTTP", httplib_version() );
/* /*
* Prepare the environment block * Prepare the environment block
*/ */
XX_httplib_addenv( env, "%s", "GATEWAY_INTERFACE=CGI/1.1" ); XX_httplib_addenv( ctx, env, "%s", "GATEWAY_INTERFACE=CGI/1.1" );
XX_httplib_addenv( env, "%s", "SERVER_PROTOCOL=HTTP/1.1" ); XX_httplib_addenv( ctx, env, "%s", "SERVER_PROTOCOL=HTTP/1.1" );
XX_httplib_addenv( env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */ 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 ) ); 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( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin.sin_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_sockaddr_to_string( src_addr, sizeof(src_addr), &conn->client.rsa );
XX_httplib_addenv( env, "REMOTE_ADDR=%s", src_addr ); XX_httplib_addenv( ctx, env, "REMOTE_ADDR=%s", src_addr );
XX_httplib_addenv( env, "REQUEST_METHOD=%s", conn->request_info.request_method ); XX_httplib_addenv( ctx, env, "REQUEST_METHOD=%s", conn->request_info.request_method );
XX_httplib_addenv( env, "REMOTE_PORT=%d", conn->request_info.remote_port ); XX_httplib_addenv( ctx, env, "REMOTE_PORT=%d", conn->request_info.remote_port );
XX_httplib_addenv( env, "REQUEST_URI=%s", conn->request_info.request_uri ); XX_httplib_addenv( ctx, 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, "LOCAL_URI=%s", conn->request_info.local_uri );
/* /*
* SCRIPT_NAME * 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 ); if ( conn->path_info == NULL ) XX_httplib_addenv( ctx, env, "PATH_TRANSLATED=%s", ctx->document_root );
else XX_httplib_addenv( env, "PATH_TRANSLATED=%s%s", conn->ctx->document_root, conn->path_info ); 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 ( (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( env, "QUERY_STRING=%s", conn->request_info.query_string ); 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( env, "CONTENT_LENGTH=%s", s ); 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( env, "PATH=%s", s ); if ( (s = getenv( "PATH" )) != NULL ) XX_httplib_addenv( ctx, env, "PATH=%s", s );
if ( conn->path_info != NULL ) XX_httplib_addenv( env, "PATH_INFO=%s", conn->path_info ); if ( conn->path_info != NULL ) XX_httplib_addenv( ctx, env, "PATH_INFO=%s", conn->path_info );
if (conn->status_code > 0) { 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 * 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 defined(_WIN32)
if ( (s = getenv( "COMSPEC" )) != NULL ) XX_httplib_addenv( env, "COMSPEC=%s", s ); if ( (s = getenv( "COMSPEC" )) != NULL ) XX_httplib_addenv( ctx, env, "COMSPEC=%s", s );
if ( (s = getenv( "SYSTEMROOT" )) != NULL ) XX_httplib_addenv( env, "SYSTEMROOT=%s", s ); if ( (s = getenv( "SYSTEMROOT" )) != NULL ) XX_httplib_addenv( ctx, env, "SYSTEMROOT=%s", s );
if ( (s = getenv( "SystemDrive" )) != NULL ) XX_httplib_addenv( env, "SystemDrive=%s", s ); if ( (s = getenv( "SystemDrive" )) != NULL ) XX_httplib_addenv( ctx, env, "SystemDrive=%s", s );
if ( (s = getenv( "ProgramFiles" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles=%s", s ); if ( (s = getenv( "ProgramFiles" )) != NULL ) XX_httplib_addenv( ctx, env, "ProgramFiles=%s", s );
if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) XX_httplib_addenv( env, "ProgramFiles(x86)=%s", s ); if ( (s = getenv( "ProgramFiles(x86)" )) != NULL ) XX_httplib_addenv( ctx, env, "ProgramFiles(x86)=%s", s );
#else #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 */ #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) { if (conn->request_info.remote_user != NULL) {
XX_httplib_addenv( env, "REMOTE_USER=%s", conn->request_info.remote_user ); XX_httplib_addenv( ctx, env, "REMOTE_USER=%s", conn->request_info.remote_user );
XX_httplib_addenv( env, "%s", "AUTH_TYPE=Digest" ); 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; i<conn->request_info.num_headers; i++) { for (i=0; i<conn->request_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 ) { 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; continue;
} }
@@ -152,18 +152,18 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const
*p = (char)toupper(*(unsigned char *)p); *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 * Add user-specified variables
*/ */
s = conn->ctx->cgi_environment; s = ctx->cgi_environment;
while ( (s = XX_httplib_next_option( s, &var_vec, NULL )) != NULL ) { 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; env->var[env->varused] = NULL;

View File

@@ -28,24 +28,26 @@
#include "httplib_main.h" #include "httplib_main.h"
#include "httplib_string.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 size[64];
char mod[64]; char mod[64];
char href[PATH_MAX * 3 /* worst case */]; char href[PATH_MAX * 3 /* worst case */];
struct tm tmm; 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 { else {
/* /*
* We use (signed) cast below because MSVC 6 compiler cannot * We use (signed) cast below because MSVC 6 compiler cannot
* convert unsigned __int64 to double. Sigh. * 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 ); 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( de->conn, NULL, size, sizeof(size), "%.1fk", ((double)de->file.size) / 1024.0 ); 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( de->conn, NULL, size, sizeof(size), "%.1fM", ((double)de->file.size) / 1048576.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( de->conn, NULL, size, sizeof(size), "%.1fG", ((double)de->file.size) / 1073741824.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) ); 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,
"<tr><td><a href=\"%s%s%s\">%s%s</a></td>" "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
"<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n", "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
de->conn->request_info.local_uri, de->conn->request_info.local_uri,

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #include "httplib_main.h"
#include "httplib_string.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; va_list ap;
int result; int result;
va_start( ap, fmt ); va_start( ap, fmt );
result = XX_httplib_vprintf( conn, fmt, ap ); result = XX_httplib_vprintf( ctx, conn, fmt, ap );
va_end( ap ); va_end( ap );
return result; return result;

View File

@@ -29,13 +29,13 @@
#include "httplib_string.h" #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 * The function XX_httplib_process_new_connection() is used to process a new
* incoming connection on a socket. * 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; struct httplib_request_info *ri;
int keep_alive; int keep_alive;
@@ -49,7 +49,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
void * var; void * var;
} ptr; } ptr;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
ri = & conn->request_info; ri = & conn->request_info;
@@ -62,7 +62,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
was_error = false; was_error = false;
do { 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 * 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. * 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; was_error = true;
} }
else if ( strcmp( ri->http_version, "1.0" ) && strcmp( ri->http_version, "1.1" ) ) { 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 ); httplib_cry( DEBUG_LEVEL_ERROR, 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 ) ); XX_httplib_send_http_error( ctx, conn, 505, "%s", httplib_get_response_code_text( ctx, conn, 505 ) );
was_error = true; 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_NOPORT :
case URI_TYPE_ABS_PORT : 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; if ( hostend != NULL ) conn->request_info.local_uri = hostend;
else conn->request_info.local_uri = NULL; else conn->request_info.local_uri = NULL;
break; break;
default : default :
httplib_cry( DEBUG_LEVEL_ERROR, conn->ctx, conn, "%s: invalid URI", __func__ ); httplib_cry( DEBUG_LEVEL_ERROR, ctx, conn, "%s: invalid URI", __func__ );
XX_httplib_send_http_error( conn, 400, "%s", httplib_get_response_code_text( conn, 400 ) ); XX_httplib_send_http_error( ctx, conn, 400, "%s", httplib_get_response_code_text( ctx, conn, 400 ) );
conn->request_info.local_uri = NULL; conn->request_info.local_uri = NULL;
was_error = true; was_error = true;
@@ -131,9 +131,9 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
* handle request to local server * handle request to local server
*/ */
XX_httplib_handle_request( conn ); XX_httplib_handle_request( ctx, conn );
if ( conn->ctx->callbacks.end_request != NULL ) conn->ctx->callbacks.end_request( conn, conn->status_code ); if ( ctx->callbacks.end_request != NULL ) ctx->callbacks.end_request( conn, conn->status_code );
XX_httplib_log_access(conn); XX_httplib_log_access( ctx, conn );
} }
else { else {
@@ -166,7 +166,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
* in loop exit condition. * 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 * Discard all buffered data for this request

View File

@@ -34,7 +34,7 @@
* Return negative value on error, or number of bytes read on success. * 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 nread;
int err; 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 (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) ) { if ( nread > 0 || (nread == 0 && len == 0) ) {

View File

@@ -27,20 +27,20 @@
#include "httplib_main.h" #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 n;
int nread; int nread;
double timeout; double timeout;
if ( conn == NULL || conn->ctx == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
nread = 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 ) { if ( n < 0 ) {

View File

@@ -36,7 +36,7 @@
#endif #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, * 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 * socket or SSL descriptor. The function returns the number of bytes which
@@ -50,7 +50,7 @@
* been written. * 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 start;
struct timespec now; 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 function XX_httplib_push_all() pushes all data in a buffer to a socket.
* The number of bytes written is returned. * 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; double timeout;
int64_t n; int64_t n;

View File

@@ -39,7 +39,7 @@
* Return -2 if path can not be created. * 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]; char buf[PATH_MAX];
const char *s; const char *s;
@@ -48,6 +48,8 @@ int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ) {
size_t len; size_t len;
int res; int res;
if ( ctx == NULL ) return -2;
res = 1; res = 1;
s = path+2; s = path+2;
@@ -73,7 +75,7 @@ int XX_httplib_put_dir( struct httplib_connection *conn, const char *path ) {
* Try to create intermediate directory * 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 * path does not exixt and can not be created

View File

@@ -29,13 +29,13 @@
#include "httplib_utils.h" #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 * The function XX_httplib_put_file() processes a file PUT request coming from
* a remote client. * 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; struct file file = STRUCT_FILE_INITIALIZER;
const char *range; 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]; char error_string[ERROR_STRING_LEN];
time_t curtime; time_t curtime;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
if ( conn->ctx->document_root == NULL ) return; if ( ctx->document_root == NULL ) return;
curtime = time( NULL ); curtime = time( NULL );
if ( XX_httplib_stat( conn, path, &file ) ) { if ( XX_httplib_stat( ctx, conn, path, &file ) ) {
/* /*
* File already exists * 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 * 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; return;
} }
@@ -101,7 +101,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) {
} }
else { 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; return;
} }
} }
@@ -113,7 +113,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) {
*/ */
conn->status_code = 201; conn->status_code = 201;
rc = XX_httplib_put_dir( conn, path ); rc = XX_httplib_put_dir( ctx, conn, path );
} }
if ( rc == 0 ) { 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 ); 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 ) ); 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( conn ); XX_httplib_send_no_cache_header( ctx, 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, "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. * 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_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; 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_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; return;
} }
@@ -159,14 +159,14 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) {
* A file should be created or overwritten. * 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_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; return;
} }
XX_httplib_fclose_on_exec( & file, conn ); XX_httplib_fclose_on_exec( ctx, &file, conn );
range = httplib_get_header( conn, "Content-Range" ); range = httplib_get_header( conn, "Content-Range" );
r1 = 0; r1 = 0;
@@ -178,7 +178,7 @@ void XX_httplib_put_file( struct httplib_connection *conn, const char *path ) {
fseeko( file.fp, r1, SEEK_SET ); 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. * 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 ); 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 ) ); 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( conn ); XX_httplib_send_no_cache_header( ctx, 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, "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 ); XX_httplib_fclose( & file );

View File

@@ -27,7 +27,7 @@
#include "httplib_main.h" #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 n;
int64_t buffered_len; int64_t buffered_len;
@@ -36,7 +36,7 @@ static int httplib_read_inner( struct httplib_connection *conn, void *buffie, si
const char *body; const char *body;
char *buf; char *buf;
if ( conn == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
buf = buffie; buf = buffie;
@@ -90,7 +90,7 @@ static int httplib_read_inner( struct httplib_connection *conn, void *buffie, si
* socket. * 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; if ( n >= 0 ) nread += n;
else nread = (nread > 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 */ } /* 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; char c;
if ( conn == NULL ) return 0; if ( conn == NULL ) return 0;
conn->content_len++; 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; return c;
} /* httplib_getc */ } /* 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; 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)); size_t read_now = ((conn->chunk_remainder > len) ? (len) : (conn->chunk_remainder));
conn->content_len += (int)read_now; 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; all_read += (size_t)read_ret;
conn->chunk_remainder -= read_now; 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 * 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 * 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++) { 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; 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 (int)all_read;
} }
return httplib_read_inner( conn, buf, len ); return httplib_read_inner( ctx, conn, buf, len );
} /* httplib_read */ } /* httplib_read */

View File

@@ -28,14 +28,14 @@
#include "httplib_main.h" #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 * The function XX_httpib_read_auth_file() loops over the password file to
* read its contents. Include statements are honored which lets the routine * read its contents. Include statements are honored which lets the routine
* also open and scan child files. * 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; int is_authorized;
struct file fp; struct file fp;
@@ -45,7 +45,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct
char * var; char * var;
} ptr; } ptr;
if ( filep == NULL || workdata == NULL ) return false; if ( ctx == NULL || filep == NULL || workdata == NULL ) return false;
is_authorized = 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 ) ) { 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 ); 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; continue;
} }
@@ -100,7 +100,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct
* future) * 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; continue;
} }
@@ -108,7 +108,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct
if ( workdata->f_domain == NULL ) { 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; continue;
} }
@@ -119,7 +119,7 @@ bool XX_httplib_read_auth_file( struct file *filep, struct read_auth_file_struct
if ( workdata->f_ha1 == NULL ) { 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; continue;
} }

View File

@@ -29,7 +29,7 @@
#include "httplib_utils.h" #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 * 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) * 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. * 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 request_len;
int n; int n;
struct timespec last_action_time; struct timespec last_action_time;
double request_timeout; double request_timeout;
if ( conn == NULL || conn->ctx == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
n = 0; n = 0;
memset( & last_action_time, 0, sizeof(last_action_time) ); 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 ); 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 ); clock_gettime( CLOCK_MONOTONIC, & last_action_time );
while ( conn->ctx->status == CTX_STATUS_RUNNING && while ( ctx->status == CTX_STATUS_RUNNING &&
*nread < bufsiz && *nread < bufsiz &&
request_len == 0 && request_len == 0 &&
((XX_httplib_difftimespec(&last_action_time, &(conn->req_time)) <= request_timeout) || (request_timeout < 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; *nread += n;
if ( *nread > bufsiz ) return -2; if ( *nread > bufsiz ) return -2;

View File

@@ -28,12 +28,12 @@
#include "httplib_main.h" #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. * 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 /* Pointer to the beginning of the portion of the incoming websocket
* message queue. * message queue.
@@ -76,27 +76,27 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
unsigned char mop; /* mask flag and opcode */ unsigned char mop; /* mask flag and opcode */
double timeout; double timeout;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
data = mem; data = mem;
timeout = ((double)conn->ctx->websocket_timeout) / 1000.0; timeout = ((double)ctx->websocket_timeout) / 1000.0;
if ( timeout <= 0.0 ) timeout = ((double)conn->ctx->request_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 * Loop continuously, reading messages from the socket, invoking the
* callback, and waiting repeatedly until an error occurs. * callback, and waiting repeatedly until an error occurs.
*/ */
while ( conn->ctx->status == CTX_STATUS_RUNNING ) { while ( ctx->status == CTX_STATUS_RUNNING ) {
header_len = 0; header_len = 0;
if ( conn->data_len < conn->request_len ) { 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; break;
} }
@@ -145,7 +145,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
* connection * 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; break;
} }
} }
@@ -161,7 +161,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
if ( body_len < header_len ) { 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; break;
} }
@@ -183,7 +183,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
while ( len < data_len ) { 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 ) { if ( n <= 0 ) {
error = 1; error = 1;
@@ -195,7 +195,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
if (error) { 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; break;
} }
@@ -270,7 +270,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
* message queue. * 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 * 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 */ } /* XX_httplib_read_websocket */

View File

@@ -29,20 +29,20 @@
#include "httplib_string.h" #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 * The function XX_httplib_redirect_to_https_port() redirects a request to an
* encrypted connection over HTTPS. * 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]; char host[1024+1];
const char *host_header; const char *host_header;
size_t hostlen; size_t hostlen;
char *pos; char *pos;
if ( conn == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
host_header = httplib_get_header(conn, "Host"); host_header = httplib_get_header(conn, "Host");
hostlen = sizeof( 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 * 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, host,
(conn->ctx->listening_sockets[ssl_index].lsa.sa.sa_family == AF_INET6) (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( ctx->listening_sockets[ssl_index].lsa.sin6.sin6_port )
: (int)ntohs( conn->ctx->listening_sockets[ssl_index].lsa.sin.sin_port ), : (int)ntohs( ctx->listening_sockets[ssl_index].lsa.sin.sin_port ),
conn->request_info.local_uri, conn->request_info.local_uri,
(conn->request_info.query_string == NULL) ? "" : "?", (conn->request_info.query_string == NULL) ? "" : "?",
(conn->request_info.query_string == NULL) ? "" : conn->request_info.query_string); (conn->request_info.query_string == NULL) ? "" : conn->request_info.query_string);

View File

@@ -41,19 +41,19 @@ static long int data_check = 0;
#if !defined(NO_SSL) #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; volatile int *p_reload_lock;
struct stat cert_buf; struct stat cert_buf;
long int t; long int t;
char *pem; char *pem;
if ( conn == NULL || conn->ctx == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
p_reload_lock = & reload_lock; 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; if ( stat( pem, &cert_buf ) != -1 ) t = (long int)cert_buf.st_mtime;
else t = data_check; else t = data_check;
@@ -62,11 +62,11 @@ int XX_httplib_refresh_trust( struct httplib_connection *conn ) {
data_check = t; 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; return 0;
} }
@@ -74,7 +74,7 @@ int XX_httplib_refresh_trust( struct httplib_connection *conn ) {
if ( httplib_atomic_inc( p_reload_lock ) == 1 ) { 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; *p_reload_lock = 0;
} }
} }

View File

@@ -28,16 +28,16 @@
#include "httplib_main.h" #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 * The function XX_httplib_remove_bad_file() removes an invalid file and throws
* an error message if this does not succeed. * 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 ); 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 */ } /* XX_httplib_remove_bad_file */

View File

@@ -29,13 +29,13 @@
#include "httplib_string.h" #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. * 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 path[PATH_MAX];
char error_string[ERROR_STRING_LEN]; char error_string[ERROR_STRING_LEN];
@@ -45,6 +45,8 @@ int XX_httplib_remove_directory( struct httplib_connection *conn, const char *di
bool truncated; bool truncated;
int ok; int ok;
if ( ctx == NULL || dir == NULL ) return 0;
ok = 1; ok = 1;
dirp = httplib_opendir( dir ); 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; 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 * 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; 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; ok = 0;
} }
if ( de.file.membuf == NULL ) { 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 ( 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; else if ( httplib_remove( path ) == 0 ) ok = 0;

View File

@@ -28,7 +28,7 @@
#include "httplib_main.h" #include "httplib_main.h"
#include "httplib_string.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 path[PATH_MAX];
char error_string[ERROR_STRING_LEN]; 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; struct de de;
bool truncated; bool truncated;
if ( ctx == NULL ) return 0;
dirp = httplib_opendir( dir ); dirp = httplib_opendir( dir );
if ( dirp == NULL ) return 0; 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 * 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 * 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 ( 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; de.file_name = dp->d_name;
cb( &de, data ); cb( ctx, &de, data );
} }
httplib_closedir( dirp ); httplib_closedir( dirp );

View File

@@ -29,43 +29,43 @@
#include "httplib_pthread.h" #include "httplib_pthread.h"
#include "httplib_utils.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]; char date[64];
time_t curtime; time_t curtime;
uint64_t nonce; uint64_t nonce;
const char *auth_domain; const char *auth_domain;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
curtime = time( NULL ); curtime = time( NULL );
nonce = (uint64_t)conn->ctx->start_time; nonce = (uint64_t)ctx->start_time;
httplib_pthread_mutex_lock( & conn->ctx->nonce_mutex ); httplib_pthread_mutex_lock( & ctx->nonce_mutex );
nonce += conn->ctx->nonce_count; nonce += ctx->nonce_count;
++conn->ctx->nonce_count; ++ctx->nonce_count;
httplib_pthread_mutex_unlock( & conn->ctx->nonce_mutex ); httplib_pthread_mutex_unlock( & ctx->nonce_mutex );
nonce ^= conn->ctx->auth_nonce_mask; nonce ^= ctx->auth_nonce_mask;
conn->status_code = 401; conn->status_code = 401;
conn->must_close = true; conn->must_close = true;
XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); XX_httplib_gmt_time_string( date, sizeof(date), &curtime );
if ( conn->ctx->authentication_domain != NULL ) auth_domain = conn->ctx->authentication_domain; if ( ctx->authentication_domain != NULL ) auth_domain = ctx->authentication_domain;
else auth_domain = "example.com"; else auth_domain = "example.com";
httplib_printf( conn, "HTTP/1.1 401 Unauthorized\r\n" ); httplib_printf( ctx, conn, "HTTP/1.1 401 Unauthorized\r\n" );
XX_httplib_send_no_cache_header( conn ); XX_httplib_send_no_cache_header( ctx, conn );
httplib_printf( conn, httplib_printf( ctx, conn,
"Date: %s\r\n" "Date: %s\r\n"
"Connection: %s\r\n" "Connection: %s\r\n"
"Content-Length: 0\r\n" "Content-Length: 0\r\n"
"WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", " "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", "
"nonce=\"%" UINT64_FMT "\"\r\n\r\n", "nonce=\"%" UINT64_FMT "\"\r\n\r\n",
date, date,
XX_httplib_suggest_connection_header(conn), XX_httplib_suggest_connection_header( ctx, conn ),
auth_domain, auth_domain,
nonce ); nonce );

View File

@@ -28,29 +28,29 @@
#include "httplib_main.h" #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 function httplib_send_file() sends a file to the other peer. Optionally
* the MIME type and additional headers can be specified. * 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; 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 ( file.is_directory ) {
if ( conn == NULL || conn->ctx == NULL ) return; 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" );
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" );
} }
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 */ } /* httplib_send_file */

View File

@@ -34,7 +34,7 @@
* Send len bytes from the opened file to the client. * 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 buf[MG_BUF_LEN];
char error_string[ERROR_STRING_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; int loop_cnt;
#endif /* __linux__ */ #endif /* __linux__ */
if ( filep == NULL || conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || filep == NULL || conn == NULL ) return;
/* /*
* Sanity check the offset * 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; 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 * 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_offs = (off_t)offset;
sf_file = fileno( filep->fp ); sf_file = fileno( filep->fp );
@@ -140,8 +140,8 @@ void XX_httplib_send_file_data( struct httplib_connection *conn, struct file *fi
#endif #endif
if ( offset > 0 && fseeko( filep->fp, offset, SEEK_SET ) != 0 ) { 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 ) ); 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( conn, 500, "%s", "Error: Unable to access file at requested position." ); XX_httplib_send_http_error( ctx, conn, 500, "%s", "Error: Unable to access file at requested position." );
} }
else { 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 * 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 * Both read and were successful, adjust counters

View File

@@ -29,7 +29,7 @@
#include "httplib_string.h" #include "httplib_string.h"
#include "httplib_utils.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]; char buf[MG_BUF_LEN];
va_list ap; 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 *tstr;
const char *status_text; const char *status_text;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
curtime = time( NULL ); curtime = time( NULL );
error_handler = 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; 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 ) { 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 * Send user defined error pages, if defined
*/ */
error_handler = conn->ctx->error_pages; error_handler = ctx->error_pages;
error_page_file_ext = conn->ctx->index_files; error_page_file_ext = ctx->index_files;
page_handler_found = 0; page_handler_found = 0;
if ( error_handler != NULL ) { 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 * 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; break;
case 2 : 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) * 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; break;
default : default :
@@ -95,7 +95,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co
* Handler for all errors * 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; 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]; for (i=1; i<32 && tstr[i] != 0 && tstr[i] != ','; i++) buf[len + i - 1] = tstr[i];
buf[len + i - 1] = 0; 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; page_handler_found = 1;
break; break;
@@ -128,7 +128,7 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co
if ( page_handler_found ) { if ( page_handler_found ) {
conn->in_error_handler = true; 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; conn->in_error_handler = false;
return; return;
@@ -149,11 +149,11 @@ void XX_httplib_send_http_error( struct httplib_connection *conn, int status, co
conn->must_close = true; conn->must_close = true;
httplib_printf( conn, "HTTP/1.1 %d %s\r\n", status, status_text ); httplib_printf( ctx, conn, "HTTP/1.1 %d %s\r\n", status, status_text );
XX_httplib_send_no_cache_header( conn ); XX_httplib_send_no_cache_header( ctx, conn );
if ( has_body ) httplib_printf( conn, "%s", "Content-Type: text/plain; charset=utf-8\r\n" ); if ( has_body ) httplib_printf( ctx, 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 ); 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 * 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 ) { 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 ) { if ( fmt != NULL ) {
va_start( ap, fmt ); 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 ); va_end( ap );
httplib_write( conn, buf, strlen(buf) ); httplib_write( ctx, conn, buf, strlen(buf) );
} }
} }

View File

@@ -27,13 +27,13 @@
#include "httplib_main.h" #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. * Send all current and obsolete cache opt-out directives.
*/ */
return httplib_printf( conn, return httplib_printf( ctx, conn,
"Cache-Control: no-cache, no-store, " "Cache-Control: no-cache, no-store, "
"must-revalidate, private, max-age=0\r\n" "must-revalidate, private, max-age=0\r\n"
"Pragma: no-cache\r\n" "Pragma: no-cache\r\n"

View File

@@ -29,19 +29,19 @@
#include "httplib_utils.h" #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 * The function XX_httplib_send_options() sends a list of allowed options a
* client can use to connect to the server. * 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]; char date[64];
time_t curtime; time_t curtime;
if ( conn == NULL || conn->ctx == NULL ) return; if ( ctx == NULL || conn == NULL ) return;
if ( conn->ctx->document_root == NULL ) return; if ( ctx->document_root == NULL ) return;
curtime = time( NULL ); curtime = time( NULL );
conn->status_code = 200; 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 ); XX_httplib_gmt_time_string( date, sizeof(date), &curtime );
httplib_printf( conn, httplib_printf( ctx, conn,
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Date: %s\r\n" "Date: %s\r\n"
/* TODO: "Cache-Control" (?) */ /* TODO: "Cache-Control" (?) */
@@ -58,6 +58,6 @@ void XX_httplib_send_options( struct httplib_connection *conn ) {
"PROPFIND, MKCOL\r\n" "PROPFIND, MKCOL\r\n"
"DAV: 1\r\n\r\n", "DAV: 1\r\n\r\n",
date, date,
XX_httplib_suggest_connection_header( conn ) ); XX_httplib_suggest_connection_header( ctx, conn ) );
} /* XX_httplib_send_options */ } /* XX_httplib_send_options */

View File

@@ -28,22 +28,22 @@
#include "httplib_main.h" #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 * The function XX_httplib_send_static_cache_header() sends cache headers
* depending on the cache setting of the current context. * 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. * Read the server config to check how long a file may be cached.
* The configuration is in seconds. * 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 * 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. * 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. * 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 */ } /* XX_httplib_send_static_cache_header */

View File

@@ -32,13 +32,13 @@
#define B64_SHA_LEN (sizeof(sha)*2) #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 * The function XX_httplib_send_websocket_handshake() sends a handshake over
* a websocket connection. * 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"; static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
const char *protocol; const char *protocol;
@@ -48,13 +48,15 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const
SHA1_CTX sha_ctx; SHA1_CTX sha_ctx;
bool truncated; bool truncated;
if ( ctx == NULL ) return 0;
protocol = NULL; protocol = NULL;
/* /*
* Calculate Sec-WebSocket-Accept reply from Sec-WebSocket-Key. * 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 ) { if ( truncated ) {
conn->must_close = true; 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 ); SHA1Final( (unsigned char *)sha, &sha_ctx );
httplib_base64_encode( (unsigned char *)sha, sizeof(sha), b64_sha, B64_SHA_LEN ); 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" "HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n" "Upgrade: websocket\r\n"
"Connection: Upgrade\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. * 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 { else {
@@ -103,14 +105,14 @@ int XX_httplib_send_websocket_handshake( struct httplib_connection *conn, const
* no subprotocol is acceptable. * 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 * TODO: Real subprotocol negotiation instead of just taking the first
* websocket subprotocol suggested by the client. * websocket subprotocol suggested by the client.
*/ */
} }
else httplib_printf( conn, "%s", "\r\n" ); else httplib_printf( ctx, conn, "%s", "\r\n" );
return 1; return 1;

View File

@@ -45,7 +45,7 @@ bool XX_httplib_set_gpass_option( struct httplib_context *ctx ) {
path = ctx->global_auth_file; 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 ) ); 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; return false;

View File

@@ -54,11 +54,11 @@ typedef struct tagTHREADNAME_INFO {
#endif /* __linux__ */ #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/.. */ 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) #if defined(_WIN32)

View File

@@ -24,8 +24,8 @@
#include "httplib_main.h" #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 */ } /* XX_httplib_should_decode_url */

View File

@@ -25,7 +25,7 @@
#include "httplib_main.h" #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 * The function XX_httplib_should_keep_alive() returns true if the connection
* should be kept alive and false if it should be closed. * should be kept alive and false if it should be closed.
@@ -35,19 +35,19 @@
* request parsing failed. * 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 *http_version;
const char *header; 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; http_version = conn->request_info.http_version;
header = httplib_get_header( conn, "Connection" ); header = httplib_get_header( conn, "Connection" );
if ( conn->must_close ) return false; if ( conn->must_close ) return false;
if ( conn->status_code == 401 ) 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 && ! XX_httplib_header_has_option( header, "keep-alive" ) ) return false;
if ( header == NULL && http_version != NULL && strcmp( http_version, "1.1" ) ) return false; if ( header == NULL && http_version != NULL && strcmp( http_version, "1.1" ) ) return false;

View File

@@ -29,19 +29,19 @@
#include "httplib_string.h" #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 * 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 * to a connection. The string can be formated with a format string and
* parameters in the same way as the snprintf function works. * 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_list ap;
va_start( ap, fmt ); 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 ); va_end( ap );
} /* XX_httplib_snprintf */ } /* XX_httplib_snprintf */

View File

@@ -40,7 +40,7 @@ static void trim_trailing_whitespaces( char *s ) {
} /* trim_trailing_whitespaces */ } /* 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; HANDLE me;
char *p; char *p;
@@ -56,7 +56,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro
UNUSED_PARAMETER(envp); UNUSED_PARAMETER(envp);
if ( conn == NULL || conn->ctx == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
memset( &si, 0, sizeof(si) ); memset( &si, 0, sizeof(si) );
si.cb = 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 * If CGI file is a script, try to read the interpreter line
*/ */
interp = conn->ctx->cgi_interpreter; interp = ctx->cgi_interpreter;
if ( interp == NULL ) { 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 ) { 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; pi.hProcess = (pid_t)-1;
/* /*
@@ -157,7 +157,7 @@ spawn_cleanup:
#else /* _WIN32 */ #else /* _WIN32 */
#ifndef NO_CGI #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; pid_t pid;
const char *interp; const char *interp;
@@ -165,7 +165,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro
UNUSED_PARAMETER(envblk); UNUSED_PARAMETER(envblk);
if ( conn == NULL || conn->ctx == NULL ) return 0; if ( ctx == NULL || conn == NULL ) return 0;
if ( (pid = fork()) == -1 ) { if ( (pid = fork()) == -1 ) {
@@ -173,7 +173,7 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro
* Parent * 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 ) { else if ( pid == 0 ) {
@@ -182,10 +182,10 @@ pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *pro
* Child * 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 ) ); 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, conn->ctx, conn, "%s: dup2(%d, 0): %s", __func__, fdin[0], 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, conn->ctx, conn, "%s: dup2(%d, 1): %s", __func__, fdout[1], 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, conn->ctx, conn, "%s: dup2(%d, 2): %s", __func__, fderr[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 { else {
/* /*
* Keep stderr and stdout in two different pipes. * 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 ); signal( SIGCHLD, SIG_DFL );
interp = conn->ctx->cgi_interpreter; interp = ctx->cgi_interpreter;
if ( interp == NULL ) { if ( interp == NULL ) {
execle( prog, prog, NULL, envp ); 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 { else {
execle( interp, interp, prog, NULL, envp ); 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 ) );
} }
} }

View File

@@ -29,10 +29,10 @@
#include "httplib_string.h" #include "httplib_string.h"
#include "httplib_utils.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 file_name[MG_BUF_LEN];
char path[512]; char path[512];
@@ -44,7 +44,7 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch
size_t len; size_t len;
bool truncated; 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; truncated = false;
@@ -61,9 +61,9 @@ static void do_ssi_include( struct httplib_connection *conn, const char *ssi, ch
*/ */
file_name[511] = 0; 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; 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; 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 ( ! truncated ) {
if ( (p = strrchr( path, '/' )) != NULL) p[1] = '\0'; if ( (p = strrchr( path, '/' )) != NULL) p[1] = '\0';
len = strlen( path ); 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 { 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; return;
} }
if ( truncated ) { 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; 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; 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 ); 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( conn, &file, 0, INT64_MAX ); else XX_httplib_send_file_data( ctx, conn, &file, 0, INT64_MAX );
XX_httplib_fclose( & file ); 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) #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 cmd[1024] = "";
char error_string[ERROR_STRING_LEN]; 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 ) { 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 { else {
cmd[1023] = 0; cmd[1023] = 0;
if ( (file.fp = popen( cmd, "r" ) ) == NULL ) { 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 { 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 ); pclose( file.fp );
} }
} }
@@ -165,7 +165,7 @@ static int httplib_fgetc( struct file *filep, int offset ) {
} /* httplib_fgetc */ } /* 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]; char buf[MG_BUF_LEN];
int ch; int ch;
@@ -173,9 +173,9 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st
int len; int len;
int in_ssi_tag; 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; return;
} }
@@ -199,21 +199,21 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st
* Not an SSI tag, pass it * Not an SSI tag, pass it
*/ */
httplib_write( conn, buf, (size_t)len ); httplib_write( ctx, conn, buf, (size_t)len );
} }
else { else {
if ( ! memcmp( buf + 5, "include", 7 ) ) { 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) #if !defined(NO_POPEN)
} else if ( ! memcmp( buf+5, "exec", 4 ) ) {
else if (!memcmp(buf + 5, "exec", 4)) {
do_ssi_exec(conn, buf + 9); do_ssi_exec( ctx, conn, buf+9 );
#endif /* !NO_POPEN */
} }
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; 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 ) { 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; len = 0;
} }
@@ -243,7 +243,7 @@ static void send_ssi_file( struct httplib_connection *conn, const char *path, st
in_ssi_tag = 1; 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; len = 0;
buf[len++] = (char)(ch & 0xff); 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)) { if (len == (int)sizeof(buf)) {
httplib_write(conn, buf, (size_t)len); httplib_write( ctx, conn, buf, (size_t)len );
len = 0; 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 * 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 */ } /* 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 date[64];
char error_string[ERROR_STRING_LEN]; 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 *cors2;
const char *cors3; 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 ); curtime = time( NULL );
@@ -289,7 +289,7 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const
*/ */
cors1 = "Access-Control-Allow-Origin: "; 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"; cors3 = "\r\n";
} }
@@ -299,25 +299,25 @@ void XX_httplib_handle_ssi_file_request( struct httplib_connection *conn, const
cors3 = ""; 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), * File exists (precondition for calling this function),
* but can not be opened by the server. * 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 { else {
conn->must_close = true; conn->must_close = true;
XX_httplib_gmt_time_string( date, sizeof(date), &curtime ); XX_httplib_gmt_time_string( date, sizeof(date), &curtime );
XX_httplib_fclose_on_exec( filep, conn ); XX_httplib_fclose_on_exec( ctx, filep, conn );
httplib_printf(conn, "HTTP/1.1 200 OK\r\n"); httplib_printf( ctx, conn, "HTTP/1.1 200 OK\r\n" );
XX_httplib_send_no_cache_header( conn ); XX_httplib_send_no_cache_header( ctx, 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 ) ); 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( conn, path, filep, 0 ); send_ssi_file( ctx, conn, path, filep, 0 );
XX_httplib_fclose( filep ); XX_httplib_fclose( filep );
} }

View File

@@ -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 ); long XX_httplib_ssl_get_protocol( int version_id );
unsigned long XX_httplib_ssl_id_callback( void ); unsigned long XX_httplib_ssl_id_callback( void );
void XX_httplib_ssl_locking_callback( int mode, int mutex_num, const char *file, int line ); 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_ssl_use_pem_file( const struct httplib_context *ctx, const char *pem );
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 *) );
void XX_httplib_tls_dtor( void *key ); void XX_httplib_tls_dtor( void *key );
void XX_httplib_uninitialize_ssl( struct httplib_context *ctx ); void XX_httplib_uninitialize_ssl( struct httplib_context *ctx );

View File

@@ -29,7 +29,7 @@
#include "httplib_ssl.h" #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 * 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. * is passed as a parameter with the filename of the certificate.
@@ -37,7 +37,7 @@
#if ! defined(NO_SSL) #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; if ( ctx == NULL || pem == NULL ) return 0;

View File

@@ -36,17 +36,17 @@
#if !defined(NO_SSL) #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 ret;
int err; int err;
unsigned i; 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; if ( ! trust_ret ) return trust_ret;
} }

View File

@@ -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]; wchar_t wbuf[PATH_MAX];
WIN32_FILE_ATTRIBUTE_DATA info; 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, * last_modified = now ... assumes the file may change during runtime,
* so every XX_httplib_fopen call may return different data * 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 * 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 * browser caching. Since we do not know, we have to assume the file
* in memory may change. * in memory may change.
@@ -121,7 +121,7 @@ int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct f
#else #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; 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) ); 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 ) { if ( stat( path, &st ) == 0 ) {

View File

@@ -35,7 +35,7 @@
* negative number to indicate a failure. * 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]; char buf[MG_BUF_LEN];
int64_t len; int64_t len;
@@ -43,15 +43,17 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path )
int n; int n;
struct file fi; struct file fi;
if ( ctx == NULL ) return -1;
len = 0; len = 0;
if ( conn->consumed_content != 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; return -11;
} }
ret = XX_httplib_put_dir( conn, path ); ret = XX_httplib_put_dir( ctx, conn, path );
if ( ret < 0 ) { if ( ret < 0 ) {
/* /*
@@ -71,9 +73,9 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path )
return 0; 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 ) { while ( ret > 0 ) {
@@ -81,15 +83,15 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path )
if ( n != ret ) { if ( n != ret ) {
XX_httplib_fclose( & fi ); XX_httplib_fclose( & fi );
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
return -13; return -13;
} }
ret = httplib_read( conn, buf, sizeof(buf) ); ret = httplib_read( ctx, conn, buf, sizeof(buf) );
} }
if ( XX_httplib_fclose( & fi ) != 0 ) { if ( XX_httplib_fclose( & fi ) != 0 ) {
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( ctx, conn, path );
return -14; return -14;
} }

View File

@@ -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); 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( 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 );
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 );

View File

@@ -29,7 +29,7 @@
#include "httplib_string.h" #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 * 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 * 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. * 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; const char *list;
struct file file = STRUCT_FILE_INITIALIZER; 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; size_t n;
bool found; bool found;
if ( conn == NULL || conn->ctx == NULL || path == NULL ) return 0; if ( ctx == NULL || conn == NULL || path == NULL ) return 0;
if ( conn->ctx->document_root == NULL ) return 0; if ( ctx->document_root == NULL ) return 0;
list = conn->ctx->index_files; list = ctx->index_files;
n = strlen( path ); n = strlen( path );
found = false; found = false;
@@ -84,7 +84,7 @@ int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *pat
* Does it exist? * Does it exist?
*/ */
if ( XX_httplib_stat( conn, path, &file ) ) { if ( XX_httplib_stat( ctx, conn, path, &file ) ) {
/* /*
* Yes it does, break the loop * Yes it does, break the loop

View File

@@ -28,15 +28,15 @@
#include "httplib_main.h" #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() * 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 * returns a string to be used in the header which suggests the connection to
* be either closed, or kept alive for further requests. * 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 */ } /* XX_httplib_suggest_connection_header */

View File

@@ -22,7 +22,7 @@
#define LEAP_YEAR(x) ( ((x)%4) == 0 && ( ((x)%100) != 0 || ((x)%400) == 0 ) ) #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 ); 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 ); 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 ); int XX_httplib_inet_pton( int af, const char *src, void *dst, size_t dstlen );

View File

@@ -145,7 +145,7 @@ static int alloc_vprintf( char **out_buf, char *prealloc_buf, size_t prealloc_si
} /* alloc_vprintf */ } /* 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 mem[MG_BUF_LEN];
char *buf; char *buf;
@@ -153,7 +153,7 @@ int XX_httplib_vprintf( struct httplib_connection *conn, const char *fmt, va_lis
buf = NULL; 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 ); if ( buf != mem ) buf = httplib_free( buf );
return len; return len;

View File

@@ -33,7 +33,7 @@
* Report errors if length is exceeded. * 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; int n;
bool ok; bool ok;
@@ -60,7 +60,7 @@ void XX_httplib_vsnprintf( const struct httplib_connection *conn, bool *truncate
else { else {
if ( truncated != NULL ) *truncated = true; 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; n = (int)buflen - 1;
} }
buf[n] = '\0'; buf[n] = '\0';

View File

@@ -20,9 +20,6 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* ============
* Release: 2.0
*/ */
#include "httplib_main.h" #include "httplib_main.h"
@@ -31,32 +28,41 @@
* LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ); * LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data );
* *
* The function XX_httplib_websocket_client_thread() is the worker thread which * 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 ) { LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ) {
struct websocket_client_thread_data *cdata; struct websocket_client_thread_data *cdata;
struct httplib_context *ctx;
struct httplib_connection *conn;
cdata = data; if ( (cdata = data ) == NULL ) return LIBHTTP_THREAD_RETNULL;
if ( cdata == NULL || cdata->conn == NULL || cdata->conn->ctx == 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 ); ctx->workerthreadids = httplib_free( ctx->workerthreadids );
cdata->conn = httplib_free( cdata->conn ); conn = httplib_free( conn );
cdata = httplib_free( cdata ); cdata = httplib_free( cdata );
cdata->conn->ctx->user_data = NULL; ctx->user_data = NULL;
cdata->conn->ctx->num_threads = 0; ctx->num_threads = 0;
cdata->conn->ctx->status = CTX_STATUS_TERMINATED; ctx->status = CTX_STATUS_TERMINATED;
return LIBHTTP_THREAD_RETNULL; return LIBHTTP_THREAD_RETNULL;

View File

@@ -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. * 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; int retval;
char *masked_data; char *masked_data;
uint32_t masking_key; uint32_t masking_key;
if ( conn == NULL || conn->ctx == NULL ) return -1; if ( ctx == NULL || conn == NULL ) return -1;
retval = -1; retval = -1;
masked_data = httplib_malloc( ((dataLen + 7) / 4) * 4 ); 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 ) { 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; return -1;
} }
mask_data( data, dataLen, masking_key, masked_data ); 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 ); masked_data = httplib_free( masked_data );
return retval; return retval;

View File

@@ -20,22 +20,19 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* ============
* Release: 2.0
*/ */
#include "httplib_main.h" #include "httplib_main.h"
/* /*
* 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 * The function httplib_websocket_write() writes data over a websocket
* connection. * 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 */ } /* httplib_websocket_write */

View File

@@ -28,13 +28,13 @@
#include "httplib_main.h" #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 * The function XX_httplib_websocket_write_exec() does the heavy lifting in
* writing data over a websocket connectin to a remote peer. * 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]; unsigned char header[14];
size_t header_len; 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 len1;
uint32_t len2; uint32_t len2;
if ( ctx == NULL ) return -1;
retval = -1; retval = -1;
header_len = 1; header_len = 1;
header[0] = 0x80 + (opcode & 0xF); 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 ); httplib_lock_connection( conn );
retval = httplib_write( conn, header, header_len ); retval = httplib_write( ctx, conn, header, header_len );
if ( data_len > 0 ) retval = httplib_write( conn, data, data_len ); if ( data_len > 0 ) retval = httplib_write( ctx, conn, data, data_len );
httplib_unlock_connection( conn ); httplib_unlock_connection( conn );

View File

@@ -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 ) { 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_connection *conn;
struct httplib_workerTLS tls; struct httplib_workerTLS tls;
union { union {
@@ -79,7 +79,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
ctx = thread_args->ctx; 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 ); tls.thread_idx = (unsigned)httplib_atomic_inc( & XX_httplib_thread_idx_max );
#if defined(_WIN32) #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_size = MAX_REQUEST_SIZE;
conn->buf = (char *)(conn+1); conn->buf = (char *)(conn+1);
conn->ctx = ctx;
conn->thread_index = thread_args->index; conn->thread_index = thread_args->index;
conn->request_info.user_data = ctx->user_data; 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 * 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) * 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 * process HTTPS connection
*/ */
XX_httplib_process_new_connection( conn ); XX_httplib_process_new_connection( ctx, conn );
/* /*
* Free client certificate info * Free client certificate info
@@ -167,9 +166,9 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
#endif #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 );
} }
} }

View File

@@ -25,6 +25,8 @@
#include "httplib_main.h" #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 function httplib_write() writes a number of bytes over a connection.
* The amount of characters written is returned. If an error occurs * The amount of characters written is returned. If an error occurs
* the value 0 is returned. * the value 0 is returned.
@@ -37,7 +39,7 @@
* case a monotonic clock with guaranteed increase would be a better choice. * 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; time_t now;
int64_t n; int64_t n;
@@ -46,7 +48,7 @@ int httplib_write( struct httplib_connection *conn, const void *buffie, size_t l
int64_t allowed; int64_t allowed;
const char *buf; 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; buf = buffie;
len = lennie; 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; allowed = conn->throttle - conn->last_throttle_bytes;
if ( allowed > len ) allowed = len; 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 ) { if ( total == allowed ) {
buf = buf + total; buf = buf + total;
conn->last_throttle_bytes += 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; if ( conn->throttle > len-total ) allowed = len-total;
else allowed = conn->throttle; 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 != allowed ) {
if ( n > 0 ) total += n; 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; return (int)total;

View File

@@ -72,7 +72,7 @@ int main( void ) {
for (a=0; a<idx; a++) { for (a=0; a<idx; a++) {
XX_httplib_snprintf( NULL, NULL, buffer, BUFLEN, "filename%s", XX_httplib_builtin_mime_ext( a ) ); snprintf( buffer, BUFLEN, "filename%s", XX_httplib_builtin_mime_ext( a ) );
p1 = XX_httplib_builtin_mime_type( a ); p1 = XX_httplib_builtin_mime_type( a );
p2 = httplib_get_builtin_mime_type( buffer ); p2 = httplib_get_builtin_mime_type( buffer );