Commit 63c19b46 authored by Sergey Lyubka's avatar Sergey Lyubka

Moved to unix file format

parent 1f471e1c
// Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com> // Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
// Copyright (c) 2013 Cesanta Software Limited // Copyright (c) 2013 Cesanta Software Limited
// All rights reserved // All rights reserved
// //
// This library is dual-licensed: you can redistribute it and/or modify // This library is dual-licensed: you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation. For the terms of this // published by the Free Software Foundation. For the terms of this
// license, see <http://www.gnu.org/licenses/>. // license, see <http://www.gnu.org/licenses/>.
// //
// You are free to use this library under the terms of the GNU General // You are free to use this library under the terms of the GNU General
// Public License, but WITHOUT ANY WARRANTY; without even the implied // Public License, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// Alternatively, you can license this library under a commercial // Alternatively, you can license this library under a commercial
// license, as set out in <http://cesanta.com/products.html>. // license, as set out in <http://cesanta.com/products.html>.
#if defined(_WIN32) #if defined(_WIN32)
#undef _UNICODE #undef _UNICODE
#define _MBCS #define _MBCS
#if !defined(_CRT_SECURE_NO_WARNINGS) #if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005 #define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005
#endif #endif
#else #else
#ifdef __linux__ #ifdef __linux__
#define _XOPEN_SOURCE 600 // For flockfile() on Linux #define _XOPEN_SOURCE 600 // For flockfile() on Linux
#endif #endif
#if !defined(_LARGEFILE_SOURCE) #if !defined(_LARGEFILE_SOURCE)
#define _LARGEFILE_SOURCE // Enable 64-bit file offsets #define _LARGEFILE_SOURCE // Enable 64-bit file offsets
#endif #endif
#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++ #define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX #define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
#endif #endif
#if defined (_MSC_VER) #if defined (_MSC_VER)
// conditional expression is constant: introduced by FD_SET(..) // conditional expression is constant: introduced by FD_SET(..)
#pragma warning (disable : 4127) #pragma warning (disable : 4127)
// non-constant aggregate initializer: issued due to missing C99 support // non-constant aggregate initializer: issued due to missing C99 support
#pragma warning (disable : 4204) #pragma warning (disable : 4204)
#endif #endif
// Disable WIN32_LEAN_AND_MEAN. // Disable WIN32_LEAN_AND_MEAN.
// This makes windows.h always include winsock2.h // This makes windows.h always include winsock2.h
#ifdef WIN32_LEAN_AND_MEAN #ifdef WIN32_LEAN_AND_MEAN
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#endif #endif
#if defined(__SYMBIAN32__) #if defined(__SYMBIAN32__)
#define NO_SSL // SSL is not supported #define NO_SSL // SSL is not supported
#define NO_CGI // CGI is not supported #define NO_CGI // CGI is not supported
#define PATH_MAX FILENAME_MAX #define PATH_MAX FILENAME_MAX
#endif // __SYMBIAN32__ #endif // __SYMBIAN32__
#ifndef _WIN32_WCE // Some ANSI #includes are not available on Windows CE #ifndef _WIN32_WCE // Some ANSI #includes are not available on Windows CE
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h> #include <fcntl.h>
#endif // !_WIN32_WCE #endif // !_WIN32_WCE
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#if defined(_WIN32) && !defined(__SYMBIAN32__) // Windows specific #if defined(_WIN32) && !defined(__SYMBIAN32__) // Windows specific
#undef _WIN32_WINNT #undef _WIN32_WINNT
#define _WIN32_WINNT 0x0400 // To make it link in VS2005 #define _WIN32_WINNT 0x0400 // To make it link in VS2005
#include <windows.h> #include <windows.h>
#ifndef PATH_MAX #ifndef PATH_MAX
#define PATH_MAX MAX_PATH #define PATH_MAX MAX_PATH
#endif #endif
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
#include <process.h> #include <process.h>
#include <direct.h> #include <direct.h>
#include <io.h> #include <io.h>
#else // _WIN32_WCE #else // _WIN32_WCE
#define NO_CGI // WinCE has no pipes #define NO_CGI // WinCE has no pipes
typedef long off_t; typedef long off_t;
#define errno GetLastError() #define errno GetLastError()
#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10) #define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
#endif // _WIN32_WCE #endif // _WIN32_WCE
#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \ #define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
((uint64_t)((uint32_t)(hi))) << 32)) ((uint64_t)((uint32_t)(hi))) << 32))
#define RATE_DIFF 10000000 // 100 nsecs #define RATE_DIFF 10000000 // 100 nsecs
#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de) #define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
#define SYS2UNIX_TIME(lo, hi) \ #define SYS2UNIX_TIME(lo, hi) \
(time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF) (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
// Visual Studio 6 does not know __func__ or __FUNCTION__ // Visual Studio 6 does not know __func__ or __FUNCTION__
// The rest of MS compilers use __FUNCTION__, not C99 __func__ // The rest of MS compilers use __FUNCTION__, not C99 __func__
// Also use _strtoui64 on modern M$ compilers // 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 STRX(x) #x
#define STR(x) STRX(x) #define STR(x) STRX(x)
#define __func__ __FILE__ ":" STR(__LINE__) #define __func__ __FILE__ ":" STR(__LINE__)
#define strtoull(x, y, z) (unsigned __int64) _atoi64(x) #define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
#define strtoll(x, y, z) _atoi64(x) #define strtoll(x, y, z) _atoi64(x)
#else #else
#define __func__ __FUNCTION__ #define __func__ __FUNCTION__
#define strtoull(x, y, z) _strtoui64(x, y, z) #define strtoull(x, y, z) _strtoui64(x, y, z)
#define strtoll(x, y, z) _strtoi64(x, y, z) #define strtoll(x, y, z) _strtoi64(x, y, z)
#endif // _MSC_VER #endif // _MSC_VER
#define ERRNO GetLastError() #define ERRNO GetLastError()
#define NO_SOCKLEN_T #define NO_SOCKLEN_T
#define SSL_LIB "ssleay32.dll" #define SSL_LIB "ssleay32.dll"
#define CRYPTO_LIB "libeay32.dll" #define CRYPTO_LIB "libeay32.dll"
#define O_NONBLOCK 0 #define O_NONBLOCK 0
#if !defined(EWOULDBLOCK) #if !defined(EWOULDBLOCK)
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
#endif // !EWOULDBLOCK #endif // !EWOULDBLOCK
#define _POSIX_ #define _POSIX_
#define INT64_FMT "I64d" #define INT64_FMT "I64d"
#define WINCDECL __cdecl #define WINCDECL __cdecl
#define SHUT_WR 1 #define SHUT_WR 1
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#define mg_sleep(x) Sleep(x) #define mg_sleep(x) Sleep(x)
#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY) #define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
#ifndef popen #ifndef popen
#define popen(x, y) _popen(x, y) #define popen(x, y) _popen(x, y)
#endif #endif
#ifndef pclose #ifndef pclose
#define pclose(x) _pclose(x) #define pclose(x) _pclose(x)
#endif #endif
#define close(x) _close(x) #define close(x) _close(x)
#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y)) #define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
#define RTLD_LAZY 0 #define RTLD_LAZY 0
#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z)) #define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
#define fdopen(x, y) _fdopen((x), (y)) #define fdopen(x, y) _fdopen((x), (y))
#define write(x, y, z) _write((x), (y), (unsigned) z) #define write(x, y, z) _write((x), (y), (unsigned) z)
#define read(x, y, z) _read((x), (y), (unsigned) z) #define read(x, y, z) _read((x), (y), (unsigned) z)
#define flockfile(x) #define flockfile(x)
#define funlockfile(x) #define funlockfile(x)
#define sleep(x) Sleep((x) * 1000) #define sleep(x) Sleep((x) * 1000)
#define rmdir(x) _rmdir(x) #define rmdir(x) _rmdir(x)
#if !defined(va_copy) #if !defined(va_copy)
#define va_copy(x, y) x = y #define va_copy(x, y) x = y
#endif // !va_copy MINGW #defines va_copy #endif // !va_copy MINGW #defines va_copy
#if !defined(fileno) #if !defined(fileno)
#define fileno(x) _fileno(x) #define fileno(x) _fileno(x)
#endif // !fileno MINGW #defines fileno #endif // !fileno MINGW #defines fileno
typedef HANDLE pthread_mutex_t; typedef HANDLE pthread_mutex_t;
typedef struct {HANDLE signal, broadcast;} pthread_cond_t; typedef struct {HANDLE signal, broadcast;} pthread_cond_t;
typedef DWORD pthread_t; typedef DWORD pthread_t;
#define pid_t HANDLE // MINGW typedefs pid_t to int. Using #define here. #define pid_t HANDLE // MINGW typedefs pid_t to int. Using #define here.
static int pthread_mutex_lock(pthread_mutex_t *); static int pthread_mutex_lock(pthread_mutex_t *);
static int pthread_mutex_unlock(pthread_mutex_t *); static int pthread_mutex_unlock(pthread_mutex_t *);
static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len); static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
#if defined(HAVE_STDINT) #if defined(HAVE_STDINT)
#include <stdint.h> #include <stdint.h>
#else #else
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
typedef unsigned short uint16_t; typedef unsigned short uint16_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
typedef __int64 int64_t; typedef __int64 int64_t;
#define INT64_MAX 9223372036854775807 #define INT64_MAX 9223372036854775807
#endif // HAVE_STDINT #endif // HAVE_STDINT
// POSIX dirent interface // POSIX dirent interface
struct dirent { struct dirent {
char d_name[PATH_MAX]; char d_name[PATH_MAX];
}; };
typedef struct DIR { typedef struct DIR {
HANDLE handle; HANDLE handle;
WIN32_FIND_DATAW info; WIN32_FIND_DATAW info;
struct dirent result; struct dirent result;
} DIR; } DIR;
#ifndef HAVE_POLL #ifndef HAVE_POLL
struct pollfd { struct pollfd {
SOCKET fd; SOCKET fd;
short events; short events;
short revents; short revents;
}; };
#define POLLIN 1 #define POLLIN 1
#endif #endif
// Mark required libraries // Mark required libraries
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "Ws2_32.lib")
#endif #endif
#else // UNIX specific #else // UNIX specific
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdint.h> #include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <netdb.h> #include <netdb.h>
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#if !defined(NO_SSL_DL) && !defined(NO_SSL) #if !defined(NO_SSL_DL) && !defined(NO_SSL)
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <pthread.h> #include <pthread.h>
#if defined(__MACH__) #if defined(__MACH__)
#define SSL_LIB "libssl.dylib" #define SSL_LIB "libssl.dylib"
#define CRYPTO_LIB "libcrypto.dylib" #define CRYPTO_LIB "libcrypto.dylib"
#else #else
#if !defined(SSL_LIB) #if !defined(SSL_LIB)
#define SSL_LIB "libssl.so" #define SSL_LIB "libssl.so"
#endif #endif
#if !defined(CRYPTO_LIB) #if !defined(CRYPTO_LIB)
#define CRYPTO_LIB "libcrypto.so" #define CRYPTO_LIB "libcrypto.so"
#endif #endif
#endif #endif
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 #define O_BINARY 0
#endif // O_BINARY #endif // O_BINARY
#define closesocket(a) close(a) #define closesocket(a) close(a)
#define mg_mkdir(x, y) mkdir(x, y) #define mg_mkdir(x, y) mkdir(x, y)
#define mg_remove(x) remove(x) #define mg_remove(x) remove(x)
#define mg_sleep(x) usleep((x) * 1000) #define mg_sleep(x) usleep((x) * 1000)
#define ERRNO errno #define ERRNO errno
#define INVALID_SOCKET (-1) #define INVALID_SOCKET (-1)
#define INT64_FMT PRId64 #define INT64_FMT PRId64
typedef int SOCKET; typedef int SOCKET;
#define WINCDECL #define WINCDECL
#endif // End of Windows and UNIX specific includes #endif // End of Windows and UNIX specific includes
#include "mongoose.h" #include "mongoose.h"
#define MONGOOSE_VERSION "4.2" #define MONGOOSE_VERSION "4.2"
#define PASSWORDS_FILE_NAME ".htpasswd" #define PASSWORDS_FILE_NAME ".htpasswd"
#define CGI_ENVIRONMENT_SIZE 4096 #define CGI_ENVIRONMENT_SIZE 4096
#define MAX_CGI_ENVIR_VARS 64 #define MAX_CGI_ENVIR_VARS 64
#define MG_BUF_LEN 8192 #define MG_BUF_LEN 8192
#define MAX_REQUEST_SIZE 16384 #define MAX_REQUEST_SIZE 16384
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
#undef DEBUG_TRACE #undef DEBUG_TRACE
#define DEBUG_TRACE(x) #define DEBUG_TRACE(x)
#else #else
#if defined(DEBUG) #if defined(DEBUG)
#define DEBUG_TRACE(x) do { \ #define DEBUG_TRACE(x) do { \
flockfile(stdout); \ flockfile(stdout); \
printf("*** %lu.%p.%s.%d: ", \ printf("*** %lu.%p.%s.%d: ", \
(unsigned long) time(NULL), (void *) pthread_self(), \ (unsigned long) time(NULL), (void *) pthread_self(), \
__func__, __LINE__); \ __func__, __LINE__); \
printf x; \ printf x; \
putchar('\n'); \ putchar('\n'); \
fflush(stdout); \ fflush(stdout); \
funlockfile(stdout); \ funlockfile(stdout); \
} while (0) } while (0)
#else #else
#define DEBUG_TRACE(x) #define DEBUG_TRACE(x)
#endif // DEBUG #endif // DEBUG
#endif // DEBUG_TRACE #endif // DEBUG_TRACE
// Darwin prior to 7.0 and Win32 do not have socklen_t // Darwin prior to 7.0 and Win32 do not have socklen_t
#ifdef NO_SOCKLEN_T #ifdef NO_SOCKLEN_T
typedef int socklen_t; typedef int socklen_t;
#endif // NO_SOCKLEN_T #endif // NO_SOCKLEN_T
#define _DARWIN_UNLIMITED_SELECT #define _DARWIN_UNLIMITED_SELECT
#define IP_ADDR_STR_LEN 50 // IPv6 hex string is 46 chars #define IP_ADDR_STR_LEN 50 // IPv6 hex string is 46 chars
#if !defined(MSG_NOSIGNAL) #if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0 #define MSG_NOSIGNAL 0
#endif #endif
#if !defined(SOMAXCONN) #if !defined(SOMAXCONN)
#define SOMAXCONN 100 #define SOMAXCONN 100
#endif #endif
#if !defined(PATH_MAX) #if !defined(PATH_MAX)
#define PATH_MAX 4096 #define PATH_MAX 4096
#endif #endif
// Size of the accepted socket queue // Size of the accepted socket queue
#if !defined(MGSQLEN) #if !defined(MGSQLEN)
#define MGSQLEN 20 #define MGSQLEN 20
#endif #endif
// Extra HTTP headers to send in every static file reply // Extra HTTP headers to send in every static file reply
#if !defined(EXTRA_HTTP_HEADERS) #if !defined(EXTRA_HTTP_HEADERS)
#define EXTRA_HTTP_HEADERS "" #define EXTRA_HTTP_HEADERS ""
#endif #endif
static const char *http_500_error = "Internal Server Error"; static const char *http_500_error = "Internal Server Error";
#if defined(NO_SSL_DL) #if defined(NO_SSL_DL)
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#else #else
// SSL loaded dynamically from DLL. // SSL loaded dynamically from DLL.
// I put the prototypes here to be independent from OpenSSL source installation. // I put the prototypes here to be independent from OpenSSL source installation.
typedef struct ssl_st SSL; typedef struct ssl_st SSL;
typedef struct ssl_method_st SSL_METHOD; typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_ctx_st SSL_CTX; typedef struct ssl_ctx_st SSL_CTX;
struct ssl_func { struct ssl_func {
const char *name; // SSL function name const char *name; // SSL function name
void (*ptr)(void); // Function pointer void (*ptr)(void); // Function pointer
}; };
static struct ssl_func ssl_sw[]; static struct ssl_func ssl_sw[];
#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr) #define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr) #define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr) #define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr) #define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr) #define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr) #define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr) #define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr) #define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr) #define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr) #define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr) #define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \ #define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
const char *, int)) ssl_sw[11].ptr) const char *, int)) ssl_sw[11].ptr)
#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \ #define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
const char *, int)) ssl_sw[12].ptr) const char *, int)) ssl_sw[12].ptr)
#define SSL_CTX_set_default_passwd_cb \ #define SSL_CTX_set_default_passwd_cb \
(* (void (*)(SSL_CTX *, mg_event_handler_t)) ssl_sw[13].ptr) (* (void (*)(SSL_CTX *, mg_event_handler_t)) ssl_sw[13].ptr)
#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr) #define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr) #define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
#define SSL_CTX_use_certificate_chain_file \ #define SSL_CTX_use_certificate_chain_file \
(* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr) (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr) #define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr) #define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr) #define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr) #define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr) #define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
#define CRYPTO_set_locking_callback \ #define CRYPTO_set_locking_callback \
(* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr) (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
#define CRYPTO_set_id_callback \ #define CRYPTO_set_id_callback \
(* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr) (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr) #define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr) #define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
#endif // NO_SSL_DL #endif // NO_SSL_DL
// Unified socket address. For IPv6 support, add IPv6 address structure // Unified socket address. For IPv6 support, add IPv6 address structure
// in the union u. // in the union u.
union usa { union usa {
struct sockaddr sa; struct sockaddr sa;
struct sockaddr_in sin; struct sockaddr_in sin;
#if defined(USE_IPV6) #if defined(USE_IPV6)
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
#endif #endif
}; };
// Describes a string (chunk of memory). // Describes a string (chunk of memory).
struct vec { struct vec {
const char *ptr; const char *ptr;
size_t len; size_t len;
}; };
struct file { struct file {
int is_directory; int is_directory;
time_t modification_time; time_t modification_time;
int64_t size; int64_t size;
// set to 1 if the content is gzipped // set to 1 if the content is gzipped
// in which case we need a content-encoding: gzip header // in which case we need a content-encoding: gzip header
int gzipped; int gzipped;
}; };
#define STRUCT_FILE_INITIALIZER { 0, 0, 0, 0 } #define STRUCT_FILE_INITIALIZER { 0, 0, 0, 0 }
// Describes listening socket, or socket which was accept()-ed by the master // Describes listening socket, or socket which was accept()-ed by the master
// thread and queued for future handling by the worker thread. // thread and queued for future handling by the worker thread.
struct socket { struct socket {
SOCKET sock; // Listening socket SOCKET sock; // Listening socket
union usa lsa; // Local socket address union usa lsa; // Local socket address
union usa rsa; // Remote socket address union usa rsa; // Remote socket address
unsigned is_ssl:1; // Is port SSL-ed unsigned is_ssl:1; // Is port SSL-ed
unsigned ssl_redir:1; // Is port supposed to redirect everything to SSL port unsigned ssl_redir:1; // Is port supposed to redirect everything to SSL port
}; };
// NOTE(lsm): this enum shoulds be in sync with the config_options. // NOTE(lsm): this enum shoulds be in sync with the config_options.
enum { enum {
CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER, CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE, PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE, ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST, GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE, EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT, NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
NUM_OPTIONS NUM_OPTIONS
}; };
struct mg_context { struct mg_context {
volatile int stop_flag; // Should we stop event loop volatile int stop_flag; // Should we stop event loop
SSL_CTX *ssl_ctx; // SSL context SSL_CTX *ssl_ctx; // SSL context
char *config[NUM_OPTIONS]; // Mongoose configuration parameters char *config[NUM_OPTIONS]; // Mongoose configuration parameters
mg_event_handler_t event_handler; // User-defined callback function mg_event_handler_t event_handler; // User-defined callback function
void *user_data; // User-defined data void *user_data; // User-defined data
struct socket *listening_sockets; struct socket *listening_sockets;
int num_listening_sockets; int num_listening_sockets;
volatile int num_threads; // Number of threads volatile int num_threads; // Number of threads
pthread_mutex_t mutex; // Protects (max|num)_threads pthread_mutex_t mutex; // Protects (max|num)_threads
pthread_cond_t cond; // Condvar for tracking workers terminations pthread_cond_t cond; // Condvar for tracking workers terminations
struct socket queue[MGSQLEN]; // Accepted sockets struct socket queue[MGSQLEN]; // Accepted sockets
volatile int sq_head; // Head of the socket queue volatile int sq_head; // Head of the socket queue
volatile int sq_tail; // Tail of the socket queue volatile int sq_tail; // Tail of the socket queue
pthread_cond_t sq_full; // Signaled when socket is produced pthread_cond_t sq_full; // Signaled when socket is produced
pthread_cond_t sq_empty; // Signaled when socket is consumed pthread_cond_t sq_empty; // Signaled when socket is consumed
}; };
struct mg_connection { struct mg_connection {
struct mg_request_info request_info; struct mg_request_info request_info;
struct mg_event event; struct mg_event event;
struct mg_context *ctx; struct mg_context *ctx;
SSL *ssl; // SSL descriptor SSL *ssl; // SSL descriptor
SSL_CTX *client_ssl_ctx; // SSL context for client connections SSL_CTX *client_ssl_ctx; // SSL context for client connections
struct socket client; // Connected client struct socket client; // Connected client
time_t birth_time; // Time when request was received time_t birth_time; // Time when request was received
int64_t num_bytes_sent; // Total bytes sent to client int64_t num_bytes_sent; // Total bytes sent to client
int64_t content_len; // Content-Length header value int64_t content_len; // Content-Length header value
int64_t num_bytes_read; // Bytes read from a remote socket int64_t num_bytes_read; // Bytes read from a remote socket
char *buf; // Buffer for received data char *buf; // Buffer for received data
char *path_info; // PATH_INFO part of the URL 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 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
int throttle; // Throttling, bytes/sec. <= 0 means no throttle int throttle; // Throttling, bytes/sec. <= 0 means no throttle
time_t last_throttle_time; // Last time throttled data was sent 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
}; };
// Directory entry // Directory entry
struct de { struct de {
struct mg_connection *conn; struct mg_connection *conn;
char *file_name; char *file_name;
struct file file; struct file file;
}; };
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment