1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-07 16:02:55 +03:00

Code cleanup

This commit is contained in:
Lammert Bies
2016-12-26 13:35:16 +01:00
parent 1230958eb3
commit f77e497a65
14 changed files with 118 additions and 143 deletions

View File

@@ -1281,12 +1281,10 @@ ${OBJDIR}httplib_strcasestr${OBJEXT} : ${SRCDIR}httplib_strcasestr.c \
${INCDIR}libhttp.h ${INCDIR}libhttp.h
${OBJDIR}httplib_strdup${OBJEXT} : ${SRCDIR}httplib_strdup.c \ ${OBJDIR}httplib_strdup${OBJEXT} : ${SRCDIR}httplib_strdup.c \
${SRCDIR}httplib_string.h \
${SRCDIR}httplib_main.h \ ${SRCDIR}httplib_main.h \
${INCDIR}libhttp.h ${INCDIR}libhttp.h
${OBJDIR}httplib_strlcpy${OBJEXT} : ${SRCDIR}httplib_strlcpy.c \ ${OBJDIR}httplib_strlcpy${OBJEXT} : ${SRCDIR}httplib_strlcpy.c \
${SRCDIR}httplib_string.h \
${SRCDIR}httplib_main.h \ ${SRCDIR}httplib_main.h \
${INCDIR}libhttp.h ${INCDIR}libhttp.h
@@ -1297,7 +1295,6 @@ ${OBJDIR}httplib_strncasecmp${OBJEXT} : ${SRCDIR}httplib_strncasecmp.c \
${OBJDIR}httplib_strndup${OBJEXT} : ${SRCDIR}httplib_strndup.c \ ${OBJDIR}httplib_strndup${OBJEXT} : ${SRCDIR}httplib_strndup.c \
${SRCDIR}httplib_memory.h \ ${SRCDIR}httplib_memory.h \
${SRCDIR}httplib_string.h \
${SRCDIR}httplib_main.h \ ${SRCDIR}httplib_main.h \
${INCDIR}libhttp.h ${INCDIR}libhttp.h

View File

@@ -839,8 +839,6 @@ LIBHTTP_API const char * httplib_get_builtin_mime_type( const char *file_name );
LIBHTTP_API const char *httplib_get_response_code_text(struct httplib_connection *conn, int response_code); LIBHTTP_API const char *httplib_get_response_code_text(struct httplib_connection *conn, int response_code);
/* Return LibHTTP version. */
LIBHTTP_API const char *httplib_version(void);
/* URL-decode input buffer into destination buffer. /* URL-decode input buffer into destination buffer.
@@ -1019,6 +1017,7 @@ LIBHTTP_API char * httplib_strdup( const char *str );
LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len ); LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len );
LIBHTTP_API int httplib_strncasecmp( const char *s1, const char *s2, size_t len ); LIBHTTP_API int httplib_strncasecmp( const char *s1, const char *s2, size_t len );
LIBHTTP_API char * httplib_strndup( const char *str, size_t len ); LIBHTTP_API char * httplib_strndup( const char *str, size_t len );
LIBHTTP_API const char * httplib_version( void );
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -20,27 +20,31 @@
* 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"
/* /*
* void XX_httplib_fclose( struct file *filep ); * int XX_httplib_fclose( struct file *filep );
* *
* The function XX_httplib_fclose() closed a file associated with a filep * The function XX_httplib_fclose() closed a file associated with a filep
* structure. The function doesn't return a success or error code, but the * structure. If the function succeeds, the value 0 is returned. Otherwise
* value of the fp parameter in the filep structure is reset to NULL which * the return value is EOF and errno is set.
* prevents the old file pointer to be reused.
*/ */
void XX_httplib_fclose( struct file *filep ) { int XX_httplib_fclose( struct file *filep ) {
if ( filep == NULL || filep->fp == NULL ) return; int retval;
fclose( filep->fp ); if ( filep == NULL || filep->fp == NULL ) {
errno = EINVAL;
return EOF;
}
retval = fclose( filep->fp );
filep->fp = NULL; filep->fp = NULL;
return retval;
} /* XX_httplib_fclose */ } /* XX_httplib_fclose */

