mirror of
https://github.com/lammertb/libhttp.git
synced 2025-12-22 04:02:04 +03:00
Replacement for static_assert
This commit is contained in:
108
src/civetweb.c
108
src/civetweb.c
@@ -58,6 +58,26 @@
|
||||
#pragma warning(disable : 4204)
|
||||
#endif
|
||||
|
||||
/* This code uses static_assert to check some conditions.
|
||||
* Unfortunately some compilers still do not support it, so we have a
|
||||
* replacement function here. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
|
||||
#define mg_static_assert static_assert
|
||||
#else
|
||||
char static_assert_replacement[1];
|
||||
#define mg_static_assert(cond, txt) \
|
||||
{ extern char static_assert_replacement[(cond) ? 1 : -1]; }
|
||||
#endif
|
||||
|
||||
mg_static_assert(1, "static assert has to be available");
|
||||
mg_static_assert(sizeof(int) == 4 || sizeof(int) == 8,
|
||||
"int data type size check");
|
||||
mg_static_assert(sizeof(void *) == 4 || sizeof(void *) == 8,
|
||||
"pointer data type size check");
|
||||
mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check");
|
||||
/* mg_static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t data
|
||||
* type size check"); */
|
||||
|
||||
/* DTL -- including winsock2.h works better if lean and mean */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -150,16 +170,25 @@ int clock_gettime(int clk_id, struct timespec *t) {
|
||||
#define MAX_WORKER_THREADS (1024 * 64)
|
||||
#endif
|
||||
|
||||
mg_static_assert(MAX_WORKER_THREADS >= 1,
|
||||
"worker threads must be a positive number");
|
||||
|
||||
#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
|
||||
#include <windows.h>
|
||||
#include <winsock2.h> /* DTL add for SO_EXCLUSIVE */
|
||||
|
||||
typedef const char *SOCK_OPT_TYPE;
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#if !defined(PATH_MAX)
|
||||
#define PATH_MAX (MAX_PATH)
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_MAX)
|
||||
#define PATH_MAX (4096)
|
||||
#endif
|
||||
|
||||
mg_static_assert(PATH_MAX >= 1, "path length must be a positive number");
|
||||
|
||||
#ifndef _IN_PORT_T
|
||||
#ifndef in_port_t
|
||||
#define in_port_t u_short
|
||||
@@ -189,7 +218,7 @@ typedef long off_t;
|
||||
/* Visual Studio 6 does not know __func__ or __FUNCTION__
|
||||
* The rest of MS compilers use __FUNCTION__, not C99 __func__
|
||||
* Also use _strtoui64 on modern M$ compilers */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
#define STRX(x) #x
|
||||
#define STR(x) STRX(x)
|
||||
#define __func__ __FILE__ ":" STR(__LINE__)
|
||||
@@ -318,7 +347,7 @@ struct pollfd {
|
||||
#endif
|
||||
|
||||
/* Mark required libraries */
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#endif
|
||||
|
||||
@@ -426,9 +455,14 @@ void *pthread_getspecific(pthread_key_t key) { return TlsGetValue(key); }
|
||||
#define CGI_ENVIRONMENT_SIZE (4096)
|
||||
#define MAX_CGI_ENVIR_VARS (64)
|
||||
#define MG_BUF_LEN (8192)
|
||||
|
||||
#ifndef MAX_REQUEST_SIZE
|
||||
#define MAX_REQUEST_SIZE (16384)
|
||||
#endif
|
||||
|
||||
mg_static_assert(MAX_REQUEST_SIZE >= 256,
|
||||
"request size length must be a positive number");
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
#if !defined(DEBUG_TRACE)
|
||||
@@ -626,10 +660,6 @@ typedef int socklen_t;
|
||||
#define SOMAXCONN (100)
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_MAX)
|
||||
#define PATH_MAX (4096)
|
||||
#endif
|
||||
|
||||
/* Size of the accepted socket queue */
|
||||
#if !defined(MGSQLEN)
|
||||
#define MGSQLEN (20)
|
||||
@@ -992,8 +1022,8 @@ static int is_websocket_protocol(const struct mg_connection *conn);
|
||||
int mg_atomic_inc(volatile int *addr) {
|
||||
int ret;
|
||||
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||
/* Depending on the SDK, this function uses either
|
||||
* (volatile unsigned int *) or (volatile LONG *),
|
||||
/* Depending on the SDK, this function uses either
|
||||
* (volatile unsigned int *) or (volatile LONG *),
|
||||
* so whatever you use, the other SDK is likely to raise a warning. */
|
||||
ret = InterlockedIncrement((volatile unsigned int *)addr);
|
||||
#elif defined(__GNUC__)
|
||||
@@ -1007,8 +1037,8 @@ int mg_atomic_inc(volatile int *addr) {
|
||||
int mg_atomic_dec(volatile int *addr) {
|
||||
int ret;
|
||||
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||
/* Depending on the SDK, this function uses either
|
||||
* (volatile unsigned int *) or (volatile LONG *),
|
||||
/* Depending on the SDK, this function uses either
|
||||
* (volatile unsigned int *) or (volatile LONG *),
|
||||
* so whatever you use, the other SDK is likely to raise a warning. */
|
||||
ret = InterlockedDecrement((volatile unsigned int *)addr);
|
||||
#elif defined(__GNUC__)
|
||||
@@ -1058,8 +1088,8 @@ void mg_set_thread_name(const char *name) {
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {}
|
||||
#elif defined(__MINGW32__)
|
||||
/* No option known to set thread name for MinGW */
|
||||
;
|
||||
/* No option known to set thread name for MinGW */
|
||||
;
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
/* Linux */
|
||||
@@ -2684,8 +2714,8 @@ static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len) {
|
||||
if (fp != NULL) {
|
||||
/* Use read() instead of fread(), because if we're reading from the
|
||||
* CGI pipe, fread() may block until IO buffer is filled up. We
|
||||
* cannot afford to block and must pass all read bytes immediately
|
||||
* to the client. */
|
||||
* cannot afford to block and must pass all read bytes immediately
|
||||
* to the client. */
|
||||
nread = (int)read(fileno(fp), buf, (size_t)len);
|
||||
#ifndef NO_SSL
|
||||
} else if (conn->ssl != NULL) {
|
||||
@@ -3320,15 +3350,15 @@ interpret_uri(struct mg_connection *conn, /* in: request */
|
||||
#endif
|
||||
) {
|
||||
/* The request addresses a CGI script or a Lua script. The URI
|
||||
* corresponds to the script itself (like /path/script.cgi),
|
||||
* and there is no additional resource path
|
||||
* (like /path/script.cgi/something).
|
||||
* corresponds to the script itself (like /path/script.cgi),
|
||||
* and there is no additional resource path
|
||||
* (like /path/script.cgi/something).
|
||||
* Requests that modify (replace or delete) a resource, like
|
||||
* PUT and DELETE requests, should replace/delete the script
|
||||
* file.
|
||||
* PUT and DELETE requests, should replace/delete the script
|
||||
* file.
|
||||
* Requests that read or write from/to a resource, like GET and
|
||||
* POST requests, should call the script and return the
|
||||
* generated response. */
|
||||
* generated response. */
|
||||
*is_script_ressource = !*is_put_or_delete_request;
|
||||
}
|
||||
return;
|
||||
@@ -3798,7 +3828,8 @@ static int parse_auth_header(struct mg_connection *conn, char *buf,
|
||||
/* Convert the nonce from the client to a number and check it. */
|
||||
/* Server side nonce check is valuable in all situations but one: if the
|
||||
* server restarts frequently,
|
||||
* but the client should not see that, so the server should accept nonces from
|
||||
* but the client should not see that, so the server should accept nonces
|
||||
* from
|
||||
* previous starts. */
|
||||
if (ah->nonce == NULL) {
|
||||
return 0;
|
||||
@@ -6462,20 +6493,20 @@ int mg_upload(struct mg_connection *conn, const char *destination_dir) {
|
||||
struct mg_request_info part_request_info;
|
||||
|
||||
/* Request looks like this:
|
||||
*
|
||||
*
|
||||
* POST /upload HTTP/1.1
|
||||
* Host: 127.0.0.1:8080
|
||||
* Content-Length: 244894
|
||||
* Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryRVr
|
||||
*
|
||||
*
|
||||
* ------WebKitFormBoundaryRVr
|
||||
* Content-Disposition: form-data; name="file"; filename="accum.png"
|
||||
* Content-Type: image/png
|
||||
*
|
||||
*
|
||||
* <89>PNG
|
||||
* <PNG DATA>
|
||||
* ------WebKitFormBoundaryRVr */
|
||||
|
||||
|
||||
/* Extract boundary string from the Content-Type header */
|
||||
if ((content_type_header = mg_get_header(conn, "Content-Type")) == NULL ||
|
||||
(boundary_start = mg_strcasestr(content_type_header, "boundary=")) ==
|
||||
@@ -7004,8 +7035,8 @@ static void handle_request(struct mg_connection *conn) {
|
||||
&ws_data_handler, &ws_close_handler,
|
||||
&callback_data)) {
|
||||
/* 5.2.1. A callback will handle this request. All requests handled
|
||||
* by a callback have to be considered as requests to a script
|
||||
* resource. */
|
||||
* by a callback have to be considered as requests to a script
|
||||
* resource. */
|
||||
is_callback_resource = 1;
|
||||
is_script_resource = 1;
|
||||
is_put_or_delete_request = is_put_or_delete_method(conn);
|
||||
@@ -7013,7 +7044,7 @@ static void handle_request(struct mg_connection *conn) {
|
||||
no_callback_resource:
|
||||
/* 5.2.2. No callback is responsible for this request. The URI
|
||||
* addresses a file based resource (static content or Lua/cgi
|
||||
* scripts in the file system). */
|
||||
* scripts in the file system). */
|
||||
is_callback_resource = 0;
|
||||
interpret_uri(conn, path, sizeof(path), &file, &is_script_resource,
|
||||
&is_websocket_request, &is_put_or_delete_request);
|
||||
@@ -8305,8 +8336,8 @@ static void process_new_connection(struct mg_connection *conn) {
|
||||
do {
|
||||
if (!getreq(conn, ebuf, sizeof(ebuf), &reqerr)) {
|
||||
/* The request sent by the client could not be understood by
|
||||
* the server, or it was incomplete or a timeout. Send an
|
||||
* error message and close the connection. */
|
||||
* the server, or it was incomplete or a timeout. Send an
|
||||
* error message and close the connection. */
|
||||
if (reqerr > 0) {
|
||||
/*assert(ebuf[0] != '\0');*/
|
||||
send_http_error(conn, reqerr, "%s", ebuf);
|
||||
@@ -8339,7 +8370,8 @@ static void process_new_connection(struct mg_connection *conn) {
|
||||
}
|
||||
|
||||
/* NOTE(lsm): order is important here. should_keep_alive() call is
|
||||
* using parsed request, which will be invalid after memmove's below.
|
||||
* using parsed request, which will be invalid after memmove's
|
||||
* below.
|
||||
* Therefore, memorize should_keep_alive() result now for later use
|
||||
* in loop exit condition. */
|
||||
keep_alive = conn->ctx->stop_flag == 0 && keep_alive_enabled &&
|
||||
@@ -8571,7 +8603,7 @@ static void accept_new_connection(const struct socket *listener,
|
||||
* so the server can exit after 10 seconds if required. */
|
||||
/* TODO: Currently values > 10 s are round up to the next 10 s.
|
||||
* For values like 24 s a socket timeout of 8 or 12 s would be better.
|
||||
*/
|
||||
*/
|
||||
if ((timeout > 0) && (timeout < 10000)) {
|
||||
set_sock_timeout(so.sock, timeout);
|
||||
} else {
|
||||
@@ -8722,7 +8754,7 @@ static void free_context(struct mg_context *ctx) {
|
||||
/* Deallocate config parameters */
|
||||
for (i = 0; i < NUM_OPTIONS; i++) {
|
||||
if (ctx->config[i] != NULL)
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(suppress : 6001)
|
||||
#endif
|
||||
mg_free(ctx->config[i]);
|
||||
@@ -8823,7 +8855,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
|
||||
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||
WSADATA data;
|
||||
WSAStartup(MAKEWORD(2, 2), &data);
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(suppress : 28125)
|
||||
#endif
|
||||
if (!sTlsInit)
|
||||
@@ -8832,9 +8864,9 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
|
||||
|
||||
/* Check if the config_options and the corresponding enum have compatible
|
||||
* sizes. */
|
||||
static_assert(sizeof(config_options) / sizeof(config_options[0]) ==
|
||||
NUM_OPTIONS + 1,
|
||||
"config_options and enum not sync");
|
||||
mg_static_assert((sizeof(config_options) / sizeof(config_options[0])) ==
|
||||
(NUM_OPTIONS + 1),
|
||||
"config_options and enum not sync");
|
||||
|
||||
/* Allocate context and initialize reasonable general case defaults.
|
||||
* TODO(lsm): do proper error handling here. */
|
||||
|
||||
Reference in New Issue
Block a user