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

Renamed httplib_server_ports to lh_slp_t

This commit is contained in:
Lammert Bies
2017-01-02 13:11:39 +01:00
parent f184ad39ff
commit edbeae386f
2 changed files with 249 additions and 490 deletions

View File

@@ -45,7 +45,23 @@
#else
#define LIBHTTP_API
#endif
#endif
#endif /* LIBHTTP_API */
#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 */
#include <stdio.h>
#include <stddef.h>
@@ -128,7 +144,7 @@ typedef struct DIR {
WIN32_FIND_DATAW info;
struct dirent result;
} DIR;
#endif
#endif /* _WIN32 */
#if defined(_WIN32) && !defined(POLLIN)
/*
@@ -144,13 +160,97 @@ struct pollfd {
#endif /* HAVE_POLL */
#endif /* _WIN32 && ! POLLIN */
/*
* Macros for enabling compiler-specific checks for printf-like arguments.
*/
struct lh_ctx_t; /* Handle for the HTTP service itself */
struct lh_con_t; /* Handle for the individual connection */
#undef PRINTF_FORMAT_STRING
#if defined(_MSC_VER) && _MSC_VER >= 1400
#include <sal.h>
#if defined(_MSC_VER) && _MSC_VER > 1400
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
#else
#define PRINTF_FORMAT_STRING(s) __format_string s
#endif
#else
#define PRINTF_FORMAT_STRING(s) s
#endif
#ifdef __GNUC__
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
#else
#define PRINTF_ARGS(x, y)
#endif
/************************************************************************************************/
/* */
/* enum debug_level_t; */
/* */
/* Error messages are generated depending on the debug level of a context. Different contexts */
/* can have different debug levels allowing an application to only generate debug messages of */
/* specific servers or client connections. */
enum debug_level_t { /* */
DEBUG_LEVEL_NONE = 0x00, /* No error messages are generated at all */
DEBUG_LEVEL_CRASH = 0x10, /* Messages for errors impacting multiple connections in a severe way are generated */
DEBUG_LEVEL_ERROR = 0x20, /* Messages for errors impacting single connections in a severe way are generated (default) */
DEBUG_LEVEL_WARNING = 0x30, /* Messages for errors impacting single connections in a minor way are generated */
DEBUG_LEVEL_INFO = 0x40 /* All error, warning and informational messages are generated */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* Return values definition for the "field_found" callback in httplib_form_data_handler. */
enum { /* */
FORM_FIELD_STORAGE_SKIP = 0x00, /* Skip this field (neither get nor store it). Continue with the next field. */
FORM_FIELD_STORAGE_GET = 0x01, /* Get the field value. */
FORM_FIELD_STORAGE_STORE = 0x02, /* Store the field value into a file. */
FORM_FIELD_STORAGE_ABORT = 0x10 /* Stop parsing this request. Skip the remaining fields */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
enum { /* */
WEBSOCKET_OPCODE_CONTINUATION = 0x00, /* */
WEBSOCKET_OPCODE_TEXT = 0x01, /* */
WEBSOCKET_OPCODE_BINARY = 0x02, /* */
WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x08, /* */
WEBSOCKET_OPCODE_PING = 0x09, /* */
WEBSOCKET_OPCODE_PONG = 0x0A /* */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* struct lh_ctx_t; */
/* struct lh_con_t; */
/* */
/* Hidden structures used by the library to store context and connection information */
/* */
struct lh_ctx_t; /* Handle for an HTTP context */
struct lh_con_t; /* Handle for an individual connection */
/* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* struct client_cert; */
/* */
/* Client certificate information (part of lh_rqi_t) */
struct client_cert { /* */
const char *subject; /* Subject of the certificate */
const char *issuer; /* Issuer of the certificate */
const char *serial; /* Serial number of the certificate */
const char *finger; /* Finger print of the certificate */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* struct lh_rqi_t; */
/* */
/* This structure contains information about the HTTP request. */
struct lh_rqi_t { /* */
const char * request_method; /* "GET", "POST", etc */
@@ -175,402 +275,72 @@ struct lh_rqi_t { /* */
}; /* */
/************************************************************************************************/
/* Client certificate information (part of lh_rqi_t) */
struct client_cert {
const char *subject;
const char *issuer;
const char *serial;
const char *finger;
};
/*
* This structure needs to be passed to httplib_start(), to let LibHTTP know
* which callbacks to invoke. For a detailed description, see
* https://github.com/lammertb/libhttp/blob/master/docs/UserManual.md
*/
struct lh_clb_t {
int (*begin_request)( const struct lh_ctx_t *ctx, struct lh_con_t *conn );
void (*end_request)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, int reply_status_code );
int (*log_message)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *message );
int (*log_access)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *message );
int (*init_ssl)( const struct lh_ctx_t *ctx, void *ssl_context, void *user_data );
void (*connection_close)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn );
const char * (*open_file)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *path, size_t *data_len );
void (*init_lua)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, void *lua_context );
int (*http_error)( const struct lh_ctx_t *ctx, struct lh_con_t *, int status);
void (*init_context)( const struct lh_ctx_t *ctx );
void (*init_thread)( const struct lh_ctx_t *ctx, int thread_type );
void (*exit_context)( const struct lh_ctx_t *ctx );
};
/************************************************************************************************/
/* */
/* struct lh_clb_t; */
/* */
/* This structure needs to be passed to httplib_start(), to let LibHTTP know which callbacks to */
/* invoke. For a detailed description, see */
/* https://github.com/lammertb/libhttp/blob/master/docs/UserManual.md */
struct lh_clb_t { /* */
int (*begin_request)( const struct lh_ctx_t *ctx, struct lh_con_t *conn ); /* */
void (*end_request)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, int reply_status_code ); /* */
int (*log_message)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *message ); /* */
int (*log_access)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *message ); /* */
int (*init_ssl)( const struct lh_ctx_t *ctx, void *ssl_context, void *user_data ); /* */
void (*connection_close)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn ); /* */
const char * (*open_file)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, const char *path, size_t *data_len ); /* */
void (*init_lua)( const struct lh_ctx_t *ctx, const struct lh_con_t *conn, void *lua_context ); /* */
int (*http_error)( const struct lh_ctx_t *ctx, struct lh_con_t *, int status ); /* */
void (*init_context)( const struct lh_ctx_t *ctx ); /* */
void (*init_thread)( const struct lh_ctx_t *ctx, int thread_type ); /* */
void (*exit_context)( const struct lh_ctx_t *ctx ); /* */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* struct lh_opt_t; */
/* */
/* Option record passed in an array of option records when a context is created */
struct lh_opt_t { /* */
const char * name; /* name of the option used when creating a context */
const char * value; /* value of the option */
}; /* */
/************************************************************************************************/
/************************************************************************************************/
/* */
/* struct lh_slp_t */
/* */
/* Record of a port a server is listening on */
struct lh_slp_t { /* */
int protocol; /* The protocol supported by the port: 1 = IPv4, 2 = IPv6, 3 = both */
int port; /* The port number the server is listening on */
bool has_ssl; /* Does this port support https encryption: false = no, true = yes */
bool has_redirect; /* redirect all requests to a https connection false = no, true = yes */
}; /* */
/************************************************************************************************/
typedef int (*httplib_request_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
typedef int (*httplib_authorization_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
/* Callback types for websocket handlers in C/C++.
httplib_websocket_connect_handler
Is called when the client intends to establish a websocket connection,
before websocket handshake.
Return value:
0: LibHTTP proceeds with websocket handshake.
1: connection is closed immediately.
httplib_websocket_ready_handler
Is called when websocket handshake is successfully completed, and
connection is ready for data exchange.
httplib_websocket_data_handler
Is called when a data frame has been received from the client.
Parameters:
bits: first byte of the websocket frame, see websocket RFC at
http://tools.ietf.org/html/rfc6455, section 5.2
data, data_len: payload, with mask (if any) already applied.
Return value:
1: keep this websocket connection open.
0: close this websocket connection.
lh_con_t_close_handler
Is called, when the connection is closed.*/
typedef int (*httplib_websocket_connect_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *);
typedef void (*httplib_websocket_ready_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *);
typedef int (*httplib_websocket_data_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int, char *, size_t, void *);
typedef void (*httplib_websocket_close_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *);
/* httplib_set_auth_handler
Sets or removes a URI mapping for an authorization handler.
This function works similar to httplib_set_request_handler - see there. */
/* Get the value of particular configuration parameter.
The value returned is read-only. LibHTTP does not allow changing
configuration at run time.
If given parameter name is not valid, NULL is returned. For valid
names, return value is guaranteed to be non-NULL. If parameter is not
set, zero-length string is returned. */
/* Get user data passed to httplib_start from context. */
struct httplib_server_ports {
int protocol; /* 1 = IPv4, 2 = IPv6, 3 = both */
int port; /* port number */
bool has_ssl; /* https port: 0 = no, 1 = yes */
bool has_redirect; /* redirect all requests: 0 = no, 1 = yes */
};
/* Get the list of ports that LibHTTP is listening on.
The parameter size is the size of the ports array in elements.
The caller is responsibility to allocate the required memory.
This function returns the number of struct httplib_server_ports elements
filled in, or <0 in case of an error. */
/* Add, edit or delete the entry in the passwords file.
This function allows an application to manipulate .htpasswd files on the
fly by adding, deleting and changing user records. This is one of the
several ways of implementing authentication on the server side. For another,
cookie-based way please refer to the examples/chat in the source tree.
If password is not NULL, entry is added (or modified if already exists).
If password is NULL, entry is deleted.
Return:
1 on success, 0 on error. */
/* Return information associated with the request. */
/* Send data to the client.
Return:
0 when the connection has been closed
-1 on error
>0 number of bytes written on success */
/* Send data to a websocket client wrapped in a websocket frame. Uses
httplib_lock_connection to ensure that the transmission is not interrupted,
i.e., when the application is proactively communicating and responding to
a request simultaneously.
Send data to a websocket client wrapped in a websocket frame.
Return:
0 when the connection has been closed
-1 on error
>0 number of bytes written on success */
/* Send data to a websocket server wrapped in a masked websocket frame. Uses
httplib_lock_connection to ensure that the transmission is not interrupted,
i.e., when the application is proactively communicating and responding to
a request simultaneously.
Send data to a websocket server wrapped in a masked websocket frame.
Return:
0 when the connection has been closed
-1 on error
>0 number of bytes written on success */
/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
enum {
WEBSOCKET_OPCODE_CONTINUATION = 0x0,
WEBSOCKET_OPCODE_TEXT = 0x1,
WEBSOCKET_OPCODE_BINARY = 0x2,
WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
WEBSOCKET_OPCODE_PING = 0x9,
WEBSOCKET_OPCODE_PONG = 0xA
};
/* Macros for enabling compiler-specific checks for printf-like arguments. */
#undef PRINTF_FORMAT_STRING
#if defined(_MSC_VER) && _MSC_VER >= 1400
#include <sal.h>
#if defined(_MSC_VER) && _MSC_VER > 1400
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
#else
#define PRINTF_FORMAT_STRING(s) __format_string s
#endif
#else
#define PRINTF_FORMAT_STRING(s) s
#endif
#ifdef __GNUC__
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
#else
#define PRINTF_ARGS(x, y)
#endif
/* Read data from the remote end, return number of bytes read.
Return:
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 number of bytes read into the buffer. */
/* Get the value of particular HTTP header.
This is a helper function. It traverses request_info->http_headers array,
and if the header is present in the array, returns its value. If it is
not present, NULL is returned. */
/* Get a value of particular form variable.
Parameters:
data: pointer to form-uri-encoded buffer. This could be either POST data,
or request_info.query_string.
data_len: length of the encoded data.
var_name: variable name to decode from the buffer
dst: destination buffer for the decoded variable
dst_len: length of the destination buffer
Return:
On success, length of the decoded variable.
On error:
-1 (variable not found).
-2 (destination buffer is NULL, zero length or too small to hold the
decoded variable).
Destination buffer is guaranteed to be '\0' - terminated if it is not
NULL or zero length. */
/* Get a value of particular form variable.
Parameters:
data: pointer to form-uri-encoded buffer. This could be either POST data,
or request_info.query_string.
data_len: length of the encoded data.
var_name: variable name to decode from the buffer
dst: destination buffer for the decoded variable
dst_len: length of the destination buffer
occurrence: which occurrence of the variable, 0 is the first, 1 the
second...
this makes it possible to parse a query like
b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
Return:
On success, length of the decoded variable.
On error:
-1 (variable not found).
-2 (destination buffer is NULL, zero length or too small to hold the
decoded variable).
Destination buffer is guaranteed to be '\0' - terminated if it is not
NULL or zero length. */
/* Fetch value of certain cookie variable into the destination buffer.
Destination buffer is guaranteed to be '\0' - terminated. In case of
failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
parameter. This function returns only first occurrence.
Return:
On success, value length.
On error:
-1 (either "Cookie:" header is not present at all or the requested
parameter is not found).
-2 (destination buffer is NULL, zero length or too small to hold the
value). */
/* Download data from the remote web server.
host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
port: port number, e.g. 80.
use_ssl: wether to use SSL connection.
error_buffer, error_buffer_size: error message placeholder.
request_fmt,...: HTTP request.
Return:
On success, valid pointer to the new connection, suitable for httplib_read().
On error, NULL. error_buffer contains error message.
Example:
char ebuf[100];
struct lh_con_t *conn;
conn = httplib_download("google.com", 80, 0, ebuf, sizeof(ebuf),
"%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
*/
/* Close the connection opened by httplib_download(). */
/* This structure contains callback functions for handling form fields.
It is used as an argument to httplib_handle_form_request. */
struct httplib_form_data_handler {
/* This callback function is called, if a new field has been found.
* The return value of this callback is used to define how the field
* should be processed.
*
* Parameters:
* key: Name of the field ("name" property of the HTML input field).
* filename: Name of a file to upload, at the client computer.
* Only set for input fields of type "file", otherwise NULL.
* path: Output parameter: File name (incl. path) to store the file
* at the server computer. Only used if FORM_FIELD_STORAGE_STORE
* is returned by this callback. Existing files will be
* overwritten.
* pathlen: Length of the buffer for path.
* user_data: Value of the member user_data of httplib_form_data_handler
*
* Return value:
* The callback must return the intended storage for this field
* (See FORM_FIELD_STORAGE_*).
*/
int (*field_found)( const char *key, const char *filename, char *path, size_t pathlen, void *user_data );
/* If the "field_found" callback returned FORM_FIELD_STORAGE_GET,
* this callback will receive the field data.
*
* Parameters:
* key: Name of the field ("name" property of the HTML input field).
* value: Value of the input field.
* user_data: Value of the member user_data of httplib_form_data_handler
*
* Return value:
* TODO: Needs to be defined.
*/
int (*field_get)( const char *key, const char *value, size_t valuelen, void *user_data );
/* If the "field_found" callback returned FORM_FIELD_STORAGE_STORE,
* the data will be stored into a file. If the file has been written
* successfully, this callback will be called. This callback will
* not be called for only partially uploaded files. The
* httplib_handle_form_request function will either store the file completely
* and call this callback, or it will remove any partial content and
* not call this callback function.
*
* Parameters:
* path: Path of the file stored at the server.
* file_size: Size of the stored file in bytes.
* user_data: Value of the member user_data of httplib_form_data_handler
*
* Return value:
* TODO: Needs to be defined.
*/
int (*field_store)( const char *path, int64_t file_size, void *user_data );
/* User supplied argument, passed to all callback functions. */
void * user_data;
};
typedef int (*httplib_request_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
typedef int (*httplib_authorization_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
typedef int (*httplib_websocket_connect_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
typedef void (*httplib_websocket_ready_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
typedef int (*httplib_websocket_data_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int, char *buffer, size_t buflen, void *cbdata );
typedef void (*httplib_websocket_close_handler)( const struct lh_ctx_t *ctx, struct lh_con_t *conn, void *cbdata );
/*
* Return values definition for the "field_found" callback in
* httplib_form_data_handler.
*/
enum {
FORM_FIELD_STORAGE_SKIP = 0x00, /* Skip this field (neither get nor store it). Continue with the next field. */
FORM_FIELD_STORAGE_GET = 0x01, /* Get the field value. */
FORM_FIELD_STORAGE_STORE = 0x02, /* Store the field value into a file. */
FORM_FIELD_STORAGE_ABORT = 0x10 /* Stop parsing this request. Skip the remaining fields */
};
/* Process form data.
* Returns the number of fields handled, or < 0 in case of an error.
* Note: It is possible that several fields are already handled successfully
* (e.g., stored into files), before the request handling is stopped with an
* 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
* no longer required. */
#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 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);
/* URL-decode input buffer into destination buffer.
0-terminate the destination buffer.
form-url-encoded data differs from URI encoding in a way that it
uses '+' as character for space, see RFC 1866 section 8.2.1
http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
Return: length of the decoded data, or -1 if dst buffer is too small. */
typedef LIBHTTP_THREAD_TYPE (LIBHTTP_THREAD_CALLING_CONV *httplib_thread_func_t)(void *arg);
struct httplib_client_options {
const char *host;
@@ -580,18 +350,6 @@ struct httplib_client_options {
/* TODO: add more data */
};
enum debug_level_t {
DEBUG_LEVEL_NONE,
DEBUG_LEVEL_CRASH,
DEBUG_LEVEL_ERROR,
DEBUG_LEVEL_WARNING,
DEBUG_LEVEL_INFO
};
enum { TIMEOUT_INFINITE = -1 };
@@ -630,7 +388,7 @@ LIBHTTP_API uint64_t httplib_get_random( void );
LIBHTTP_API const struct lh_rqi_t * httplib_get_request_info( const struct lh_con_t *conn );
LIBHTTP_API int httplib_get_response( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int timeout );
LIBHTTP_API const char * httplib_get_response_code_text( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int response_code );
LIBHTTP_API int httplib_get_server_ports( const struct lh_ctx_t *ctx, int size, struct httplib_server_ports *ports );
LIBHTTP_API int httplib_get_server_ports( const struct lh_ctx_t *ctx, int size, struct lh_slp_t *ports );
LIBHTTP_API void * httplib_get_user_connection_data( const struct lh_con_t *conn );
LIBHTTP_API void * httplib_get_user_data( const struct lh_ctx_t *ctx );
LIBHTTP_API int httplib_get_var( const char *data, size_t data_len, const char *var_name, char *dst, size_t dst_len );
@@ -675,6 +433,7 @@ LIBHTTP_API void httplib_set_request_handler( struct lh_ctx_t *ctx, const char
LIBHTTP_API void httplib_set_user_connection_data( struct lh_con_t *conn, void *data );
LIBHTTP_API void httplib_set_websocket_handler( struct lh_ctx_t *ctx, const char *uri, httplib_websocket_connect_handler connect_handler, httplib_websocket_ready_handler ready_handler, httplib_websocket_data_handler data_handler, httplib_websocket_close_handler close_handler, void *cbdata );
LIBHTTP_API struct lh_ctx_t * httplib_start( const struct lh_clb_t *callbacks, void *user_data, const struct lh_opt_t *options );
LIBHTTP_API int httplib_start_thread( httplib_thread_func_t func, void *param );
LIBHTTP_API void httplib_stop( struct lh_ctx_t *ctx );
LIBHTTP_API int64_t httplib_store_body( const struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *path );
LIBHTTP_API int httplib_strcasecmp( const char *s1, const char *s2 );

View File

@@ -27,7 +27,7 @@
#include "httplib_main.h"
int httplib_get_server_ports( const struct lh_ctx_t *ctx, int size, struct httplib_server_ports *ports ) {
int httplib_get_server_ports( const struct lh_ctx_t *ctx, int size, struct lh_slp_t *ports ) {
int i;
int cnt;