View File

@@ -613,37 +613,36 @@ struct httplib_context {
* struct httplib_connection; * struct httplib_connection;
*/ */
struct httplib_connection { /****************************************************************************************/
struct httplib_request_info request_info; struct httplib_connection { /* */
struct httplib_context *ctx; struct httplib_request_info request_info; /* The request info of the connection */
SSL *ssl; /* SSL descriptor */ struct httplib_context *ctx; /* The LibHTTP context of the connection */
SSL_CTX *client_ssl_ctx; /* SSL context for client connections */ SSL * ssl; /* SSL descriptor */
struct socket client; /* Connected client */ SSL_CTX * client_ssl_ctx; /* SSL context for client connections */
time_t conn_birth_time; /* Time (wall clock) when connection was established */ struct socket client; /* Connected client */
struct timespec req_time; /* Time (since system start) when the request was received */ time_t conn_birth_time; /* Time (wall clock) when connection was established */
int64_t num_bytes_sent; /* Total bytes sent to client */ struct timespec req_time; /* Time (since system start) when the request was received */
int64_t content_len; /* Content-Length header value */ int64_t num_bytes_sent; /* Total bytes sent to client */
int64_t consumed_content; /* How many bytes of content have been read */ int64_t content_len; /* Content-Length header value */
int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: data available, 2: all data read */ int64_t consumed_content; /* How many bytes of content have been read */
size_t chunk_remainder; /* Unread data from the last chunk */ int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: data available, 2: all data read */
char *buf; /* Buffer for received data */ size_t chunk_remainder; /* Unread data from the last chunk */
char *path_info; /* PATH_INFO part of the URL */ char * buf; /* Buffer for received data */
char * path_info; /* PATH_INFO part of the URL */
int must_close; /* 1 if connection must be closed */ int must_close; /* 1 if connection must be closed */
int in_error_handler; /* 1 if in handler for user defined error pages */ int in_error_handler; /* 1 if in handler for user defined error pages */
int internal_error; /* 1 if an error occured while processing the request */ int internal_error; /* 1 if an error occured while processing the request */
int buf_size; /* Buffer size */
int buf_size; /* Buffer size */ int request_len; /* Size of the request + headers in a buffer */
int request_len; /* Size of the request + headers in a buffer */ int data_len; /* Total size of data in a buffer */
int data_len; /* Total size of data in a buffer */ int status_code; /* HTTP reply status code, e.g. 200 */
int status_code; /* HTTP reply status code, e.g. 200 */ time_t last_throttle_time; /* Last time throttled data was sent */
int throttle; /* Throttling, bytes/sec. <= 0 means no throttle */ int64_t throttle; /* Throttling, bytes/sec. <= 0 means no throttle */
time_t last_throttle_time; /* Last time throttled data was sent */ int64_t last_throttle_bytes; /* Bytes sent this second */
int64_t last_throttle_bytes; /* Bytes sent this second */ pthread_mutex_t mutex; /* Used by httplib_(un)lock_connection to ensure atomic transmissions for websockets */
pthread_mutex_t mutex; /* Used by httplib_(un)lock_connection to ensure atomic transmissions for websockets */ int thread_index; /* Thread index within ctx */
}; /* */
int thread_index; /* Thread index within ctx */ /****************************************************************************************/
};
struct worker_thread_args { struct worker_thread_args {
struct httplib_context *ctx; struct httplib_context *ctx;
@@ -673,7 +672,7 @@ struct file {
int gzipped; /* set to 1 if the content is gzipped in which case we need a content-encoding: gzip header */ int gzipped; /* set to 1 if the content is gzipped in which case we need a content-encoding: gzip header */
}; };
#define STRUCT_FILE_INITIALIZER { (uint64_t)0, (time_t)0, (FILE *)NULL, (const char *)NULL, 0, 0 } #define STRUCT_FILE_INITIALIZER { (uint64_t)0, (time_t)0, NULL, NULL, 0, 0 }
/* Describes a string (chunk of memory). */ /* Describes a string (chunk of memory). */
struct vec { struct vec {
@@ -805,7 +804,7 @@ void XX_httplib_delete_file( struct httplib_connection *conn, const char *path
void XX_httplib_dir_scan_callback( struct de *de, void *data ); void XX_httplib_dir_scan_callback( struct de *de, void *data );
void XX_httplib_discard_unread_request_data( struct httplib_connection *conn ); void XX_httplib_discard_unread_request_data( struct httplib_connection *conn );
struct httplib_connection * XX_httplib_fc( struct httplib_context *ctx ); struct httplib_connection * XX_httplib_fc( struct httplib_context *ctx );
void 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( 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_connection *conn, const char *path, const char *mode, struct file *filep );

View File

@@ -32,7 +32,8 @@
* void XX_httplib_mkcol( struct httplib_connection *conn, const char *path ); * void XX_httplib_mkcol( 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. * client. The MKCOL method is used to create a new collection resource at the
* location specificied by the request URI.
*/ */
#if !defined(NO_FILES) #if !defined(NO_FILES)

View File

@@ -29,39 +29,43 @@
#include "httplib_ssl.h" #include "httplib_ssl.h"
#include "httplib_utils.h" #include "httplib_utils.h"
/*
* static int push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int len, double timeout );
*
* The function push() writes data to the I/O chanel, opened file descriptor,
* socket or SSL descriptor. The function returns the number of bytes which
* were actually written.
*/
static int push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int len, double timeout ) {
struct timespec start;
struct timespec now;
int n;
int err;
#ifdef _WIN32 #ifdef _WIN32
typedef int len_t; typedef int len_t;
#else #else
typedef size_t len_t; typedef size_t len_t;
#endif #endif
/*
* static int64_t push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout );
*
* The function push() writes data to the I/O channel, opened file descriptor,
* socket or SSL descriptor. The function returns the number of bytes which
* were actually written. A negative value is returned if an error is
* encountered.
*
* Although we specify the number of bytes in a 64 bit integer, the OS functins
* may not be able to handle that. We therefore cap the amount of bytes to
* write to the maximum integer and size_t value, whatever is the smallest. The
* function push() will be called automatically again if not all bytes have
* been written.
*/
static int64_t push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len, double timeout ) {
struct timespec start;
struct timespec now;
int n;
int err;
if ( ctx == NULL ) return -1; if ( ctx == NULL ) return -1;
#ifdef NO_SSL #ifdef NO_SSL
if ( ssl != NULL ) return -1; if ( ssl != NULL ) return -1;
#endif #endif /* NO_SSL */
if ( timeout > 0 ) { if ( len > (int64_t)SIZE_T_MAX ) len = SIZE_T_MAX;
if ( len > (int64_t)INT_MAX ) len = INT_MAX;
memset( & start, 0, sizeof(start) ); if ( timeout > 0.0 ) clock_gettime( CLOCK_MONOTONIC, &start );
memset( & now, 0, sizeof(now) );
clock_gettime( CLOCK_MONOTONIC, &start );
}
do { do {
@@ -84,7 +88,7 @@ static int push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, c
} }
else else
#endif #endif /* NO_SSL */
if ( fp != NULL ) { if ( fp != NULL ) {
n = (int)fwrite( buf, 1, (size_t)len, fp ); n = (int)fwrite( buf, 1, (size_t)len, fp );
@@ -113,14 +117,7 @@ static int push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, c
if ( ctx->stop_flag ) return -1; if ( ctx->stop_flag ) return -1;
if ( n > 0 || (n == 0 && len == 0) ) { if ( n > 0 || (n == 0 && len == 0) ) return n;
/*
* some data has been read, or no data was requested
*/
return n;
}
if ( n < 0 ) { if ( n < 0 ) {
@@ -139,9 +136,9 @@ static int push( struct httplib_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, c
* ==> Fix the TODOs above first. * ==> Fix the TODOs above first.
*/ */
if ( timeout > 0 ) clock_gettime( CLOCK_MONOTONIC, &now ); if ( timeout > 0.0 ) clock_gettime( CLOCK_MONOTONIC, &now );
} while ( timeout <= 0 || XX_httplib_difftimespec( &now, &start ) <= timeout ); } while ( timeout <= 0.0 || XX_httplib_difftimespec( &now, &start ) <= timeout );
return -1; return -1;
@@ -171,31 +168,18 @@ int64_t XX_httplib_push_all( struct httplib_context *ctx, FILE *fp, SOCKET sock,
while ( len > 0 && ctx->stop_flag == 0 ) { while ( len > 0 && ctx->stop_flag == 0 ) {
n = push( ctx, fp, sock, ssl, buf + nwritten, (int)len, timeout ); n = push( ctx, fp, sock, ssl, buf + nwritten, len, timeout );
if ( n < 0 ) { if ( n < 0 ) {
/* if ( nwritten == 0 ) return n;
* Propagate the error else return nwritten;
*/
if ( nwritten == 0 ) nwritten = n;
break;
} }
else if ( n == 0 ) { if ( n == 0 ) return nwritten;
/* nwritten += n;
* No more data to write len -= n;
*/
break;
}
else {
nwritten += n;
len -= n;
}
} }
return nwritten; return nwritten;

View File

@@ -58,7 +58,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 && XX_httplib_is_file_in_memory( conn, path, filep ) ) { if ( conn != NULL && XX_httplib_is_file_in_memory( conn, path, filep ) ) {
/* /*
* filep->is_directory = 0; filep->gzipped = 0; .. already done by * filep->is_directory = 0; filep->gzipped = 0; .. already done by

View File

@@ -30,7 +30,9 @@
/* /*
* int64_t httplib_store_body( struct httplib_connection *conn, const char *path ); * int64_t httplib_store_body( struct httplib_connection *conn, const char *path );
* *
* The function httplib_store_body() stores in incoming body for future processing. * The function httplib_store_body() stores in incoming body for future
* processing. The function returns the number of bytes actually read, or a
* negative number to indicate a failure.
*/ */
int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) { int64_t httplib_store_body( struct httplib_connection *conn, const char *path ) {
@@ -59,6 +61,7 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path )
return ret; return ret;
} }
if ( ret != 1 ) { if ( ret != 1 ) {
/* /*
@@ -84,12 +87,7 @@ int64_t httplib_store_body( struct httplib_connection *conn, const char *path )
ret = httplib_read( conn, buf, sizeof(buf) ); ret = httplib_read( conn, buf, sizeof(buf) );
} }
/* if ( XX_httplib_fclose( & fi ) != 0 ) {
* TODO: XX_httplib_fclose should return an error,
* and every caller should check and handle it.
*/
if ( fclose(fi.fp) != 0 ) {
XX_httplib_remove_bad_file( conn, path ); XX_httplib_remove_bad_file( conn, path );
return -14; return -14;

View File

@@ -20,13 +20,9 @@
* 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"
#include "httplib_string.h"
/* /*
* char *httplib_strdup( const char *str ); * char *httplib_strdup( const char *str );
@@ -41,10 +37,10 @@
* the returned value is NULL. * the returned value is NULL.
*/ */
char *httplib_strdup( const char *str ) { LIBHTTP_API char *httplib_strdup( const char *str ) {
if ( str == NULL ) return NULL; if ( str == NULL ) return NULL;
return httplib_strndup(str, strlen( str ) ); return httplib_strndup( str, strlen( str ) );
} /* httplib_strdup */ } /* httplib_strdup */

View File

@@ -20,13 +20,9 @@
* 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"
#include "httplib_string.h"
/* /*
* void httplib_strlcpy( char *dst, const char *src, size_t len ); * void httplib_strlcpy( char *dst, const char *src, size_t len );
@@ -45,15 +41,15 @@
LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len ) { LIBHTTP_API void httplib_strlcpy( char *dst, const char *src, size_t len ) {
if ( dst == NULL || len == 0 ) return; if ( dst == NULL || len == 0 ) return;
if ( src == NULL ) { *dst = 0; return; } if ( src == NULL ) { *dst = '\0'; return; }
while ( len > 1 && *src ) { while ( len > 1 && *src != '\0' ) {
*dst++ = *src++; *dst++ = *src++;
len--; len--;
} }
*dst = 0; *dst = '\0';
} /* httplib_strlcpy */ } /* httplib_strlcpy */

View File

@@ -20,17 +20,13 @@
* 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"
#include "httplib_memory.h" #include "httplib_memory.h"
#include "httplib_string.h"
/* /*
* char *httplib_strndup( const char *ptr, size_t len ); * char *httplib_strndup( const char *str, size_t len );
* *
* The function strndup() duplicates a string with a maximum given length to a * The function strndup() duplicates a string with a maximum given length to a
* new string in a newly allocated block of memory. The function is equivalent * new string in a newly allocated block of memory. The function is equivalent
@@ -46,11 +42,16 @@
* the duplicate. * the duplicate.
*/ */
LIBHTTP_API char *httplib_strndup( const char *ptr, size_t len ) { LIBHTTP_API char *httplib_strndup( const char *str, size_t len ) {
char *p; char *p;
if ( (p = httplib_malloc( len+1 )) != NULL ) httplib_strlcpy( p, ptr, len+1 ); if ( str == NULL ) return NULL;
p = httplib_malloc( len+1 );
if ( p == NULL ) return NULL;
httplib_strlcpy( p, str, len+1 );
return p; return p;

View File

@@ -20,9 +20,6 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* ============
* Release: 2.0
*/ */
#include "httplib_main.h" #include "httplib_main.h"
@@ -34,7 +31,7 @@
* NULL terminated string. * NULL terminated string.
*/ */
const char *httplib_version( void ) { LIBHTTP_API const char *httplib_version( void ) {
return LIBHTTP_VERSION; return LIBHTTP_VERSION;

View File

@@ -30,7 +30,8 @@
/* /*
* int httplib_websocket_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen ); * int httplib_websocket_write( struct httplib_connection *conn, int opcode, const char *data, size_t dataLen );
* *
* The function httplib_websocket_write() writes data over a websocket connection. * The function httplib_websocket_write() writes data over a websocket
* connection.
*/ */
#if defined(USE_WEBSOCKET) #if defined(USE_WEBSOCKET)

View File

@@ -20,19 +20,21 @@
* 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"
/* /*
* The function httplib_write() writes a number of characters over a * The function httplib_write() writes a number of bytes over a connection.
* 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.
* *
* The function uses throtteling when necessary for a connection. * The function uses throtteling when necessary for a connection. Throtteling
* uses the wall clock. Although this can be dangerous in some situations where
* the value of the wall clock is changed externally, it isn't in this case
* because the throttle function only looks when the time calue changes, but
* doesn't take the actual value of the clock in the calculation. In the latter
* 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( struct httplib_connection *conn, const void *buffie, size_t lennie ) {
@@ -47,7 +49,7 @@ int httplib_write( struct httplib_connection *conn, const void *buffie, size_t l
if ( conn == NULL || buffie == NULL || lennie == 0 ) return 0; if ( conn == NULL || buffie == NULL || lennie == 0 ) return 0;
buf = buffie; buf = buffie;
len = (int64_t)lennie; len = lennie;
if ( conn->throttle > 0 ) { if ( conn->throttle > 0 ) {