diff --git a/Makefile b/Makefile index e855484f..3a38e416 100644 --- a/Makefile +++ b/Makefile @@ -1409,6 +1409,7 @@ ${OBJDIR}httplib_pthread_cond_signal${OBJEXT} : ${SRCDIR}httplib_pthread_cond ${OBJDIR}httplib_pthread_cond_timedwait${OBJEXT} : ${SRCDIR}httplib_pthread_cond_timedwait.c \ ${SRCDIR}httplib_main.h \ + ${SRCDIR}httplib_pthread.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_pthread_cond_wait${OBJEXT} : ${SRCDIR}httplib_pthread_cond_wait.c \ diff --git a/include/libhttp.h b/include/libhttp.h index 94801a2b..38958d45 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -45,6 +45,14 @@ #include #include +#include +#include +#include + +#if defined(_WIN32) +#include +#include +#endif /* _WIN32 */ /* * For our Posix emulation functions to open and close directories we need @@ -73,6 +81,15 @@ typedef HANDLE pthread_t; typedef HANDLE pthread_mutex_t; typedef DWORD pthread_key_t; +typedef void pthread_condattr_t; +typedef void pthread_mutexattr_t; + +typedef struct { + CRITICAL_SECTION threadIdSec; + struct httplib_workerTLS * waiting_thread; /* The chain of threads */ +} pthread_cond_t; + +#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */ #else /* _WIN32 */ @@ -793,9 +810,25 @@ enum { LIBHTTP_API int httplib_handle_form_request(struct httplib_connection *conn, struct httplib_form_data_handler *fdh); +#ifndef LIBHTTP_THREAD + +#if defined(_WIN32) +#define LIBHTTP_THREAD unsigned __stdcall +#define LIBHTTP_THREAD_TYPE unsigned +#define LIBHTTP_THREAD_CALLING_CONV __stdcall +#define LIBHTTP_THREAD_RETNULL 0 +#else /* _WIN32 */ +#define LIBHTTP_THREAD void * +#define LIBHTTP_THREAD_TYPE void * +#define LIBHTTP_THREAD_CALLING_CONV +#define LIBHTTP_THREAD_RETNULL NULL +#endif /* _WIN32 */ + +#endif /* LIBHTTP_THREAD */ + /* Convenience function -- create detached thread. Return: 0 on success, non-0 on error. */ -typedef void *(*httplib_thread_func_t)(void *); +typedef LIBHTTP_THREAD_TYPE (LIBHTTP_THREAD_CALLING_CONV *httplib_thread_func_t)(void *); LIBHTTP_API int httplib_start_thread(httplib_thread_func_t f, void *p); @@ -865,8 +898,7 @@ LIBHTTP_API void httplib_cry(const struct httplib_connection *conn, PRINTF_FORMA On success, valid httplib_connection object. On error, NULL. Se error_buffer for details. */ -LIBHTTP_API struct httplib_connection * -httplib_connect_websocket_client(const char *host, +LIBHTTP_API struct httplib_connection *httplib_connect_websocket_client( const char *host, int port, int use_ssl, char *error_buffer, @@ -940,18 +972,6 @@ LIBHTTP_API int httplib_get_response(struct httplib_connection *conn, char *ebuf */ LIBHTTP_API unsigned httplib_check_feature(unsigned feature); -#ifndef LIBHTTP_THREAD - -#if defined(_WIN32) -#define LIBHTTP_THREAD unsigned __stcall -#define LIBHTTP_THREAD_RETNULL 0 -#else /* _WIN32 */ -#define LIBHTTP_THREAD void * -#define LIBHTTP_THREAD_RETNULL NULL -#endif /* _WIN32 */ - -#endif /* LIBHTTP_THREAD */ - typedef void (*httplib_alloc_callback_func)( const char *file, unsigned line, const char *action, int64_t current_bytes, int64_t total_blocks, int64_t total_bytes ); #define httplib_calloc(a, b) XX_httplib_calloc_ex(a, b, __FILE__, __LINE__) @@ -987,7 +1007,7 @@ LIBHTTP_API int httplib_pthread_mutex_lock( pthread_mutex_t *mutex ); LIBHTTP_API int httplib_pthread_mutex_trylock( pthread_mutex_t *mutex ); LIBHTTP_API int httplib_pthread_mutex_unlock( pthread_mutex_t *mutex ); LIBHTTP_API pthread_t httplib_pthread_self( void ); -LIBHTTP_API int httplib_pthread_setspecific( pthread_key_t key, const void *value ); +LIBHTTP_API int httplib_pthread_setspecific( pthread_key_t key, void *value ); LIBHTTP_API struct dirent * httplib_readdir( DIR *dir ); LIBHTTP_API int httplib_remove( const char *path ); LIBHTTP_API void httplib_send_file( struct httplib_connection *conn, const char *path, const char *mime_type, const char *additional_headers ); diff --git a/src/extern_sha1.c b/src/extern_sha1.c index 7597c1d1..f85260ef 100644 --- a/src/extern_sha1.c +++ b/src/extern_sha1.c @@ -25,6 +25,7 @@ * Release: 2.0 */ +#include "libhttp.h" #include "httplib_main.h" /* diff --git a/src/httplib_closedir.c b/src/httplib_closedir.c index fd242168..96b7ed12 100644 --- a/src/httplib_closedir.c +++ b/src/httplib_closedir.c @@ -47,7 +47,7 @@ LIBHTTP_API int httplib_closedir( DIR *dir ) { if ( dir != NULL ) { if ( dir->handle != INVALID_HANDLE_VALUE ) result = ( FindClose( dir->handle ) ) ? 0 : -1; - XX_httplib_free( dir ); + httplib_free( dir ); } else { diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index 4cd65d05..f420e975 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -121,7 +121,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http if ( getsockname( sock, psa, &len ) != 0 ) httplib_cry(conn, "%s: getsockname() failed: %s", __func__, strerror(ERRNO) ); conn->client.is_ssl = (use_ssl) ? 1 : 0; - pthread_mutex_init( &conn->mutex, &XX_httplib_pthread_mutex_attr ); + httplib_pthread_mutex_init( &conn->mutex, &XX_httplib_pthread_mutex_attr ); #ifndef NO_SSL if ( use_ssl ) { diff --git a/src/httplib_initialize_ssl.c b/src/httplib_initialize_ssl.c index 740b465f..e84e03bb 100644 --- a/src/httplib_initialize_ssl.c +++ b/src/httplib_initialize_ssl.c @@ -83,7 +83,7 @@ int XX_httplib_initialize_ssl( struct httplib_context *ctx ) { return 0; } - for (i=0; i= 1900 */ -#ifndef _TIMESPEC_DEFINED -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ -}; -#endif /* _TIMESPEC_DEFINED */ - -#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */ /* Mark required libraries */ #if defined(_MSC_VER) @@ -491,10 +478,11 @@ typedef struct ssl_st SSL; typedef struct ssl_method_st SSL_METHOD; typedef struct ssl_ctx_st SSL_CTX; typedef struct x509_store_ctx_st X509_STORE_CTX; -typedef struct x509_name X509_NAME; +// typedef struct x509_name X509_NAME; typedef struct asn1_integer ASN1_INTEGER; typedef struct evp_md EVP_MD; typedef struct x509 X509; +typedef struct x509_name X509_NAMEX; #endif /* NO_SSL_DL */ #endif /* NO_SSL */ @@ -845,6 +833,7 @@ int XX_httplib_is_valid_port( unsigned long port ); bool XX_httplib_is_websocket_protocol( const struct httplib_connection *conn ); void * XX_httplib_load_dll( struct httplib_context *ctx, const char *dll_name, struct ssl_func *sw ); void XX_httplib_log_access( const struct httplib_connection *conn ); +LIBHTTP_THREAD XX_httplib_master_thread( void *thread_func_param ); int XX_httplib_match_prefix(const char *pattern, size_t pattern_len, const char *str); void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ); int XX_httplib_must_hide_file( struct httplib_connection *conn, const char *path ); @@ -900,11 +889,13 @@ char * XX_httplib_skip( char **buf, const char *delimiters ); char * XX_httplib_skip_quoted( char **buf, const char *delimiters, const char *whitespace, char quotechar ); void XX_httplib_sockaddr_to_string(char *buf, size_t len, const union usa *usa ); pid_t XX_httplib_spawn_process( struct httplib_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ); +int XX_httplib_start_thread_with_id( httplib_thread_func_t func, void *param, pthread_t *threadidptr ); int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct file *filep ); int XX_httplib_substitute_index_file( struct httplib_connection *conn, char *path, size_t path_len, struct file *filep ); const char * XX_httplib_suggest_connection_header( const struct httplib_connection *conn ); 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 ); +LIBHTTP_THREAD XX_httplib_worker_thread( void *thread_func_param ); @@ -924,18 +915,10 @@ void md5_finish( md5_state_t *pms, md5_byte_t digest[16] ); #ifdef _WIN32 -unsigned __stdcall XX_httplib_master_thread( void *thread_func_param ); -int XX_httplib_start_thread_with_id( unsigned(__stdcall *f)(void *), void *p, pthread_t *threadidptr ); -unsigned __stdcall XX_httplib_worker_thread( void *thread_func_param ); - extern struct pthread_mutex_undefined_struct * XX_httplib_pthread_mutex_attr; #else /* _WIN32 */ -void * XX_httplib_master_thread( void *thread_func_param ); -int XX_httplib_start_thread_with_id( httplib_thread_func_t func, void *param, pthread_t *threadidptr ); -void * XX_httplib_worker_thread( void *thread_func_param ); - -extern pthread_mutexattr_t XX_httplib_pthread_mutex_attr; +extern pthread_mutexattr_t XX_httplib_pthread_mutex_attr; #endif /* _WIN32 */ -extern const struct uriprot_tp XX_httplib_abs_uri_protocols[]; +extern const struct uriprot_tp XX_httplib_abs_uri_protocols[]; extern struct httplib_option XX_httplib_config_options[]; diff --git a/src/httplib_master_thread.c b/src/httplib_master_thread.c index 49879aa3..7d3d5ed2 100644 --- a/src/httplib_master_thread.c +++ b/src/httplib_master_thread.c @@ -127,7 +127,7 @@ static void master_thread_run(void *thread_func_param) { pfd[i].events = POLLIN; } - if ( poll( pfd, ctx->num_listening_sockets, 200 ) > 0 ) { + if ( httplib_poll( pfd, ctx->num_listening_sockets, 200 ) > 0 ) { for (i=0; inum_listening_sockets; i++) { diff --git a/src/httplib_mkdir.c b/src/httplib_mkdir.c index 9a9ce0ba..6d7d5ec0 100644 --- a/src/httplib_mkdir.c +++ b/src/httplib_mkdir.c @@ -46,6 +46,8 @@ LIBHTTP_API int httplib_mkdir( const char *path, int mode ) { wchar_t wbuf[PATH_MAX]; + UNUSED_PARAMETER(mode); + XX_httplib_path_to_unicode( path, wbuf, ARRAY_SIZE(wbuf) ); return ( CreateDirectoryW( wbuf, NULL ) ) ? 0 : -1; diff --git a/src/httplib_opendir.c b/src/httplib_opendir.c index e916ced3..c6691e49 100644 --- a/src/httplib_opendir.c +++ b/src/httplib_opendir.c @@ -49,10 +49,10 @@ LIBHTTP_API DIR *httplib_opendir( const char *name ) { dir = NULL; - if ( name == NULL ) SetLastError( ERROR_BAD_ARGUMENTS ); - else if ( (dir = XX_httplib_malloc( sizeof(*dir) )) == NULL ) SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + if ( name == NULL ) SetLastError( ERROR_BAD_ARGUMENTS ); + else if ( (dir = httplib_malloc( sizeof(*dir) )) == NULL ) SetLastError( ERROR_NOT_ENOUGH_MEMORY ); else { - XX_httplib_path_to_unicode( conn, name, wpath, ARRAY_SIZE(wpath) ); + XX_httplib_path_to_unicode( name, wpath, ARRAY_SIZE(wpath) ); attrs = GetFileAttributesW( wpath ); if (attrs != 0xFFFFFFFF && ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) ) { @@ -62,7 +62,7 @@ LIBHTTP_API DIR *httplib_opendir( const char *name ) { dir->result.d_name[0] = '\0'; } else { - XX_httplib_free( dir ); + httplib_free( dir ); dir = NULL; } } diff --git a/src/httplib_path_to_unicode.c b/src/httplib_path_to_unicode.c index 7fc3c42b..4d25160c 100644 --- a/src/httplib_path_to_unicode.c +++ b/src/httplib_path_to_unicode.c @@ -84,8 +84,8 @@ void XX_httplib_path_to_unicode( const char *path, wchar_t *wbuf, size_t wbuf_le DWORD err; int (*fcompare)(const wchar_t *, const wchar_t *) = httplib_wcscasecmp; - XX_httplib_strlcpy(buf, path, sizeof(buf)); - change_slashes_to_backslashes(buf); + httplib_strlcpy( buf, path, sizeof(buf) ); + change_slashes_to_backslashes( buf ); /* * Convert to Unicode and back. If doubly-converted string does not diff --git a/src/httplib_pthread_cond_timedwait.c b/src/httplib_pthread_cond_timedwait.c index 9a79a65a..4c808820 100644 --- a/src/httplib_pthread_cond_timedwait.c +++ b/src/httplib_pthread_cond_timedwait.c @@ -26,6 +26,7 @@ */ #include "httplib_main.h" +#include "httplib_pthread.h" /* * int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex *mutex, const struct timespec *abstime ); @@ -53,7 +54,7 @@ int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, int64_t nswaitrel; DWORD mswaitrel; - tls = pthread_getspecific( XX_httplib_sTlsKey ); + tls = httplib_pthread_getspecific( XX_httplib_sTlsKey ); /* Add this thread to cv's waiting list */ EnterCriticalSection( & cv->threadIdSec ); @@ -81,7 +82,7 @@ int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, else mswaitrel = INFINITE; - pthread_mutex_unlock( mutex ); + httplib_pthread_mutex_unlock( mutex ); ok = ( WaitForSingleObject( tls->pthread_cond_helper_mutex, mswaitrel ) == WAIT_OBJECT_0 ); if ( ! ok ) { @@ -110,7 +111,7 @@ int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, if ( ok ) WaitForSingleObject( tls->pthread_cond_helper_mutex, INFINITE ); } /* This thread has been removed from cv's waiting list */ - pthread_mutex_lock( mutex ); + httplib_pthread_mutex_lock( mutex ); return ok ? 0 : -1; diff --git a/src/httplib_pthread_join.c b/src/httplib_pthread_join.c index 847b06db..b7788aa5 100644 --- a/src/httplib_pthread_join.c +++ b/src/httplib_pthread_join.c @@ -50,14 +50,14 @@ int httplib_pthread_join( pthread_t thread, void **value_ptr ) { UNUSED_PARAMETER(value_ptr); result = -1; - dwevent = WaitForSingleObject( threadid, INFINITE ); + dwevent = WaitForSingleObject( thread, INFINITE ); if ( dwevent == WAIT_FAILED ) { } else if ( dwevent == WAIT_OBJECT_0 ) { - CloseHandle( threadid ); + CloseHandle( thread ); result = 0; } diff --git a/src/httplib_pthread_self.c b/src/httplib_pthread_self.c index 76b964bd..22ce3085 100644 --- a/src/httplib_pthread_self.c +++ b/src/httplib_pthread_self.c @@ -40,7 +40,7 @@ pthread_t httplib_pthread_self( void ) { #if defined(_WIN32) - return GetCurrentThreadId(); + return (pthread_t)GetCurrentThreadId(); #else /* _WIN32 */ diff --git a/src/httplib_pthread_setspecific.c b/src/httplib_pthread_setspecific.c index 73e07ae9..ff2680a8 100644 --- a/src/httplib_pthread_setspecific.c +++ b/src/httplib_pthread_setspecific.c @@ -28,7 +28,7 @@ #include "httplib_main.h" /* - * int httplib_pthread_setspecific( pthread_key_t key, const void *value ); + * int httplib_pthread_setspecific( pthread_key_t key, void *value ); * * The platform independent function httplib_pthread_setspecific() is used to * set a key value for a previously obtained thread specific key. The function @@ -38,7 +38,7 @@ * function call is used. */ -int httplib_pthread_setspecific( pthread_key_t key, const void *value ) { +int httplib_pthread_setspecific( pthread_key_t key, void *value ) { #if defined(_WIN32) diff --git a/src/httplib_set_sock_timeout.c b/src/httplib_set_sock_timeout.c index 77e96639..5868f7b3 100644 --- a/src/httplib_set_sock_timeout.c +++ b/src/httplib_set_sock_timeout.c @@ -54,6 +54,7 @@ int XX_httplib_set_sock_timeout( SOCKET sock, int milliseconds ) { #ifdef _WIN32 DWORD tv = (DWORD)milliseconds; + r0 = 0; #else /* _WIN32 */ diff --git a/src/httplib_ssl.h b/src/httplib_ssl.h index 7b77cc27..34b2c9bf 100644 --- a/src/httplib_ssl.h +++ b/src/httplib_ssl.h @@ -119,9 +119,9 @@ struct ssl_func { #define CRYPTO_cleanup_all_ex_data (*(void (*)(void))XX_httplib_crypto_sw[9].ptr) #define EVP_cleanup (*(void (*)(void))XX_httplib_crypto_sw[10].ptr) #define X509_free (*(void (*)(X509 *))XX_httplib_crypto_sw[11].ptr) -#define X509_get_subject_name (*(X509_NAME * (*)(X509 *))XX_httplib_crypto_sw[12].ptr) -#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))XX_httplib_crypto_sw[13].ptr) -#define X509_NAME_oneline (*(char *(*)(X509_NAME *, char *, int))XX_httplib_crypto_sw[14].ptr) +#define X509_get_subject_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[12].ptr) +#define X509_get_issuer_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[13].ptr) +#define X509_NAME_oneline (*(char *(*)(X509_NAMEX *, char *, int))XX_httplib_crypto_sw[14].ptr) #define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))XX_httplib_crypto_sw[15].ptr) #define i2c_ASN1_INTEGER (*(int (*)(ASN1_INTEGER *, unsigned char **))XX_httplib_crypto_sw[16].ptr) #define EVP_get_digestbyname (*(const EVP_MD *(*)(const char *))XX_httplib_crypto_sw[17].ptr) diff --git a/src/httplib_ssl_get_client_cert_info.c b/src/httplib_ssl_get_client_cert_info.c index 7daf6315..1be6c34c 100644 --- a/src/httplib_ssl_get_client_cert_info.c +++ b/src/httplib_ssl_get_client_cert_info.c @@ -53,8 +53,8 @@ void XX_httplib_ssl_get_client_cert_info( struct httplib_connection *conn ) { int len2; unsigned int ulen; X509 *cert; - X509_NAME *subj; - X509_NAME *iss; + X509_NAMEX *subj; + X509_NAMEX *iss; ASN1_INTEGER *serial; const EVP_MD *digest; diff --git a/src/httplib_start.c b/src/httplib_start.c index 7a1c4282..2b606162 100644 --- a/src/httplib_start.c +++ b/src/httplib_start.c @@ -105,12 +105,12 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks #endif httplib_pthread_setspecific( XX_httplib_sTlsKey, & tls ); - ok = 0 == pthread_mutex_init( & ctx->thread_mutex, &XX_httplib_pthread_mutex_attr ); + ok = 0 == httplib_pthread_mutex_init( & ctx->thread_mutex, &XX_httplib_pthread_mutex_attr ); #if !defined(ALTERNATIVE_QUEUE) ok &= 0 == httplib_pthread_cond_init( & ctx->sq_empty, NULL ); ok &= 0 == httplib_pthread_cond_init( & ctx->sq_full, NULL ); #endif - ok &= 0 == pthread_mutex_init( & ctx->nonce_mutex, & XX_httplib_pthread_mutex_attr ); + ok &= 0 == httplib_pthread_mutex_init( & ctx->nonce_mutex, & XX_httplib_pthread_mutex_attr ); if ( ! ok ) { diff --git a/src/httplib_stat.c b/src/httplib_stat.c index 5726ab2e..4e2e8e13 100644 --- a/src/httplib_stat.c +++ b/src/httplib_stat.c @@ -80,7 +80,7 @@ int XX_httplib_stat( struct httplib_connection *conn, const char *path, struct f return 1; } - XX_httplib_path_to_unicode( conn, path, wbuf, ARRAY_SIZE(wbuf) ); + XX_httplib_path_to_unicode( path, wbuf, ARRAY_SIZE(wbuf) ); if ( GetFileAttributesExW( wbuf, GetFileExInfoStandard, &info ) != 0 ) { diff --git a/src/httplib_worker_thread.c b/src/httplib_worker_thread.c index 22ca32c8..00c9a511 100644 --- a/src/httplib_worker_thread.c +++ b/src/httplib_worker_thread.c @@ -103,7 +103,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { * within the request handler and from elsewhere in the application */ - pthread_mutex_init( & conn->mutex, &XX_httplib_pthread_mutex_attr ); + httplib_pthread_mutex_init( & conn->mutex, &XX_httplib_pthread_mutex_attr ); /* * Call XX_httplib_consume_socket() even when ctx->stop_flag > 0, to let it