mirror of
https://github.com/lammertb/libhttp.git
synced 2025-08-07 16:02:55 +03:00
Memory allocation always debugged
This commit is contained in:
@@ -87,6 +87,7 @@ LibHTTP is often used as HTTP and HTTPS library inside a larger application. A
|
||||
### Memory Allocation Functions
|
||||
|
||||
* [`httplib_free( ptr );`](api/httplib_free.md)
|
||||
* [`httplib_set_alloc_callback_func( log_func );`](api/httplib_set_alloc_callback_func.md)
|
||||
|
||||
### Process Functions
|
||||
|
||||
|
43
doc/api/httplib_set_alloc_callback_func.md
Normal file
43
doc/api/httplib_set_alloc_callback_func.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# LibHTTP API Reference
|
||||
|
||||
### `httplib_set_alloc_callback_func( log_func );`
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
|**`log_func`**|`httplib_alloc_callback_func`|The function called with each memory allocation transaction|
|
||||
|
||||
`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 );`
|
||||
|
||||
### Return Value
|
||||
|
||||
*none*
|
||||
|
||||
### Description
|
||||
|
||||
The function `httplib_set_alloc_callback_func()` hooks an optional callback function to the LibHTTP memory allocation functions. This function can be used to track memory usage of the library and to determine memory leaks. The callback function is called each time when a memory transaction takes place which changes the amount of allocated memory from the heap.
|
||||
|
||||
The callback function may not call directly or indirectly any LibHTTP function as these functions may recursively call internal memory allocation functions causing an infinte loop consuming all memory resources.
|
||||
|
||||
If the parameter NULL is passed as callback function the existing callback is removed.
|
||||
|
||||
The callback function takes six parameters and does not return a value. The parameters which are passed from LibHTTP to the callback function are the following.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
|**`file`**|`const char *`|The name of the source file where the memory allocation function was called|
|
||||
|**`line`**|`unsigned`|The line in the source file where the memory allocation function is located|
|
||||
|**`action`**|`const char *`|A string indicating the source of the callback. Currently this can be either **malloc**, **free** and **realloc**. Please note that a call to `httplib_calloc()` is internally translated to a `httplib_malloc()` call and these requests are reported as **malloc** actions. Furthermore in certain situations `httplib_realloc()` may actually be converted to a plain memory allocation of free action resulting in **malloc** or **free** mentioned as `action` parameter.|
|
||||
|**`current_bytes`**|`int64_t`|The amount of bytes in the current request. A positive number indicates that memory was allocated from the heap, a negative value is returned when memory was given back to the heap. Please note that a **realloc** action can therefore both have a positive and negative `current_bytes` value.|
|
||||
|**`total_blocks`**|The total amount of currently allocated blocks|
|
||||
|**`total_bytes`**|The total amount of bytes currently allocated through the LibHTTP memory allocation functions|
|
||||
|
||||
Please note that the processing of the callback function may take an arbitrary amount of time depending on the code which it has to execute. For that reason the setting of the callback function should not be changed during operation of a server process because this may cause unexpected results when the callback function is changed halfway an ongoing callback process. It should also be noted that the memory allocation function issuing the callback will not return until the callback has been fully processed. Long processing times in the callback function may therefore negatively impact the performance of LibHTTP.
|
||||
|
||||
### See Also
|
||||
|
||||
* [`httplib_calloc();`](httplib_calloc.md)
|
||||
* [`httplib_free();`](httplib_free.md)
|
||||
* [`httplib_malloc();`](httplib_malloc.md)
|
||||
* [`httplib_realloc();`](httplib_realloc.md)
|
@@ -961,6 +961,18 @@ LIBHTTP_API int httplib_get_response(struct httplib_connection *conn, char *ebuf
|
||||
*/
|
||||
LIBHTTP_API unsigned httplib_check_feature(unsigned feature);
|
||||
|
||||
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__)
|
||||
#define httplib_free(a) XX_httplib_free_ex(a, __FILE__, __LINE__)
|
||||
#define httplib_malloc(a) XX_httplib_malloc_ex(a, __FILE__, __LINE__)
|
||||
#define httplib_realloc(a, b) XX_httplib_realloc_ex(a, b, __FILE__, __LINE__)
|
||||
|
||||
LIBHTTP_API void * XX_httplib_calloc_ex( size_t count, size_t size, const char *file, unsigned line );
|
||||
LIBHTTP_API void XX_httplib_free_ex( void *memory, const char *file, unsigned line );
|
||||
LIBHTTP_API void * XX_httplib_malloc_ex( size_t size, const char *file, unsigned line );
|
||||
LIBHTTP_API void * XX_httplib_realloc_ex( void *memory, size_t newsize, const char *file, unsigned line );
|
||||
|
||||
LIBHTTP_API int httplib_atomic_dec( volatile int *addr );
|
||||
LIBHTTP_API int httplib_atomic_inc( volatile int *addr );
|
||||
LIBHTTP_API int httplib_closedir( DIR *dir );
|
||||
@@ -970,6 +982,7 @@ LIBHTTP_API DIR * httplib_opendir( const char *name );
|
||||
LIBHTTP_API int httplib_poll( struct pollfd *pfd, unsigned int nfds, int timeout );
|
||||
LIBHTTP_API struct dirent * httplib_readdir( DIR *dir );
|
||||
LIBHTTP_API int httplib_remove( const char *path );
|
||||
LIBHTTP_API void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func );
|
||||
LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len );
|
||||
LIBHTTP_API char * httplib_strndup( const char *str, size_t len );
|
||||
|
||||
|
@@ -59,7 +59,7 @@ void XX_httplib_addenv( struct cgi_environment *env, const char *fmt, ... ) {
|
||||
if (space <= n) {
|
||||
/* Allocate new buffer */
|
||||
n = env->buflen + CGI_ENVIRONMENT_SIZE;
|
||||
added = (char *)XX_httplib_realloc(env->buf, n);
|
||||
added = httplib_realloc(env->buf, n);
|
||||
if (!added) {
|
||||
/* Out of memory */
|
||||
httplib_cry(env->conn, "%s: Cannot allocate memory for CGI variable [%s]", __func__, fmt);
|
||||
|
@@ -46,7 +46,7 @@ LIBHTTP_API int httplib_base64_encode( const unsigned char *src, int src_len, ch
|
||||
int b;
|
||||
int c;
|
||||
|
||||
if ( src == NULL || src_len <= 0 || dst == NULL || dst_len < 1 ) -1;
|
||||
if ( src == NULL || src_len <= 0 || dst == NULL || dst_len < 1 ) return -1;
|
||||
|
||||
j = 0;
|
||||
|
||||
|
@@ -59,9 +59,6 @@ unsigned httplib_check_feature( unsigned feature ) {
|
||||
|
||||
/* Set some extra bits not defined in the API documentation.
|
||||
* These bits may change without further notice. */
|
||||
#if defined(MEMORY_DEBUGGING)
|
||||
| 0x0100u
|
||||
#endif
|
||||
#if defined(USE_TIMERS)
|
||||
| 0x0200u
|
||||
#endif
|
||||
|
@@ -45,9 +45,9 @@ void XX_httplib_close_all_listening_sockets( struct httplib_context *ctx ) {
|
||||
closesocket(ctx->listening_sockets[i].sock);
|
||||
ctx->listening_sockets[i].sock = INVALID_SOCKET;
|
||||
}
|
||||
XX_httplib_free(ctx->listening_sockets);
|
||||
httplib_free( ctx->listening_sockets );
|
||||
httplib_free( ctx->listening_socket_fds );
|
||||
ctx->listening_sockets = NULL;
|
||||
XX_httplib_free(ctx->listening_socket_fds);
|
||||
ctx->listening_socket_fds = NULL;
|
||||
|
||||
} /* XX_close_all_listening_sockets */
|
||||
|
@@ -106,10 +106,10 @@ void httplib_close_connection( struct httplib_connection *conn ) {
|
||||
if (client_ctx->workerthreadids[i] != 0) XX_httplib_join_thread(client_ctx->workerthreadids[i]);
|
||||
}
|
||||
|
||||
XX_httplib_free(client_ctx->workerthreadids);
|
||||
XX_httplib_free(client_ctx);
|
||||
httplib_free( client_ctx->workerthreadids );
|
||||
httplib_free( client_ctx );
|
||||
pthread_mutex_destroy( & conn->mutex );
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
}
|
||||
|
||||
} /* httplib_close_connection */
|
||||
|
@@ -88,7 +88,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
||||
|
||||
if (!XX_httplib_connect_socket(&fake_ctx, client_options->host, client_options->port, use_ssl, ebuf, ebuf_len, &sock, &sa)) {
|
||||
;
|
||||
} else if ((conn = (struct httplib_connection *) XX_httplib_calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE)) == NULL) {
|
||||
} else if ((conn = httplib_calloc( 1, sizeof(*conn) + MAX_REQUEST_SIZE )) == NULL ) {
|
||||
XX_httplib_snprintf(NULL, NULL, ebuf, ebuf_len, "calloc(): %s", strerror(ERRNO));
|
||||
closesocket(sock);
|
||||
#ifndef NO_SSL
|
||||
@@ -96,7 +96,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
||||
|
||||
XX_httplib_snprintf(NULL, NULL, ebuf, ebuf_len, "SSL_CTX_new error");
|
||||
closesocket(sock);
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
conn = NULL;
|
||||
#endif /* NO_SSL */
|
||||
|
||||
@@ -138,7 +138,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
||||
XX_httplib_snprintf(NULL, NULL, ebuf, ebuf_len, "Can not use SSL client certificate");
|
||||
SSL_CTX_free(conn->client_ssl_ctx);
|
||||
closesocket(sock);
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
conn = NULL;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http
|
||||
XX_httplib_snprintf(NULL, NULL, ebuf, ebuf_len, "SSL connection error");
|
||||
SSL_CTX_free(conn->client_ssl_ctx);
|
||||
closesocket(sock);
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
conn = NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in
|
||||
sa->sin6.sin6_port = htons((uint16_t)port);
|
||||
ip_ver = 6;
|
||||
}
|
||||
XX_httplib_free(h);
|
||||
httplib_free( h );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ struct httplib_connection *httplib_connect_websocket_client(const char *host,
|
||||
XX_httplib_snprintf(conn, NULL, error_buffer, error_buffer_size, "Unexpected server reply");
|
||||
}
|
||||
if (conn != NULL) {
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
conn = NULL;
|
||||
}
|
||||
return conn;
|
||||
@@ -94,14 +94,15 @@ struct httplib_connection *httplib_connect_websocket_client(const char *host,
|
||||
|
||||
/* For client connections, httplib_context is fake. Since we need to set a
|
||||
* callback function, we need to create a copy and modify it. */
|
||||
newctx = (struct httplib_context *)XX_httplib_malloc(sizeof(struct httplib_context));
|
||||
newctx = httplib_malloc(sizeof(struct httplib_context));
|
||||
memcpy(newctx, conn->ctx, sizeof(struct httplib_context));
|
||||
|
||||
newctx->user_data = user_data;
|
||||
newctx->context_type = 2; /* client context type */
|
||||
newctx->cfg_worker_threads = 1; /* one worker thread will be created */
|
||||
newctx->workerthreadids = (pthread_t *)XX_httplib_calloc(newctx->cfg_worker_threads, sizeof(pthread_t));
|
||||
newctx->workerthreadids = httplib_calloc(newctx->cfg_worker_threads, sizeof(pthread_t));
|
||||
conn->ctx = newctx;
|
||||
thread_data = (struct websocket_client_thread_data *) XX_httplib_calloc(sizeof(struct websocket_client_thread_data), 1);
|
||||
thread_data = httplib_calloc(sizeof(struct websocket_client_thread_data), 1);
|
||||
thread_data->conn = conn;
|
||||
thread_data->data_handler = data_func;
|
||||
thread_data->close_handler = close_func;
|
||||
@@ -112,10 +113,11 @@ struct httplib_connection *httplib_connect_websocket_client(const char *host,
|
||||
* called on the client connection */
|
||||
if (XX_httplib_start_thread_with_id( XX_httplib_websocket_client_thread, (void *)thread_data, newctx->workerthreadids) != 0) {
|
||||
|
||||
XX_httplib_free((void *)thread_data);
|
||||
XX_httplib_free((void *)newctx->workerthreadids);
|
||||
XX_httplib_free((void *)newctx);
|
||||
XX_httplib_free((void *)conn);
|
||||
httplib_free( thread_data );
|
||||
httplib_free( newctx->workerthreadids );
|
||||
httplib_free( newctx );
|
||||
httplib_free( conn );
|
||||
|
||||
conn = NULL;
|
||||
}
|
||||
#else
|
||||
|
@@ -75,7 +75,7 @@ void XX_httplib_free_context( struct httplib_context *ctx ) {
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(suppress : 6001)
|
||||
#endif
|
||||
XX_httplib_free( ctx->config[i] );
|
||||
httplib_free( ctx->config[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ void XX_httplib_free_context( struct httplib_context *ctx ) {
|
||||
while (ctx->handlers) {
|
||||
tmp_rh = ctx->handlers;
|
||||
ctx->handlers = tmp_rh->next;
|
||||
XX_httplib_free(tmp_rh->uri);
|
||||
XX_httplib_free(tmp_rh);
|
||||
httplib_free( tmp_rh->uri );
|
||||
httplib_free( tmp_rh );
|
||||
}
|
||||
|
||||
#ifndef NO_SSL
|
||||
@@ -93,7 +93,7 @@ void XX_httplib_free_context( struct httplib_context *ctx ) {
|
||||
#endif /* !NO_SSL */
|
||||
|
||||
/* Deallocate worker thread ID array */
|
||||
if (ctx->workerthreadids != NULL) XX_httplib_free(ctx->workerthreadids);
|
||||
if (ctx->workerthreadids != NULL) httplib_free( ctx->workerthreadids );
|
||||
|
||||
/* Deallocate the tls variable */
|
||||
if (httplib_atomic_dec(&XX_httplib_sTlsInit) == 0) {
|
||||
@@ -108,9 +108,9 @@ void XX_httplib_free_context( struct httplib_context *ctx ) {
|
||||
}
|
||||
|
||||
/* deallocate system name string */
|
||||
XX_httplib_free(ctx->systemName);
|
||||
httplib_free( ctx->systemName );
|
||||
|
||||
/* Deallocate context itself */
|
||||
XX_httplib_free(ctx);
|
||||
httplib_free( ctx );
|
||||
|
||||
} /* XX_httplib_free_context */
|
||||
|
@@ -172,7 +172,8 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char
|
||||
* Do not send anything back to client, until we buffer in all
|
||||
* HTTP headers. */
|
||||
data_len = 0;
|
||||
buf = (char *)XX_httplib_malloc(buflen);
|
||||
buf = httplib_malloc( buflen );
|
||||
|
||||
if (buf == NULL) {
|
||||
XX_httplib_send_http_error(conn, 500, "Error: Not enough memory for CGI buffer (%u bytes)", (unsigned int)buflen);
|
||||
httplib_cry(conn, "Error: CGI program \"%s\": Not enough memory for buffer (%u " "bytes)", prog, (unsigned int)buflen);
|
||||
@@ -238,8 +239,8 @@ void XX_httplib_handle_cgi_request( struct httplib_connection *conn, const char
|
||||
XX_httplib_send_file_data(conn, &fout, 0, INT64_MAX);
|
||||
|
||||
done:
|
||||
XX_httplib_free(blk.var);
|
||||
XX_httplib_free(blk.buf);
|
||||
httplib_free( blk.var );
|
||||
httplib_free( blk.buf );
|
||||
|
||||
if (pid != (pid_t)-1) {
|
||||
httplib_kill( pid, SIGKILL );
|
||||
@@ -258,7 +259,7 @@ done:
|
||||
if ( out != NULL ) fclose( out ); else if ( fdout[0] != -1 ) close( fdout[0] );
|
||||
if ( err != NULL ) fclose( err ); else if ( fderr[0] != -1 ) close( fderr[0] );
|
||||
|
||||
if ( buf != NULL ) XX_httplib_free( buf );
|
||||
if ( buf != NULL ) httplib_free( buf );
|
||||
|
||||
} /* XX_httplib_handle_cgi_request */
|
||||
|
||||
|
@@ -87,9 +87,9 @@ void XX_httplib_handle_directory_request( struct httplib_connection *conn, const
|
||||
XX_httplib_compare_dir_entries);
|
||||
for (i = 0; i < data.num_entries; i++) {
|
||||
XX_httplib_print_dir_entry(&data.entries[i]);
|
||||
XX_httplib_free(data.entries[i].file_name);
|
||||
httplib_free( data.entries[i].file_name );
|
||||
}
|
||||
XX_httplib_free(data.entries);
|
||||
httplib_free( data.entries );
|
||||
}
|
||||
|
||||
conn->num_bytes_sent += httplib_printf(conn, "%s", "</table></body></html>");
|
||||
|
@@ -87,7 +87,7 @@ static int url_encoded_field_get(const struct httplib_connection *conn,
|
||||
|
||||
char key_dec[1024];
|
||||
|
||||
char *value_dec = XX_httplib_malloc(value_len + 1);
|
||||
char *value_dec = httplib_malloc( value_len+1 );
|
||||
int value_dec_len, ret;
|
||||
|
||||
if (!value_dec) {
|
||||
@@ -101,7 +101,7 @@ static int url_encoded_field_get(const struct httplib_connection *conn,
|
||||
value_dec_len = httplib_url_decode(value, (int)value_len, value_dec, (int)value_len + 1, 1);
|
||||
|
||||
ret = fdh->field_get(key_dec, value_dec, (size_t)value_dec_len, fdh->user_data);
|
||||
XX_httplib_free(value_dec);
|
||||
httplib_free( value_dec );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ int XX_httplib_initialize_ssl( struct httplib_context *ctx ) {
|
||||
i = CRYPTO_num_locks();
|
||||
if (i < 0) i = 0;
|
||||
size = sizeof(pthread_mutex_t) * ((size_t)(i));
|
||||
if ((XX_httplib_ssl_mutexes = (pthread_mutex_t *)XX_httplib_malloc(size)) == NULL) {
|
||||
if ((XX_httplib_ssl_mutexes = httplib_malloc( size )) == NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s: cannot allocate mutexes: %s", __func__, XX_httplib_ssl_error());
|
||||
return 0;
|
||||
}
|
||||
|
@@ -28,114 +28,133 @@
|
||||
#include "httplib_main.h"
|
||||
#include "httplib_memory.h"
|
||||
|
||||
#if defined(MEMORY_DEBUGGING)
|
||||
static int64_t httplib_memory_blocks_used = 0;
|
||||
static int64_t httplib_memory_bytes_used = 0;
|
||||
|
||||
unsigned long httplib_memory_debug_blockCount = 0;
|
||||
unsigned long httplib_memory_debug_totalMemUsed = 0;
|
||||
static httplib_alloc_callback_func alloc_log_func = NULL;
|
||||
|
||||
/*
|
||||
* void *XX_httplib_malloc_ex( size_t size, const char *file, unsigned line );
|
||||
*
|
||||
* The function XX_httplib_malloc_ext() is a hidden function which is
|
||||
* substituted for XX_httlib_malloc() with a macro when memory debugging is
|
||||
* enabled. The function allocates not only memory, but also updates counters
|
||||
* with the total amount of memory allocated. An optional hook function can be
|
||||
* called to process information about the memory allocation in the calling
|
||||
* program.
|
||||
*
|
||||
* The first part of the allocated memory is used to store the size to be used
|
||||
* later for statistical reasons. The returned pointer is further in the block.
|
||||
* The function XX_httplib_malloc_ext() is therefore not compatible with the
|
||||
* system free() call to release the memory.
|
||||
*
|
||||
* The function returns a pointer to the allocated block, or NULL if an error
|
||||
* occured.
|
||||
*/
|
||||
|
||||
void *XX_httplib_malloc_ex( size_t size, const char *file, unsigned line ) {
|
||||
LIBHTTP_API void *XX_httplib_malloc_ex( size_t size, const char *file, unsigned line ) {
|
||||
|
||||
void *data = malloc(size + sizeof(size_t));
|
||||
void *memory = 0;
|
||||
char mallocStr[256];
|
||||
size_t *data;
|
||||
|
||||
if (data) {
|
||||
*(size_t *)data = size;
|
||||
httplib_memory_debug_totalMemUsed += size;
|
||||
httplib_memory_debug_blockCount++;
|
||||
memory = (void *)(((char *)data) + sizeof(size_t));
|
||||
}
|
||||
data = malloc( size + sizeof(size_t) );
|
||||
if ( data == NULL ) return NULL;
|
||||
|
||||
return memory;
|
||||
httplib_memory_bytes_used += size;
|
||||
httplib_memory_blocks_used++;
|
||||
|
||||
*data = size;
|
||||
|
||||
if ( alloc_log_func != NULL ) alloc_log_func( file, line, "malloc", size, httplib_memory_blocks_used, httplib_memory_bytes_used );
|
||||
|
||||
return (data+1);
|
||||
|
||||
} /* XX_httplib_malloc_ex */
|
||||
|
||||
|
||||
void *XX_httplib_calloc_ex( size_t count, size_t size, const char *file, unsigned line ) {
|
||||
LIBHTTP_API void *XX_httplib_calloc_ex( size_t count, size_t size, const char *file, unsigned line ) {
|
||||
|
||||
void *data = XX_httplib_malloc_ex(size * count, file, line);
|
||||
if ( data != NULL ) memset( data, 0, size * count );
|
||||
void *data;
|
||||
|
||||
data = XX_httplib_malloc_ex( size*count, file, line );
|
||||
if ( data == NULL ) return NULL;
|
||||
|
||||
memset( data, 0x00, size*count );
|
||||
|
||||
return data;
|
||||
|
||||
} /* XX_httplib_calloc_ex */
|
||||
|
||||
|
||||
void XX_httplib_free_ex( void *memory, const char *file, unsigned line ) {
|
||||
LIBHTTP_API void XX_httplib_free_ex( void *memory, const char *file, unsigned line ) {
|
||||
|
||||
char mallocStr[256];
|
||||
void *data = (void *)(((char *)memory) - sizeof(size_t));
|
||||
size_t size;
|
||||
size_t *data;
|
||||
|
||||
if (memory) {
|
||||
size = *(size_t *)data;
|
||||
httplib_memory_debug_totalMemUsed -= size;
|
||||
httplib_memory_debug_blockCount--;
|
||||
if ( memory == NULL ) return;
|
||||
|
||||
data = ((size_t *)memory) - 1;
|
||||
|
||||
httplib_memory_bytes_used -= *data;
|
||||
httplib_memory_blocks_used--;
|
||||
|
||||
if ( alloc_log_func != NULL ) alloc_log_func( file, line, "free", - ((int64_t)*data), httplib_memory_blocks_used, httplib_memory_bytes_used );
|
||||
|
||||
free( data );
|
||||
}
|
||||
|
||||
} /* XX_httplib_free_ex */
|
||||
|
||||
|
||||
void *XX_httplib_realloc_ex( void *memory, size_t newsize, const char *file, unsigned line ) {
|
||||
LIBHTTP_API void *XX_httplib_realloc_ex( void *memory, size_t newsize, const char *file, unsigned line ) {
|
||||
|
||||
char mallocStr[256];
|
||||
void *data;
|
||||
void *_realloc;
|
||||
size_t *olddata;
|
||||
size_t *newdata;
|
||||
size_t oldsize;
|
||||
int64_t diff;
|
||||
|
||||
if (newsize) {
|
||||
if (memory) {
|
||||
data = (void *)(((char *)memory) - sizeof(size_t));
|
||||
oldsize = *(size_t *)data;
|
||||
_realloc = realloc(data, newsize + sizeof(size_t));
|
||||
if (_realloc) {
|
||||
data = _realloc;
|
||||
httplib_memory_debug_totalMemUsed -= oldsize;
|
||||
httplib_memory_debug_totalMemUsed += newsize;
|
||||
*(size_t *)data = newsize;
|
||||
data = (void *)(((char *)data) + sizeof(size_t));
|
||||
} else {
|
||||
return _realloc;
|
||||
}
|
||||
} else {
|
||||
data = XX_httplib_malloc_ex(newsize, file, line);
|
||||
}
|
||||
} else {
|
||||
data = 0;
|
||||
XX_httplib_free_ex(memory, file, line);
|
||||
if ( newsize == 0 ) {
|
||||
|
||||
if ( memory != NULL ) XX_httplib_free_ex( memory, file, line );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
if ( memory == NULL ) return XX_httplib_malloc_ex( newsize, file, line );
|
||||
|
||||
olddata = ((size_t *)memory) - 1;
|
||||
oldsize = *olddata;
|
||||
newdata = realloc( olddata, newsize + sizeof(size_t) );
|
||||
if ( newdata == NULL ) return NULL;
|
||||
|
||||
httplib_memory_bytes_used -= oldsize;
|
||||
httplib_memory_bytes_used += newsize;
|
||||
|
||||
*newdata = newsize;
|
||||
diff = ((int64_t)newsize) - ((int64_t)oldsize);
|
||||
|
||||
if ( alloc_log_func != NULL ) alloc_log_func( file, line, "realloc", diff, httplib_memory_blocks_used, httplib_memory_bytes_used );
|
||||
|
||||
return (newdata+1);
|
||||
|
||||
} /* XX_httplib_realloc_ex */
|
||||
|
||||
|
||||
#else /* MEMORY_DEBUGGING */
|
||||
|
||||
void *XX_httplib_malloc( size_t a ) {
|
||||
/*
|
||||
* void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func );
|
||||
*
|
||||
* The function httplib_set_alloc_callback_func() sets a callback handler which
|
||||
* is called each time memory is allocated from or returned to the heap. In
|
||||
* that way the main application can keep track of memory usage and it will be
|
||||
* easier to find memory leaks.
|
||||
*
|
||||
* The callback function may not call any LibHTTP library function as these
|
||||
* functions may recursively call internal memory allocation functions causing
|
||||
* an infinite loop consuming all available memory.
|
||||
*
|
||||
* If the parameter NULL is passed as callback function the existing callback
|
||||
* is removed.
|
||||
*/
|
||||
|
||||
return malloc(a);
|
||||
LIBHTTP_API void httplib_set_alloc_callback_func( httplib_alloc_callback_func log_func ) {
|
||||
|
||||
} /* XX_httplib_malloc */
|
||||
alloc_log_func = log_func;
|
||||
|
||||
void *XX_httplib_calloc( size_t a, size_t b ) {
|
||||
|
||||
return calloc(a, b);
|
||||
|
||||
} /* XX_httplib_calloc */
|
||||
|
||||
void * XX_httplib_realloc(void *a, size_t b) {
|
||||
|
||||
return realloc(a, b);
|
||||
|
||||
} /* XX_httplib_realloc */
|
||||
|
||||
void XX_httplib_free( void *a ) {
|
||||
|
||||
free(a);
|
||||
|
||||
} /* XX_httplib_free */
|
||||
|
||||
#endif /* MEMORY_DEBUGGING */
|
||||
} /* httplib_set_alloc_callback_func */
|
||||
|
@@ -19,27 +19,4 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if defined(MEMORY_DEBUGGING)
|
||||
|
||||
void * XX_httplib_calloc_ex( size_t count, size_t size, const char *file, unsigned line );
|
||||
void XX_httplib_free_ex( void *memory, const char *file, unsigned line );
|
||||
void * XX_httplib_malloc_ex( size_t size, const char *file, unsigned line );
|
||||
void * XX_httplib_realloc_ex( void *memory, size_t newsize, const char *file, unsigned line );
|
||||
#define XX_httplib_calloc(a, b) XX_httplib_calloc_ex(a, b, __FILE__, __LINE__)
|
||||
#define XX_httplib_free(a) XX_httplib_free_ex(a, __FILE__, __LINE__)
|
||||
#define XX_httplib_malloc(a) XX_httplib_malloc_ex(a, __FILE__, __LINE__)
|
||||
#define XX_httplib_realloc(a, b) XX_httplib_realloc_ex(a, b, __FILE__, __LINE__)
|
||||
|
||||
#else /* MEMORY_DEBUGGING */
|
||||
|
||||
void * XX_httplib_calloc( size_t a, size_t b );
|
||||
void XX_httplib_free( void *a );
|
||||
void * XX_httplib_malloc( size_t a );
|
||||
void * XX_httplib_realloc( void *a, size_t b );
|
||||
|
||||
#endif /* MEMORY_DEBUGGING */
|
||||
|
||||
void * XX_httplib_realloc2( void *ptr, size_t size );
|
||||
|
@@ -55,10 +55,10 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const
|
||||
env->conn = conn;
|
||||
env->buflen = CGI_ENVIRONMENT_SIZE;
|
||||
env->bufused = 0;
|
||||
env->buf = (char *)XX_httplib_malloc(env->buflen);
|
||||
env->buf = httplib_malloc( env->buflen );
|
||||
env->varlen = MAX_CGI_ENVIR_VARS;
|
||||
env->varused = 0;
|
||||
env->var = (char **)XX_httplib_malloc(env->buflen * sizeof(char *));
|
||||
env->var = httplib_malloc( env->buflen * sizeof(char *) );
|
||||
|
||||
XX_httplib_addenv( env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN] );
|
||||
XX_httplib_addenv( env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT] );
|
||||
|
@@ -38,9 +38,7 @@
|
||||
|
||||
void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
|
||||
|
||||
if ( conn == NULL || conn->ctx == NULL ) return;
|
||||
|
||||
struct httplib_request_info *ri = &conn->request_info;
|
||||
struct httplib_request_info *ri;
|
||||
int keep_alive_enabled;
|
||||
int keep_alive;
|
||||
int discard_len;
|
||||
@@ -49,6 +47,9 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
|
||||
int reqerr;
|
||||
int uri_type;
|
||||
|
||||
if ( conn == NULL || conn->ctx == NULL ) return;
|
||||
|
||||
ri = & conn->request_info;
|
||||
keep_alive_enabled = ! strcmp( conn->ctx->config[ENABLE_KEEP_ALIVE], "yes" );
|
||||
|
||||
/* Important: on new connection, reset the receiving buffer. Credit
|
||||
@@ -113,7 +114,7 @@ void XX_httplib_process_new_connection( struct httplib_connection *conn ) {
|
||||
} else conn->must_close = 1;
|
||||
|
||||
if (ri->remote_user != NULL) {
|
||||
XX_httplib_free((void *)ri->remote_user);
|
||||
httplib_free( (void *) ri->remote_user );
|
||||
/* Important! When having connections with and without auth
|
||||
* would cause double free and then crash */
|
||||
ri->remote_user = NULL;
|
||||
|
@@ -104,7 +104,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
|
||||
/* Allocate space to hold websocket payload */
|
||||
data = mem;
|
||||
if (data_len > sizeof(mem)) {
|
||||
data = (char *)XX_httplib_malloc(data_len);
|
||||
data = httplib_malloc( data_len );
|
||||
if (data == NULL) {
|
||||
/* Allocation failed, exit the loop and then close the
|
||||
* connection */
|
||||
@@ -167,7 +167,7 @@ void XX_httplib_read_websocket( struct httplib_connection *conn, httplib_websock
|
||||
exit_by_callback = 1;
|
||||
}
|
||||
|
||||
if (data != mem) XX_httplib_free(data);
|
||||
if ( data != mem ) httplib_free( data );
|
||||
|
||||
if (exit_by_callback || ((mop & 0xf) == WEBSOCKET_OPCODE_CONNECTION_CLOSE)) {
|
||||
/* Opcode == 8, connection close */
|
||||
|
@@ -31,8 +31,8 @@
|
||||
/* Behaves like realloc(), but frees original pointer on failure */
|
||||
void *XX_httplib_realloc2( void *ptr, size_t size ) {
|
||||
|
||||
void *new_ptr = XX_httplib_realloc(ptr, size);
|
||||
if (new_ptr == NULL) XX_httplib_free(ptr);
|
||||
void *new_ptr = httplib_realloc( ptr, size );
|
||||
if (new_ptr == NULL) httplib_free( ptr );
|
||||
|
||||
return new_ptr;
|
||||
|
||||
|
@@ -95,8 +95,8 @@ void XX_httplib_set_handler_type( struct httplib_context *ctx, const char *uri,
|
||||
} else {
|
||||
/* remove existing handler */
|
||||
*lastref = tmp_rh->next;
|
||||
XX_httplib_free(tmp_rh->uri);
|
||||
XX_httplib_free(tmp_rh);
|
||||
httplib_free( tmp_rh->uri );
|
||||
httplib_free( tmp_rh );
|
||||
}
|
||||
httplib_unlock_context(ctx);
|
||||
return;
|
||||
@@ -112,8 +112,10 @@ void XX_httplib_set_handler_type( struct httplib_context *ctx, const char *uri,
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_rh = (struct httplib_handler_info *)XX_httplib_calloc(sizeof(struct httplib_handler_info), 1);
|
||||
tmp_rh = httplib_calloc( sizeof(struct httplib_handler_info), 1 );
|
||||
|
||||
if (tmp_rh == NULL) {
|
||||
|
||||
httplib_unlock_context(ctx);
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s", "Cannot create new request handler struct, OOM");
|
||||
return;
|
||||
@@ -121,7 +123,7 @@ void XX_httplib_set_handler_type( struct httplib_context *ctx, const char *uri,
|
||||
tmp_rh->uri = XX_httplib_strdup(uri);
|
||||
if (!tmp_rh->uri) {
|
||||
httplib_unlock_context(ctx);
|
||||
XX_httplib_free(tmp_rh);
|
||||
httplib_free( tmp_rh );
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s", "Cannot create new request handler struct, OOM");
|
||||
return;
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) {
|
||||
so.lsa.sin.sin_port = usa.sin.sin_port;
|
||||
}
|
||||
|
||||
if ((ptr = XX_httplib_realloc(ctx->listening_sockets, (ctx->num_listening_sockets + 1) * sizeof(ctx->listening_sockets[0]))) == NULL) {
|
||||
if ((ptr = httplib_realloc( ctx->listening_sockets, (ctx->num_listening_sockets + 1) * sizeof(ctx->listening_sockets[0]) )) == NULL) {
|
||||
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s", "Out of memory");
|
||||
closesocket(so.sock);
|
||||
@@ -198,7 +198,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pfd = XX_httplib_realloc(
|
||||
if ((pfd = httplib_realloc(
|
||||
ctx->listening_socket_fds,
|
||||
(ctx->num_listening_sockets + 1)
|
||||
* sizeof(ctx->listening_socket_fds[0]))) == NULL) {
|
||||
@@ -206,7 +206,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s", "Out of memory");
|
||||
closesocket(so.sock);
|
||||
so.sock = INVALID_SOCKET;
|
||||
XX_httplib_free(ptr);
|
||||
httplib_free( ptr );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -87,8 +87,7 @@ void XX_httplib_ssl_get_client_cert_info( struct httplib_connection *conn ) {
|
||||
ASN1_digest((int (*)())i2d_X509, digest, (char *)cert, buf, &ulen);
|
||||
if (!hexdump2string( buf, (int)ulen, str_finger, (int)sizeof(str_finger))) *str_finger = 0;
|
||||
|
||||
conn->request_info.client_cert =
|
||||
(struct client_cert *)XX_httplib_malloc(sizeof(struct client_cert));
|
||||
conn->request_info.client_cert = httplib_malloc( sizeof(struct client_cert) );
|
||||
if (conn->request_info.client_cert) {
|
||||
conn->request_info.client_cert->subject = XX_httplib_strdup( str_subject );
|
||||
conn->request_info.client_cert->issuer = XX_httplib_strdup( str_issuer );
|
||||
|
@@ -64,7 +64,7 @@ unsigned long XX_httplib_ssl_id_callback( void ) {
|
||||
if (tls == NULL) {
|
||||
/* SSL called from an unknown thread: Create some thread index.
|
||||
*/
|
||||
tls = (struct httplib_workerTLS *)XX_httplib_malloc(sizeof(struct httplib_workerTLS));
|
||||
tls = httplib_malloc( sizeof(struct httplib_workerTLS) );
|
||||
tls->is_master = -2; /* -2 means "3rd party thread" */
|
||||
tls->thread_idx = (unsigned)httplib_atomic_inc(&XX_httplib_thread_idx_max);
|
||||
pthread_setspecific(XX_httplib_sTlsKey, tls);
|
||||
|
@@ -59,7 +59,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* Allocate context and initialize reasonable general case defaults. */
|
||||
if ((ctx = (struct httplib_context *)XX_httplib_calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
||||
if ((ctx = httplib_calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
||||
|
||||
/* Random number generator will initialize at the first call */
|
||||
ctx->auth_nonce_mask = (uint64_t)XX_httplib_get_random() ^ (uint64_t)(ptrdiff_t)(options);
|
||||
@@ -80,7 +80,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
* occur in practice. */
|
||||
httplib_atomic_dec(&XX_httplib_sTlsInit);
|
||||
httplib_cry( XX_httplib_fc(ctx), "Cannot initialize thread local storage");
|
||||
XX_httplib_free(ctx);
|
||||
httplib_free( ctx );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
@@ -106,7 +106,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
/* Fatal error - abort start. However, this situation should never
|
||||
* occur in practice. */
|
||||
httplib_cry( XX_httplib_fc(ctx), "Cannot initialize thread synchronization objects");
|
||||
XX_httplib_free(ctx);
|
||||
httplib_free( ctx );
|
||||
pthread_setspecific(XX_httplib_sTlsKey, NULL);
|
||||
return NULL;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
}
|
||||
if (ctx->config[idx] != NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "warning: %s: duplicate option", name);
|
||||
XX_httplib_free(ctx->config[idx]);
|
||||
httplib_free( ctx->config[idx] );
|
||||
}
|
||||
ctx->config[idx] = XX_httplib_strdup(value);
|
||||
}
|
||||
@@ -190,8 +190,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
|
||||
if (workerthreadcount > 0) {
|
||||
ctx->cfg_worker_threads = ((unsigned int)(workerthreadcount));
|
||||
ctx->workerthreadids =
|
||||
(pthread_t *)XX_httplib_calloc(ctx->cfg_worker_threads, sizeof(pthread_t));
|
||||
ctx->workerthreadids = httplib_calloc( ctx->cfg_worker_threads, sizeof(pthread_t) );
|
||||
if (ctx->workerthreadids == NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "Not enough memory for worker thread ID array");
|
||||
XX_httplib_free_context(ctx);
|
||||
@@ -200,8 +199,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
}
|
||||
|
||||
#if defined(ALTERNATIVE_QUEUE)
|
||||
ctx->client_wait_events = XX_httplib_calloc(sizeof(ctx->client_wait_events[0]),
|
||||
ctx->cfg_worker_threads);
|
||||
ctx->client_wait_events = httplib_calloc( sizeof(ctx->client_wait_events[0]), ctx->cfg_worker_threads );
|
||||
if (ctx->client_wait_events == NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "Not enough memory for worker event array");
|
||||
XX_httplib_free(ctx->workerthreadids);
|
||||
@@ -210,8 +208,7 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->client_socks =
|
||||
XX_httplib_calloc(sizeof(ctx->client_socks[0]), ctx->cfg_worker_threads);
|
||||
ctx->client_socks = httplib_calloc( sizeof(ctx->client_socks[0]), ctx->cfg_worker_threads );
|
||||
if (ctx->client_wait_events == NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "Not enough memory for worker socket array");
|
||||
XX_httplib_free(ctx->client_socks);
|
||||
@@ -252,22 +249,16 @@ struct httplib_context *httplib_start( const struct httplib_callbacks *callbacks
|
||||
|
||||
/* Start worker threads */
|
||||
for (i = 0; i < ctx->cfg_worker_threads; i++) {
|
||||
struct worker_thread_args *wta =
|
||||
XX_httplib_malloc(sizeof(struct worker_thread_args));
|
||||
struct worker_thread_args *wta = httplib_malloc( sizeof(struct worker_thread_args) );
|
||||
if (wta) {
|
||||
wta->ctx = ctx;
|
||||
wta->index = (int)i;
|
||||
}
|
||||
|
||||
if ((wta == NULL)
|
||||
|| (XX_httplib_start_thread_with_id(XX_httplib_worker_thread,
|
||||
wta,
|
||||
&ctx->workerthreadids[i]) != 0)) {
|
||||
if ((wta == NULL) || (XX_httplib_start_thread_with_id(XX_httplib_worker_thread, wta, &ctx->workerthreadids[i]) != 0)) {
|
||||
|
||||
/* thread was not created */
|
||||
if (wta != NULL) {
|
||||
XX_httplib_free(wta);
|
||||
}
|
||||
if (wta != NULL) httplib_free( wta );
|
||||
|
||||
if (i > 0) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "Cannot start worker thread %i: error %ld", i + 1, (long)ERRNO);
|
||||
|
@@ -50,7 +50,7 @@ LIBHTTP_API char *httplib_strndup( const char *ptr, size_t len ) {
|
||||
|
||||
char *p;
|
||||
|
||||
if ( (p = XX_httplib_malloc(len+1)) != NULL ) httplib_strlcpy( p, ptr, len+1 );
|
||||
if ( (p = httplib_malloc( len+1 )) != NULL ) httplib_strlcpy( p, ptr, len+1 );
|
||||
|
||||
return p;
|
||||
|
||||
|
@@ -44,7 +44,7 @@ void XX_httplib_tls_dtor( void *key ) {
|
||||
if (tls) {
|
||||
if (tls->is_master == 2) {
|
||||
tls->is_master = -3; /* Mark memory as dead */
|
||||
XX_httplib_free(tls);
|
||||
httplib_free( tls );
|
||||
}
|
||||
}
|
||||
pthread_setspecific(XX_httplib_sTlsKey, NULL);
|
||||
|
@@ -62,7 +62,7 @@ void XX_httplib_uninitialize_ssl( struct httplib_context *ctx ) {
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
pthread_mutex_destroy(&XX_httplib_ssl_mutexes[i]);
|
||||
}
|
||||
XX_httplib_free(XX_httplib_ssl_mutexes);
|
||||
httplib_free( XX_httplib_ssl_mutexes );
|
||||
XX_httplib_ssl_mutexes = NULL;
|
||||
}
|
||||
|
||||
|
@@ -38,10 +38,10 @@ static int alloc_vprintf2( char **buf, const char *fmt, va_list ap ) {
|
||||
|
||||
*buf = NULL;
|
||||
while (len < 0) {
|
||||
if (*buf) XX_httplib_free(*buf);
|
||||
if (*buf) httplib_free( *buf );
|
||||
|
||||
size *= 4;
|
||||
*buf = (char *)XX_httplib_malloc(size);
|
||||
*buf = httplib_malloc( size );
|
||||
if (!*buf) break;
|
||||
|
||||
va_copy(ap_copy, ap);
|
||||
@@ -83,7 +83,7 @@ static int alloc_vprintf( char **out_buf, char *prealloc_buf, size_t prealloc_si
|
||||
} else if ((size_t)(len) >= prealloc_size) {
|
||||
/* The pre-allocated buffer not large enough. */
|
||||
/* Allocate a new buffer. */
|
||||
*out_buf = (char *)XX_httplib_malloc((size_t)(len) + 1);
|
||||
*out_buf = httplib_malloc( (size_t)(len) + 1 );
|
||||
if (!*out_buf) {
|
||||
/* Allocation failed. Return -1 as "out of memory" error. */
|
||||
return -1;
|
||||
@@ -116,7 +116,7 @@ int XX_httplib_vprintf( struct httplib_connection *conn, const char *fmt, va_lis
|
||||
int len;
|
||||
|
||||
if ((len = alloc_vprintf(&buf, mem, sizeof(mem), fmt, ap)) > 0) len = httplib_write(conn, buf, (size_t)len);
|
||||
if (buf != mem && buf != NULL) XX_httplib_free(buf);
|
||||
if (buf != mem && buf != NULL) httplib_free( buf );
|
||||
|
||||
return len;
|
||||
|
||||
|
@@ -57,7 +57,7 @@ void * XX_httplib_websocket_client_thread(void *data) {
|
||||
|
||||
if (cdata->close_handler != NULL) cdata->close_handler(cdata->conn, cdata->callback_data);
|
||||
|
||||
XX_httplib_free((void *)cdata);
|
||||
httplib_free( cdata );
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@@ -43,7 +43,7 @@ static void mask_data( const char *in, size_t in_len, uint32_t masking_key, char
|
||||
int httplib_websocket_client_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ) {
|
||||
|
||||
int retval = -1;
|
||||
char *masked_data = XX_httplib_malloc(((dataLen + 7) / 4) * 4);
|
||||
char *masked_data = httplib_malloc( ((dataLen + 7) / 4) * 4 );
|
||||
uint32_t masking_key = (uint32_t)XX_httplib_get_random();
|
||||
|
||||
if (masked_data == NULL) {
|
||||
@@ -55,7 +55,7 @@ int httplib_websocket_client_write( struct httplib_connection *conn, int opcode,
|
||||
mask_data(data, dataLen, masking_key, masked_data);
|
||||
|
||||
retval = XX_httplib_websocket_write_exec( conn, opcode, masked_data, dataLen, masking_key );
|
||||
XX_httplib_free(masked_data);
|
||||
httplib_free( masked_data );
|
||||
|
||||
return retval;
|
||||
|
||||
|
@@ -49,7 +49,7 @@ void *XX_httplib_worker_thread( void *thread_func_param ) {
|
||||
|
||||
struct worker_thread_args *pwta = (struct worker_thread_args *)thread_func_param;
|
||||
worker_thread_run(pwta);
|
||||
XX_httplib_free(thread_func_param);
|
||||
httplib_free( thread_func_param );
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -83,8 +83,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
|
||||
ctx->callbacks.init_thread(ctx, 1);
|
||||
}
|
||||
|
||||
conn =
|
||||
(struct httplib_connection *)XX_httplib_calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE);
|
||||
conn = httplib_calloc( 1, sizeof(*conn) + MAX_REQUEST_SIZE );
|
||||
if (conn == NULL) {
|
||||
httplib_cry( XX_httplib_fc(ctx), "%s", "Cannot create new connection struct, OOM");
|
||||
} else {
|
||||
@@ -97,7 +96,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
|
||||
/* Allocate a mutex for this connection to allow communication both
|
||||
* within the request handler and from elsewhere in the application
|
||||
*/
|
||||
(void)pthread_mutex_init(&conn->mutex, &XX_httplib_pthread_mutex_attr);
|
||||
pthread_mutex_init(&conn->mutex, &XX_httplib_pthread_mutex_attr);
|
||||
|
||||
/* Call XX_httplib_consume_socket() even when ctx->stop_flag > 0, to let it
|
||||
* signal sq_empty condvar to wake up the master waiting in
|
||||
@@ -130,6 +129,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
|
||||
#ifndef NO_SSL
|
||||
/* HTTPS connection */
|
||||
if ( XX_httplib_sslize( conn, conn->ctx->ssl_ctx, SSL_accept ) ) {
|
||||
|
||||
/* Get SSL client certificate information (if set) */
|
||||
XX_httplib_ssl_get_client_cert_info(conn);
|
||||
|
||||
@@ -137,21 +137,15 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
|
||||
XX_httplib_process_new_connection(conn);
|
||||
|
||||
/* Free client certificate info */
|
||||
if (conn->request_info.client_cert) {
|
||||
XX_httplib_free(
|
||||
(void *)(conn->request_info.client_cert->subject));
|
||||
XX_httplib_free(
|
||||
(void *)(conn->request_info.client_cert->issuer));
|
||||
XX_httplib_free(
|
||||
(void *)(conn->request_info.client_cert->serial));
|
||||
XX_httplib_free(
|
||||
(void *)(conn->request_info.client_cert->finger));
|
||||
conn->request_info.client_cert->subject = 0;
|
||||
conn->request_info.client_cert->issuer = 0;
|
||||
conn->request_info.client_cert->serial = 0;
|
||||
conn->request_info.client_cert->finger = 0;
|
||||
XX_httplib_free(conn->request_info.client_cert);
|
||||
conn->request_info.client_cert = 0;
|
||||
if ( conn->request_info.client_cert != NULL ) {
|
||||
|
||||
httplib_free( (void *)conn->request_info.client_cert->subject );
|
||||
httplib_free( (void *)conn->request_info.client_cert->issuer );
|
||||
httplib_free( (void *)conn->request_info.client_cert->serial );
|
||||
httplib_free( (void *)conn->request_info.client_cert->finger );
|
||||
httplib_free( (void *)conn->request_info.client_cert );
|
||||
|
||||
conn->request_info.client_cert = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -169,7 +163,7 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) {
|
||||
CloseHandle(tls.pthread_cond_helper_mutex);
|
||||
#endif
|
||||
pthread_mutex_destroy(&conn->mutex);
|
||||
XX_httplib_free(conn);
|
||||
httplib_free( conn );
|
||||
|
||||
return NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user