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:
5
Makefile
5
Makefile
@@ -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 \
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 ) {
|
||||||
|
|
||||||
|
@@ -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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 ) {
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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];
|
||||||
|
@@ -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", "" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 */
|
|
@@ -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;
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 */
|
||||||
|
|
||||||
|
@@ -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.
|
||||||
|
@@ -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.
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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> %s</td><td> %s</td></tr>\n",
|
"<td> %s</td><td> %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 */
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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
|
||||||
/*
|
/*
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
|
@@ -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;
|
||||||
|
@@ -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()) ... */
|
||||||
|
@@ -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 ) ) ) ;
|
||||||
|
@@ -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 ) {
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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> %s</td><td> %s</td></tr>\n",
|
"<td> %s</td><td> %s</td></tr>\n",
|
||||||
de->conn->request_info.local_uri,
|
de->conn->request_info.local_uri,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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) ) {
|
||||||
|
|
||||||
|
@@ -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 ) {
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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
|
||||||
|
@@ -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) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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"
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 ) {
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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;
|
||||||
|
@@ -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';
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 );
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user