| 
														
															@@ -164,7 +164,7 @@ typedef HANDLE pthread_mutex_t; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 typedef struct { 
														 | 
														
														 | 
														
															 typedef struct { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     HANDLE signal, broadcast; 
														 | 
														
														 | 
														
															     HANDLE signal, broadcast; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } pthread_cond_t; 
														 | 
														
														 | 
														
															 } pthread_cond_t; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-typedef DWORD pthread_t; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+typedef HANDLE 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 *); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -267,7 +267,7 @@ typedef int SOCKET; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #ifdef _WIN32 
														 | 
														
														 | 
														
															 #ifdef _WIN32 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static CRITICAL_SECTION global_log_file_lock; 
														 | 
														
														 | 
														
															 static CRITICAL_SECTION global_log_file_lock; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static pthread_t pthread_self(void) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static DWORD pthread_self(void) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return GetCurrentThreadId(); 
														 | 
														
														 | 
														
															     return GetCurrentThreadId(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -507,6 +507,8 @@ struct mg_request_handler_info { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 struct mg_context { 
														 | 
														
														 | 
														
															 struct mg_context { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     volatile int stop_flag;         // Should we stop event loop 
														 | 
														
														 | 
														
															     volatile int stop_flag;         // Should we stop event loop 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    void *ssllib_dll_handle;        // Store the ssl library handle. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    void *cryptolib_dll_handle;     // Store the crypto library handle. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     SSL_CTX *ssl_ctx;               // SSL context 
														 | 
														
														 | 
														
															     SSL_CTX *ssl_ctx;               // SSL context 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     char *config[NUM_OPTIONS];      // Civetweb configuration parameters 
														 | 
														
														 | 
														
															     char *config[NUM_OPTIONS];      // Civetweb configuration parameters 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_callbacks callbacks;  // User-defined callback function 
														 | 
														
														 | 
														
															     struct mg_callbacks callbacks;  // User-defined callback function 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -524,6 +526,9 @@ struct mg_context { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     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 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    pthread_t masterthreadid;  // The master thread ID. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int workerthreadcount;     // The amount of worker threads. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    pthread_t *workerthreadids;// The worker thread IDs. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // linked list of uri handlers 
														 | 
														
														 | 
														
															     // linked list of uri handlers 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_request_handler_info *request_handlers; 
														 | 
														
														 | 
														
															     struct mg_request_handler_info *request_handlers; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -655,7 +660,7 @@ void mg_cry(struct mg_connection *conn, const char *fmt, ...) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     time_t timestamp; 
														 | 
														
														 | 
														
															     time_t timestamp; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     va_start(ap, fmt); 
														 | 
														
														 | 
														
															     va_start(ap, fmt); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    (void) vsnprintf(buf, sizeof(buf), fmt, ap); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     va_end(ap); 
														 | 
														
														 | 
														
															     va_end(ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Do not lock when getting the callback value, here and below. 
														 | 
														
														 | 
														
															     // Do not lock when getting the callback value, here and below. 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -663,7 +668,7 @@ void mg_cry(struct mg_connection *conn, const char *fmt, ...) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // same way string option can. 
														 | 
														
														 | 
														
															     // same way string option can. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (conn->ctx->callbacks.log_message == NULL || 
														 | 
														
														 | 
														
															     if (conn->ctx->callbacks.log_message == NULL || 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->ctx->callbacks.log_message(conn, buf) == 0) { 
														 | 
														
														 | 
														
															         conn->ctx->callbacks.log_message(conn, buf) == 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fp = conn->ctx == NULL || conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL : 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL : 
														 | 
													
												
											
												
													
														| 
														 | 
														
															              fopen(conn->ctx->config[ERROR_LOG_FILE], "a+"); 
														 | 
														
														 | 
														
															              fopen(conn->ctx->config[ERROR_LOG_FILE], "a+"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (fp != NULL) { 
														 | 
														
														 | 
														
															         if (fp != NULL) { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1341,8 +1346,9 @@ static int poll(struct pollfd *pfd, int n, int milliseconds) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // HAVE_POLL 
														 | 
														
														 | 
														
															 #endif // HAVE_POLL 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static void set_close_on_exec(SOCKET sock) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void set_close_on_exec(SOCKET sock, struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    (void) conn; /* Unused. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0); 
														 | 
														
														 | 
														
															     (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1351,6 +1357,50 @@ int mg_start_thread(mg_thread_func_t f, void *p) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return (long)_beginthread((void (__cdecl *)(void *)) f, 0, p) == -1L ? -1 : 0; 
														 | 
														
														 | 
														
															     return (long)_beginthread((void (__cdecl *)(void *)) f, 0, p) == -1L ? -1 : 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Start a thread storing the thread context. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   pthread_t *threadidptr) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    uintptr_t uip; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    HANDLE threadhandle; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                         NULL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    threadhandle = (HANDLE) uip; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (threadidptr != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        *threadidptr = threadhandle; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    result = (threadhandle == NULL) ? -1 : 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Wait for a thread to finish. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int mg_join_thread(pthread_t threadid) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    DWORD dwevent; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    result = -1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    dwevent = WaitForSingleObject(threadid, INFINITE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (dwevent == WAIT_FAILED) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        int err; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        err = GetLastError(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        DEBUG_TRACE(("WaitForSingleObject() failed, error %d", err)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (dwevent == WAIT_OBJECT_0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            CloseHandle(threadid); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            result = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static HANDLE dlopen(const char *dll_name, int flags) 
														 | 
														
														 | 
														
															 static HANDLE dlopen(const char *dll_name, int flags) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     wchar_t wbuf[PATH_MAX]; 
														 | 
														
														 | 
														
															     wchar_t wbuf[PATH_MAX]; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1359,6 +1409,19 @@ static HANDLE dlopen(const char *dll_name, int flags) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return LoadLibraryW(wbuf); 
														 | 
														
														 | 
														
															     return LoadLibraryW(wbuf); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int dlclose(void *handle) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (FreeLibrary(handle) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        result = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        result = -1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if !defined(NO_CGI) 
														 | 
														
														 | 
														
															 #if !defined(NO_CGI) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #define SIGKILL 0 
														 | 
														
														 | 
														
															 #define SIGKILL 0 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static int kill(pid_t pid, int sig_num) 
														 | 
														
														 | 
														
															 static int kill(pid_t pid, int sig_num) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1473,9 +1536,12 @@ static int mg_stat(struct mg_connection *conn, const char *path, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return filep->membuf != NULL || filep->modification_time != (time_t) 0; 
														 | 
														
														 | 
														
															     return filep->membuf != NULL || filep->modification_time != (time_t) 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static void set_close_on_exec(int fd) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void set_close_on_exec(int fd, struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    fcntl(fd, F_SETFD, FD_CLOEXEC); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+               __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 int mg_start_thread(mg_thread_func_t func, void *param) 
														 | 
														
														 | 
														
															 int mg_start_thread(mg_thread_func_t func, void *param) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1487,14 +1553,48 @@ int mg_start_thread(mg_thread_func_t func, void *param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_attr_init(&attr); 
														 | 
														
														 | 
														
															     (void) pthread_attr_init(&attr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
														 | 
														
														 | 
														
															     (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-#if USE_STACK_SIZE > 1 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#if defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 
														 | 
														
														 | 
														
															     // Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE); 
														 | 
														
														 | 
														
															     (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-#endif 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    result = pthread_create(&thread_id, &attr, func, param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    pthread_attr_destroy(&attr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Start a thread storing the thread context. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int mg_start_thread_with_id(mg_thread_func_t func, void *param, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                   pthread_t *threadidptr) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    pthread_t thread_id; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    pthread_attr_t attr; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    (void) pthread_attr_init(&attr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#if defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    // Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     result = pthread_create(&thread_id, &attr, func, param); 
														 | 
														
														 | 
														
															     result = pthread_create(&thread_id, &attr, func, param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     pthread_attr_destroy(&attr); 
														 | 
														
														 | 
														
															     pthread_attr_destroy(&attr); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (threadidptr != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        *threadidptr = thread_id; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Wait for a thread to finish. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static int mg_join_thread(pthread_t threadid) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    result = pthread_join(threadid, NULL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return result; 
														 | 
														
														 | 
														
															     return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1732,6 +1832,7 @@ static int alloc_vprintf2(char **buf, const char *fmt, va_list ap) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (!*buf) break; 
														 | 
														
														 | 
														
															         if (!*buf) break; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
														
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         len = vsnprintf(*buf, size, fmt, ap_copy); 
														 | 
														
														 | 
														
															         len = vsnprintf(*buf, size, fmt, ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        va_end(ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return len; 
														 | 
														
														 | 
														
															     return len; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1752,24 +1853,29 @@ static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // On second pass, actually print the message. 
														 | 
														
														 | 
														
															     // On second pass, actually print the message. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     va_copy(ap_copy, ap); 
														 | 
														
														 | 
														
															     va_copy(ap_copy, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     len = vsnprintf(NULL, 0, fmt, ap_copy); 
														 | 
														
														 | 
														
															     len = vsnprintf(NULL, 0, fmt, ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    va_end(ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (len < 0) { 
														 | 
														
														 | 
														
															     if (len < 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // C runtime is not standard compliant, vsnprintf() returned -1. 
														 | 
														
														 | 
														
															         // C runtime is not standard compliant, vsnprintf() returned -1. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Switch to alternative code path that uses incremental allocations. 
														 | 
														
														 | 
														
															         // Switch to alternative code path that uses incremental allocations. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
														
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         len = alloc_vprintf2(buf, fmt, ap); 
														 | 
														
														 | 
														
															         len = alloc_vprintf2(buf, fmt, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        va_end(ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if (len > (int) size && 
														 | 
														
														 | 
														
															     } else if (len > (int) size && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                (size = len + 1) > 0 && 
														 | 
														
														 | 
														
															                (size = len + 1) > 0 && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                (*buf = (char *) malloc(size)) == NULL) { 
														 | 
														
														 | 
														
															                (*buf = (char *) malloc(size)) == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         len = -1;  // Allocation failed, mark failure 
														 | 
														
														 | 
														
															         len = -1;  // Allocation failed, mark failure 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
														
														 | 
														
															         va_copy(ap_copy, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        vsnprintf(*buf, size, fmt, ap_copy); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        va_end(ap_copy); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return len; 
														 | 
														
														 | 
														
															     return len; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) 
														 | 
														
														 | 
														
															 int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     char mem[MG_BUF_LEN], *buf = mem; 
														 | 
														
														 | 
														
															     char mem[MG_BUF_LEN], *buf = mem; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1788,8 +1894,13 @@ int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 int mg_printf(struct mg_connection *conn, const char *fmt, ...) 
														 | 
														
														 | 
														
															 int mg_printf(struct mg_connection *conn, const char *fmt, ...) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     va_list ap; 
														 | 
														
														 | 
														
															     va_list ap; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     va_start(ap, fmt); 
														 | 
														
														 | 
														
															     va_start(ap, fmt); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return mg_vprintf(conn, fmt, ap); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    result = mg_vprintf(conn, fmt, ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    va_end(ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return result; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 int mg_url_decode(const char *src, int src_len, char *dst, 
														 | 
														
														 | 
														
															 int mg_url_decode(const char *src, int src_len, char *dst, 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2046,7 +2157,8 @@ static time_t parse_date_string(const char *datetime) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         leap_days = num_leap_years(year) - num_leap_years(1970); 
														 | 
														
														 | 
														
															         leap_days = num_leap_years(year) - num_leap_years(1970); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         year -= 1970; 
														 | 
														
														 | 
														
															         year -= 1970; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         days = year * 365 + days_before_month[month] + (day - 1) + leap_days; 
														 | 
														
														 | 
														
															         days = year * 365 + days_before_month[month] + (day - 1) + leap_days; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        result = days * 24 * 3600 + hour * 3600 + minute * 60 + second; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        result = (time_t) days * 24 * 3600 + (time_t) hour * 3600 + 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                 minute * 60 + second; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return result; 
														 | 
														
														 | 
														
															     return result; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2258,7 +2370,9 @@ static void open_auth_file(struct mg_connection *conn, const char *path, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if (mg_stat(conn, path, &file) && file.is_directory) { 
														 | 
														
														 | 
														
															     } else if (mg_stat(conn, path, &file) && file.is_directory) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_snprintf(conn, name, sizeof(name), "%s%c%s", 
														 | 
														
														 | 
														
															         mg_snprintf(conn, name, sizeof(name), "%s%c%s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                     path, '/', PASSWORDS_FILE_NAME); 
														 | 
														
														 | 
														
															                     path, '/', PASSWORDS_FILE_NAME); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        mg_fopen(conn, name, "r", filep); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (!mg_fopen(conn, name, "r", filep)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Try to find .htpasswd in requested directory. 
														 | 
														
														 | 
														
															         // Try to find .htpasswd in requested directory. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         for (p = path, e = p + strlen(p) - 1; e > p; e--) 
														 | 
														
														 | 
														
															         for (p = path, e = p + strlen(p) - 1; e > p; e--) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2266,7 +2380,9 @@ static void open_auth_file(struct mg_connection *conn, const char *path, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 break; 
														 | 
														
														 | 
														
															                 break; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_snprintf(conn, name, sizeof(name), "%.*s%c%s", 
														 | 
														
														 | 
														
															         mg_snprintf(conn, name, sizeof(name), "%.*s%c%s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                     (int) (e - p), p, '/', PASSWORDS_FILE_NAME); 
														 | 
														
														 | 
														
															                     (int) (e - p), p, '/', PASSWORDS_FILE_NAME); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        mg_fopen(conn, name, "r", filep); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (!mg_fopen(conn, name, "r", filep)) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2510,16 +2626,16 @@ int mg_modify_passwords_file(const char *fname, const char *domain, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     fclose(fp2); 
														 | 
														
														 | 
														
															     fclose(fp2); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Put the temp file in place of real file 
														 | 
														
														 | 
														
															     // Put the temp file in place of real file 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    remove(fname); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    IGNORE_UNUSED_RESULT(remove(fname)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     IGNORE_UNUSED_RESULT(rename(tmp, fname)); 
														 | 
														
														 | 
														
															     IGNORE_UNUSED_RESULT(rename(tmp, fname)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return 1; 
														 | 
														
														 | 
														
															     return 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static SOCKET conn2(const char *host, int port, int use_ssl, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    char *ebuf, size_t ebuf_len) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static SOCKET conn2(struct mg_context *ctx, const char *host, int port, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                    int use_ssl, char *ebuf, size_t ebuf_len) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    struct sockaddr_in sin; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    struct sockaddr_in sain; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct hostent *he; 
														 | 
														
														 | 
														
															     struct hostent *he; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     SOCKET sock = INVALID_SOCKET; 
														 | 
														
														 | 
														
															     SOCKET sock = INVALID_SOCKET; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2533,11 +2649,12 @@ static SOCKET conn2(const char *host, int port, int use_ssl, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
														 | 
														
														 | 
														
															     } else if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         snprintf(ebuf, ebuf_len, "socket(): %s", strerror(ERRNO)); 
														 | 
														
														 | 
														
															         snprintf(ebuf, ebuf_len, "socket(): %s", strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        set_close_on_exec(sock); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sin.sin_family = AF_INET; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sin.sin_port = htons((uint16_t) port); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sin.sin_addr = * (struct in_addr *) he->h_addr_list[0]; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        set_close_on_exec(sock, fc(ctx)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        memset(&sain, '\0', sizeof(sain)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        sain.sin_family = AF_INET; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        sain.sin_port = htons((uint16_t) port); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        sain.sin_addr = * (struct in_addr *) he->h_addr_list[0]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (connect(sock, (struct sockaddr *) &sain, sizeof(sain)) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             snprintf(ebuf, ebuf_len, "connect(%s:%d): %s", 
														 | 
														
														 | 
														
															             snprintf(ebuf, ebuf_len, "connect(%s:%d): %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                      host, port, strerror(ERRNO)); 
														 | 
														
														 | 
														
															                      host, port, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             closesocket(sock); 
														 | 
														
														 | 
														
															             closesocket(sock); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2575,6 +2692,7 @@ int mg_url_encode(const char *src, char *dst, size_t dst_len) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void print_dir_entry(struct de *de) 
														 | 
														
														 | 
														
															 static void print_dir_entry(struct de *de) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     char size[64], mod[64], href[PATH_MAX]; 
														 | 
														
														 | 
														
															     char size[64], mod[64], href[PATH_MAX]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    struct tm *tm; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (de->file.is_directory) { 
														 | 
														
														 | 
														
															     if (de->file.is_directory) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_snprintf(de->conn, size, sizeof(size), "%s", "[DIRECTORY]"); 
														 | 
														
														 | 
														
															         mg_snprintf(de->conn, size, sizeof(size), "%s", "[DIRECTORY]"); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2594,8 +2712,13 @@ static void print_dir_entry(struct de *de) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                         "%.1fG", (double) de->file.size / 1073741824); 
														 | 
														
														 | 
														
															                         "%.1fG", (double) de->file.size / 1073741824); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-             localtime(&de->file.modification_time)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    tm = localtime(&de->file.modification_time); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (tm != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strncpy(mod, "01-Jan-1970 00:00", sizeof(mod)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        mod[sizeof(mod) - 1] = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     mg_url_encode(de->file_name, href, sizeof(href)); 
														 | 
														
														 | 
														
															     mg_url_encode(de->file_name, href, sizeof(href)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     de->conn->num_bytes_sent += mg_printf(de->conn, 
														 | 
														
														 | 
														
															     de->conn->num_bytes_sent += mg_printf(de->conn, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                           "<tr><td><a href=\"%s%s%s\">%s%s</a></td>" 
														 | 
														
														 | 
														
															                                           "<tr><td><a href=\"%s%s%s\">%s%s</a></td>" 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2672,7 +2795,10 @@ static int scan_directory(struct mg_connection *conn, const char *dir, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             // fails. For more details, see 
														 | 
														
														 | 
														
															             // fails. For more details, see 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             // http://code.google.com/p/civetweb/issues/detail?id=79 
														 | 
														
														 | 
														
															             // http://code.google.com/p/civetweb/issues/detail?id=79 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             memset(&de.file, 0, sizeof(de.file)); 
														 | 
														
														 | 
														
															             memset(&de.file, 0, sizeof(de.file)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            mg_stat(conn, path, &de.file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            if (mg_stat(conn, path, &de.file) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                mg_cry(conn, "%s: mg_stat(%s) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                       __func__, path, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															             de.file_name = dp->d_name; 
														 | 
														
														 | 
														
															             de.file_name = dp->d_name; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             cb(&de, data); 
														 | 
														
														 | 
														
															             cb(&de, data); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2709,7 +2835,10 @@ static int remove_directory(struct mg_connection *conn, const char *dir) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             // fails. For more details, see 
														 | 
														
														 | 
														
															             // fails. For more details, see 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             // http://code.google.com/p/civetweb/issues/detail?id=79 
														 | 
														
														 | 
														
															             // http://code.google.com/p/civetweb/issues/detail?id=79 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             memset(&de.file, 0, sizeof(de.file)); 
														 | 
														
														 | 
														
															             memset(&de.file, 0, sizeof(de.file)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            mg_stat(conn, path, &de.file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            if (mg_stat(conn, path, &de.file) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                mg_cry(conn, "%s: mg_stat(%s) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                       __func__, path, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             if(de.file.modification_time) { 
														 | 
														
														 | 
														
															             if(de.file.modification_time) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 if(de.file.is_directory) { 
														 | 
														
														 | 
														
															                 if(de.file.is_directory) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                     remove_directory(conn, path); 
														 | 
														
														 | 
														
															                     remove_directory(conn, path); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2802,13 +2931,15 @@ static void handle_directory_request(struct mg_connection *conn, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                       conn->request_info.uri, "..", "Parent directory", "-", "-"); 
														 | 
														
														 | 
														
															                                       conn->request_info.uri, "..", "Parent directory", "-", "-"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Sort and print directory entries 
														 | 
														
														 | 
														
															     // Sort and print directory entries 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    qsort(data.entries, (size_t) data.num_entries, sizeof(data.entries[0]), 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-          compare_dir_entries); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    for (i = 0; i < data.num_entries; i++) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        print_dir_entry(&data.entries[i]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        free(data.entries[i].file_name); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (data.entries != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        qsort(data.entries, (size_t) data.num_entries, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+              sizeof(data.entries[0]), compare_dir_entries); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        for (i = 0; i < data.num_entries; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            print_dir_entry(&data.entries[i]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            free(data.entries[i].file_name); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        free(data.entries); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    free(data.entries); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     conn->num_bytes_sent += mg_printf(conn, "%s", "</table></body></html>"); 
														 | 
														
														 | 
														
															     conn->num_bytes_sent += mg_printf(conn, "%s", "</table></body></html>"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     conn->status_code = 200; 
														 | 
														
														 | 
														
															     conn->status_code = 200; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2830,7 +2961,10 @@ static void send_file_data(struct mg_connection *conn, struct file *filep, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_write(conn, filep->membuf + offset, (size_t) len); 
														 | 
														
														 | 
														
															         mg_write(conn, filep->membuf + offset, (size_t) len); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if (len > 0 && filep->fp != NULL) { 
														 | 
														
														 | 
														
															     } else if (len > 0 && filep->fp != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fseeko(filep->fp, offset, SEEK_SET); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (fseeko(filep->fp, offset, SEEK_SET) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(conn, "%s: fseeko() failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         while (len > 0) { 
														 | 
														
														 | 
														
															         while (len > 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             // Calculate how much to read from the file in the buffer 
														 | 
														
														 | 
														
															             // Calculate how much to read from the file in the buffer 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             to_read = sizeof(buf); 
														 | 
														
														 | 
														
															             to_read = sizeof(buf); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2862,7 +2996,15 @@ static int parse_range_header(const char *header, int64_t *a, int64_t *b) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void gmt_time_string(char *buf, size_t buf_len, time_t *t) 
														 | 
														
														 | 
														
															 static void gmt_time_string(char *buf, size_t buf_len, time_t *t) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(t)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    struct tm *tm; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    tm = gmtime(t); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (tm != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strncpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        buf[buf_len - 1] = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void construct_etag(char *buf, size_t buf_len, 
														 | 
														
														 | 
														
															 static void construct_etag(char *buf, size_t buf_len, 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2872,11 +3014,16 @@ static void construct_etag(char *buf, size_t buf_len, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															              (unsigned long) filep->modification_time, filep->size); 
														 | 
														
														 | 
														
															              (unsigned long) filep->modification_time, filep->size); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static void fclose_on_exec(struct file *filep) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void fclose_on_exec(struct file *filep, struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (filep != NULL && filep->fp != NULL) { 
														 | 
														
														 | 
														
															     if (filep != NULL && filep->fp != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-#ifndef _WIN32 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fcntl(fileno(filep->fp), F_SETFD, FD_CLOEXEC); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#ifdef _WIN32 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        (void) conn; /* Unused. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (fcntl(fileno(filep->fp), F_SETFD, FD_CLOEXEC) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif 
														 | 
														
														 | 
														
															 #endif 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2913,7 +3060,7 @@ static void handle_file_request(struct mg_connection *conn, const char *path, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         return; 
														 | 
														
														 | 
														
															         return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    fclose_on_exec(filep); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    fclose_on_exec(filep, conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // If Range: header specified, act accordingly 
														 | 
														
														 | 
														
															     // If Range: header specified, act accordingly 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     r1 = r2 = 0; 
														 | 
														
														 | 
														
															     r1 = r2 = 0; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -2921,9 +3068,10 @@ static void handle_file_request(struct mg_connection *conn, const char *path, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (hdr != NULL && (n = parse_range_header(hdr, &r1, &r2)) > 0 && 
														 | 
														
														 | 
														
															     if (hdr != NULL && (n = parse_range_header(hdr, &r1, &r2)) > 0 && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         r1 >= 0 && r2 >= 0) { 
														 | 
														
														 | 
														
															         r1 >= 0 && r2 >= 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // actually, range requests don't play well with a pre-gzipped 
														 | 
														
														 | 
														
															         // actually, range requests don't play well with a pre-gzipped 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        // file (since the range is specified in the uncmpressed space) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        // file (since the range is specified in the uncompressed space) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (filep->gzipped) { 
														 | 
														
														 | 
														
															         if (filep->gzipped) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             send_http_error(conn, 501, "Not Implemented", "range requests in gzipped files are not supported"); 
														 | 
														
														 | 
														
															             send_http_error(conn, 501, "Not Implemented", "range requests in gzipped files are not supported"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_fclose(filep); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             return; 
														 | 
														
														 | 
														
															             return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->status_code = 206; 
														 | 
														
														 | 
														
															         conn->status_code = 206; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3347,15 +3495,19 @@ static void prepare_cgi_environment(struct mg_connection *conn, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void handle_cgi_request(struct mg_connection *conn, const char *prog) 
														 | 
														
														 | 
														
															 static void handle_cgi_request(struct mg_connection *conn, const char *prog) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    char *buf; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    size_t buflen; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int headers_len, data_len, i, fdin[2] = { 0, 0 }, fdout[2] = { 0, 0 }; 
														 | 
														
														 | 
														
															     int headers_len, data_len, i, fdin[2] = { 0, 0 }, fdout[2] = { 0, 0 }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const char *status, *status_text; 
														 | 
														
														 | 
														
															     const char *status, *status_text; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    char buf[MAX_REQUEST_SIZE], *pbuf, dir[PATH_MAX], *p; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    char *pbuf, dir[PATH_MAX], *p; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_request_info ri; 
														 | 
														
														 | 
														
															     struct mg_request_info ri; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct cgi_env_block blk; 
														 | 
														
														 | 
														
															     struct cgi_env_block blk; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     FILE *in = NULL, *out = NULL; 
														 | 
														
														 | 
														
															     FILE *in = NULL, *out = NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct file fout = STRUCT_FILE_INITIALIZER; 
														 | 
														
														 | 
														
															     struct file fout = STRUCT_FILE_INITIALIZER; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     pid_t pid = (pid_t) -1; 
														 | 
														
														 | 
														
															     pid_t pid = (pid_t) -1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    buf = NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    buflen = 16384; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     prepare_cgi_environment(conn, prog, &blk); 
														 | 
														
														 | 
														
															     prepare_cgi_environment(conn, prog, &blk); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // CGI must be executed in its own directory. 'dir' must point to the 
														 | 
														
														 | 
														
															     // CGI must be executed in its own directory. 'dir' must point to the 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3383,10 +3535,10 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Make sure child closes all pipe descriptors. It must dup them to 0,1 
														 | 
														
														 | 
														
															     // Make sure child closes all pipe descriptors. It must dup them to 0,1 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    set_close_on_exec(fdin[0]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    set_close_on_exec(fdin[1]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    set_close_on_exec(fdout[0]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    set_close_on_exec(fdout[1]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    set_close_on_exec(fdin[0], conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    set_close_on_exec(fdin[1], conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    set_close_on_exec(fdout[0], conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    set_close_on_exec(fdout[1], conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Parent closes only one side of the pipes. 
														 | 
														
														 | 
														
															     // Parent closes only one side of the pipes. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // If we don't mark them as closed, close() attempt before 
														 | 
														
														 | 
														
															     // If we don't mark them as closed, close() attempt before 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3424,12 +3576,19 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Do not send anything back to client, until we buffer in all 
														 | 
														
														 | 
														
															     // Do not send anything back to client, until we buffer in all 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // HTTP headers. 
														 | 
														
														 | 
														
															     // HTTP headers. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     data_len = 0; 
														 | 
														
														 | 
														
															     data_len = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    headers_len = read_request(out, conn, buf, sizeof(buf), &data_len); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    buf = malloc(buflen); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (buf == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        send_http_error(conn, 500, http_500_error, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        "Not enough memory for buffer (%u bytes)", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        (unsigned int) buflen); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        goto done; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    headers_len = read_request(out, conn, buf, buflen, &data_len); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (headers_len <= 0) { 
														 | 
														
														 | 
														
															     if (headers_len <= 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         send_http_error(conn, 500, http_500_error, 
														 | 
														
														 | 
														
															         send_http_error(conn, 500, http_500_error, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                         "CGI program sent malformed or too big (>%u bytes) " 
														 | 
														
														 | 
														
															                         "CGI program sent malformed or too big (>%u bytes) " 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                         "HTTP headers: [%.*s]", 
														 | 
														
														 | 
														
															                         "HTTP headers: [%.*s]", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                        (unsigned) sizeof(buf), data_len, buf); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        (unsigned) buflen, data_len, buf); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         goto done; 
														 | 
														
														 | 
														
															         goto done; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     pbuf = buf; 
														 | 
														
														 | 
														
															     pbuf = buf; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3498,6 +3657,9 @@ done: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if (fdout[0] != -1) { 
														 | 
														
														 | 
														
															     } else if (fdout[0] != -1) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         close(fdout[0]); 
														 | 
														
														 | 
														
															         close(fdout[0]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (buf != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        free(buf); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // !NO_CGI 
														 | 
														
														 | 
														
															 #endif // !NO_CGI 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3541,7 +3703,10 @@ static void mkcol(struct mg_connection *conn, const char *path) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int rc, body_len; 
														 | 
														
														 | 
														
															     int rc, body_len; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct de de; 
														 | 
														
														 | 
														
															     struct de de; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     memset(&de.file, 0, sizeof(de.file)); 
														 | 
														
														 | 
														
															     memset(&de.file, 0, sizeof(de.file)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    mg_stat(conn, path, &de.file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (mg_stat(conn, path, &de.file) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        mg_cry(conn, "%s: mg_stat(%s) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+               __func__, path, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if(de.file.modification_time) { 
														 | 
														
														 | 
														
															     if(de.file.modification_time) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         send_http_error(conn, 405, "Method Not Allowed", 
														 | 
														
														 | 
														
															         send_http_error(conn, 405, "Method Not Allowed", 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3596,7 +3761,7 @@ static void put_file(struct mg_connection *conn, const char *path) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         send_http_error(conn, 500, http_500_error, 
														 | 
														
														 | 
														
															         send_http_error(conn, 500, http_500_error, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                         "fopen(%s): %s", path, strerror(ERRNO)); 
														 | 
														
														 | 
														
															                         "fopen(%s): %s", path, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fclose_on_exec(&file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        fclose_on_exec(&file, conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         range = mg_get_header(conn, "Content-Range"); 
														 | 
														
														 | 
														
															         range = mg_get_header(conn, "Content-Range"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         r1 = r2 = 0; 
														 | 
														
														 | 
														
															         r1 = r2 = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (range != NULL && parse_range_header(range, &r1, &r2) > 0) { 
														 | 
														
														 | 
														
															         if (range != NULL && parse_range_header(range, &r1, &r2) > 0) { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3649,7 +3814,7 @@ static void do_ssi_include(struct mg_connection *conn, const char *ssi, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_cry(conn, "Cannot open SSI #include: [%s]: fopen(%s): %s", 
														 | 
														
														 | 
														
															         mg_cry(conn, "Cannot open SSI #include: [%s]: fopen(%s): %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                tag, path, strerror(ERRNO)); 
														 | 
														
														 | 
														
															                tag, path, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fclose_on_exec(&file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        fclose_on_exec(&file, conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (match_prefix(conn->ctx->config[SSI_EXTENSIONS], 
														 | 
														
														 | 
														
															         if (match_prefix(conn->ctx->config[SSI_EXTENSIONS], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                          (int)strlen(conn->ctx->config[SSI_EXTENSIONS]), path) > 0) { 
														 | 
														
														 | 
														
															                          (int)strlen(conn->ctx->config[SSI_EXTENSIONS]), path) > 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             send_ssi_file(conn, path, &file, include_level + 1); 
														 | 
														
														 | 
														
															             send_ssi_file(conn, path, &file, include_level + 1); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -3762,7 +3927,7 @@ static void handle_ssi_file_request(struct mg_connection *conn, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                         strerror(ERRNO)); 
														 | 
														
														 | 
														
															                         strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->must_close = 1; 
														 | 
														
														 | 
														
															         conn->must_close = 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        fclose_on_exec(&file); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        fclose_on_exec(&file, conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_printf(conn, "HTTP/1.1 200 OK\r\n" 
														 | 
														
														 | 
														
															         mg_printf(conn, "HTTP/1.1 200 OK\r\n" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   "Content-Type: text/html\r\nConnection: %s\r\n\r\n", 
														 | 
														
														 | 
														
															                   "Content-Type: text/html\r\nConnection: %s\r\n\r\n", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   suggest_connection_header(conn)); 
														 | 
														
														 | 
														
															                   suggest_connection_header(conn)); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4476,22 +4641,33 @@ static int is_put_or_delete_request(const struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static int get_first_ssl_listener_index(const struct mg_context *ctx) 
														 | 
														
														 | 
														
															 static int get_first_ssl_listener_index(const struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    int i, index = -1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    for (i = 0; index == -1 && i < ctx->num_listening_sockets; i++) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        index = ctx->listening_sockets[i].is_ssl ? i : -1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int i, idx = -1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    for (i = 0; idx == -1 && i < ctx->num_listening_sockets; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        idx = ctx->listening_sockets[i].is_ssl ? i : -1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return index; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return idx; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) 
														 | 
														
														 | 
														
															 static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     char host[1025]; 
														 | 
														
														 | 
														
															     char host[1025]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const char *host_header; 
														 | 
														
														 | 
														
															     const char *host_header; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    if ((host_header = mg_get_header(conn, "Host")) == NULL || 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sscanf(host_header, "%1024[^:]", host) == 0) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    size_t hostlen; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    host_header = mg_get_header(conn, "Host"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    hostlen = sizeof(host); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (host_header != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        char *pos; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strncpy(host, host_header, hostlen); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        host[hostlen - 1] = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        pos = strchr(host, ':'); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (pos != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            *pos = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Cannot get host from the Host: header. Fallback to our IP address. 
														 | 
														
														 | 
														
															         // Cannot get host from the Host: header. Fallback to our IP address. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        sockaddr_to_string(host, sizeof(host), &conn->client.lsa); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        sockaddr_to_string(host, hostlen, &conn->client.lsa); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     mg_printf(conn, "HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s\r\n\r\n", 
														 | 
														
														 | 
														
															     mg_printf(conn, "HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s\r\n\r\n", 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4610,6 +4786,7 @@ static void handle_request(struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     uri_len = (int) strlen(ri->uri); 
														 | 
														
														 | 
														
															     uri_len = (int) strlen(ri->uri); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     mg_url_decode(ri->uri, uri_len, (char *) ri->uri, uri_len + 1, 0); 
														 | 
														
														 | 
														
															     mg_url_decode(ri->uri, uri_len, (char *) ri->uri, uri_len + 1, 0); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     remove_double_dots_and_double_slashes((char *) ri->uri); 
														 | 
														
														 | 
														
															     remove_double_dots_and_double_slashes((char *) ri->uri); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    path[0] = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     convert_uri_to_file_name(conn, path, sizeof(path), &file); 
														 | 
														
														 | 
														
															     convert_uri_to_file_name(conn, path, sizeof(path), &file); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     conn->throttle = set_throttle(conn->ctx->config[THROTTLE], 
														 | 
														
														 | 
														
															     conn->throttle = set_throttle(conn->ctx->config[THROTTLE], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                   get_remote_ip(conn), ri->uri); 
														 | 
														
														 | 
														
															                                   get_remote_ip(conn), ri->uri); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4720,7 +4897,7 @@ static void close_all_listening_sockets(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static int is_valid_port(unsigned int port) 
														 | 
														
														 | 
														
															 static int is_valid_port(unsigned int port) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return port > 0 && port < 0xffff; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return port < 0xffff; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // Valid listening port specification is: [ip_address:]port[s] 
														 | 
														
														 | 
														
															 // Valid listening port specification is: [ip_address:]port[s] 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4801,7 +4978,9 @@ static int set_ports_option(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                    listen(so.sock, SOMAXCONN) != 0) { 
														 | 
														
														 | 
														
															                    listen(so.sock, SOMAXCONN) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             mg_cry(fc(ctx), "%s: cannot bind to %.*s: %d (%s)", __func__, 
														 | 
														
														 | 
														
															             mg_cry(fc(ctx), "%s: cannot bind to %.*s: %d (%s)", __func__, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                    (int) vec.len, vec.ptr, ERRNO, strerror(errno)); 
														 | 
														
														 | 
														
															                    (int) vec.len, vec.ptr, ERRNO, strerror(errno)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            closesocket(so.sock); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            if (so.sock != INVALID_SOCKET) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                closesocket(so.sock); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             success = 0; 
														 | 
														
														 | 
														
															             success = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } else if ((ptr = (struct socket *) realloc(ctx->listening_sockets, 
														 | 
														
														 | 
														
															         } else if ((ptr = (struct socket *) realloc(ctx->listening_sockets, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                           (ctx->num_listening_sockets + 1) * 
														 | 
														
														 | 
														
															                           (ctx->num_listening_sockets + 1) * 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4809,7 +4988,7 @@ static int set_ports_option(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             closesocket(so.sock); 
														 | 
														
														 | 
														
															             closesocket(so.sock); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             success = 0; 
														 | 
														
														 | 
														
															             success = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } else { 
														 | 
														
														 | 
														
															         } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            set_close_on_exec(so.sock); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            set_close_on_exec(so.sock, fc(ctx)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             ctx->listening_sockets = ptr; 
														 | 
														
														 | 
														
															             ctx->listening_sockets = ptr; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             ctx->listening_sockets[ctx->num_listening_sockets] = so; 
														 | 
														
														 | 
														
															             ctx->listening_sockets[ctx->num_listening_sockets] = so; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             ctx->num_listening_sockets++; 
														 | 
														
														 | 
														
															             ctx->num_listening_sockets++; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4840,6 +5019,7 @@ static void log_access(const struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const struct mg_request_info *ri; 
														 | 
														
														 | 
														
															     const struct mg_request_info *ri; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     FILE *fp; 
														 | 
														
														 | 
														
															     FILE *fp; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     char date[64], src_addr[IP_ADDR_STR_LEN]; 
														 | 
														
														 | 
														
															     char date[64], src_addr[IP_ADDR_STR_LEN]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    struct tm *tm; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     fp = conn->ctx->config[ACCESS_LOG_FILE] == NULL ?  NULL : 
														 | 
														
														 | 
														
															     fp = conn->ctx->config[ACCESS_LOG_FILE] == NULL ?  NULL : 
														 | 
													
												
											
												
													
														| 
														 | 
														
															          fopen(conn->ctx->config[ACCESS_LOG_FILE], "a+"); 
														 | 
														
														 | 
														
															          fopen(conn->ctx->config[ACCESS_LOG_FILE], "a+"); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4847,8 +5027,13 @@ static void log_access(const struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (fp == NULL) 
														 | 
														
														 | 
														
															     if (fp == NULL) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         return; 
														 | 
														
														 | 
														
															         return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-             localtime(&conn->birth_time)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    tm = localtime(&conn->birth_time); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (tm != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strftime(date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", tm); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        strncpy(date, "01/Jan/1970:00:00:00 +0000", sizeof(date)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        date[sizeof(date) - 1] = '\0'; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     ri = &conn->request_info; 
														 | 
														
														 | 
														
															     ri = &conn->request_info; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     flockfile(fp); 
														 | 
														
														 | 
														
															     flockfile(fp); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4958,8 +5143,8 @@ static unsigned long ssl_id_callback(void) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if !defined(NO_SSL_DL) 
														 | 
														
														 | 
														
															 #if !defined(NO_SSL_DL) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static int load_dll(struct mg_context *ctx, const char *dll_name, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    struct ssl_func *sw) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void *load_dll(struct mg_context *ctx, const char *dll_name, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                      struct ssl_func *sw) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     union { 
														 | 
														
														 | 
														
															     union { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         void *p; 
														 | 
														
														 | 
														
															         void *p; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4970,7 +5155,7 @@ static int load_dll(struct mg_context *ctx, const char *dll_name, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if ((dll_handle = dlopen(dll_name, RTLD_LAZY)) == NULL) { 
														 | 
														
														 | 
														
															     if ((dll_handle = dlopen(dll_name, RTLD_LAZY)) == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_cry(fc(ctx), "%s: cannot load %s", __func__, dll_name); 
														 | 
														
														 | 
														
															         mg_cry(fc(ctx), "%s: cannot load %s", __func__, dll_name); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        return 0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     for (fp = sw; fp->name != NULL; fp++) { 
														 | 
														
														 | 
														
															     for (fp = sw; fp->name != NULL; fp++) { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -4984,13 +5169,14 @@ static int load_dll(struct mg_context *ctx, const char *dll_name, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // _WIN32 
														 | 
														
														 | 
														
															 #endif // _WIN32 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (u.fp == NULL) { 
														 | 
														
														 | 
														
															         if (u.fp == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             mg_cry(fc(ctx), "%s: %s: cannot find %s", __func__, dll_name, fp->name); 
														 | 
														
														 | 
														
															             mg_cry(fc(ctx), "%s: %s: cannot find %s", __func__, dll_name, fp->name); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            return 0; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            dlclose(dll_handle); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } else { 
														 | 
														
														 | 
														
															         } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             fp->ptr = u.fp; 
														 | 
														
														 | 
														
															             fp->ptr = u.fp; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return 1; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return dll_handle; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // NO_SSL_DL 
														 | 
														
														 | 
														
															 #endif // NO_SSL_DL 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5008,8 +5194,9 @@ static int set_ssl_option(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if !defined(NO_SSL_DL) 
														 | 
														
														 | 
														
															 #if !defined(NO_SSL_DL) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    if (!load_dll(ctx, SSL_LIB, ssl_sw) || 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        !load_dll(ctx, CRYPTO_LIB, crypto_sw)) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    ctx->ssllib_dll_handle = load_dll(ctx, SSL_LIB, ssl_sw); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    ctx->cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (!ctx->ssllib_dll_handle || !ctx->cryptolib_dll_handle) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         return 0; 
														 | 
														
														 | 
														
															         return 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // NO_SSL_DL 
														 | 
														
														 | 
														
															 #endif // NO_SSL_DL 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5105,8 +5292,11 @@ static void close_socket_gracefully(struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // ephemeral port exhaust problem under high QPS. 
														 | 
														
														 | 
														
															     // ephemeral port exhaust problem under high QPS. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     linger.l_onoff = 1; 
														 | 
														
														 | 
														
															     linger.l_onoff = 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     linger.l_linger = 1; 
														 | 
														
														 | 
														
															     linger.l_linger = 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    setsockopt(conn->client.sock, SOL_SOCKET, SO_LINGER, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-               (char *) &linger, sizeof(linger)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (setsockopt(conn->client.sock, SOL_SOCKET, SO_LINGER, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   (char *) &linger, sizeof(linger)) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        mg_cry(conn, "%s: setsockopt(SOL_SOCKET SO_LINGER) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+               __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Send FIN to the client 
														 | 
														
														 | 
														
															     // Send FIN to the client 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     shutdown(conn->client.sock, SHUT_WR); 
														 | 
														
														 | 
														
															     shutdown(conn->client.sock, SHUT_WR); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5161,13 +5351,17 @@ void mg_close_connection(struct mg_connection *conn) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 struct mg_connection *mg_connect(const char *host, int port, int use_ssl, 
														 | 
														
														 | 
														
															 struct mg_connection *mg_connect(const char *host, int port, int use_ssl, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                 char *ebuf, size_t ebuf_len); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+struct mg_connection *mg_connect(const char *host, int port, int use_ssl, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                                  char *ebuf, size_t ebuf_len) 
														 | 
														
														 | 
														
															                                  char *ebuf, size_t ebuf_len) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     static struct mg_context fake_ctx; 
														 | 
														
														 | 
														
															     static struct mg_context fake_ctx; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_connection *conn = NULL; 
														 | 
														
														 | 
														
															     struct mg_connection *conn = NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     SOCKET sock; 
														 | 
														
														 | 
														
															     SOCKET sock; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    if ((sock = conn2(host, port, use_ssl, ebuf, ebuf_len)) == INVALID_SOCKET) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if ((sock = conn2(&fake_ctx, host, port, use_ssl, ebuf, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                      ebuf_len)) == INVALID_SOCKET) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if ((conn = (struct mg_connection *) 
														 | 
														
														 | 
														
															     } else if ((conn = (struct mg_connection *) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                        calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE)) == NULL) { 
														 | 
														
														 | 
														
															                        calloc(1, sizeof(*conn) + MAX_REQUEST_SIZE)) == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         snprintf(ebuf, ebuf_len, "calloc(): %s", strerror(ERRNO)); 
														 | 
														
														 | 
														
															         snprintf(ebuf, ebuf_len, "calloc(): %s", strerror(ERRNO)); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5186,7 +5380,10 @@ struct mg_connection *mg_connect(const char *host, int port, int use_ssl, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->buf = (char *) (conn + 1); 
														 | 
														
														 | 
														
															         conn->buf = (char *) (conn + 1); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->ctx = &fake_ctx; 
														 | 
														
														 | 
														
															         conn->ctx = &fake_ctx; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->client.sock = sock; 
														 | 
														
														 | 
														
															         conn->client.sock = sock; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        getsockname(sock, &conn->client.rsa.sa, &len); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (getsockname(sock, &conn->client.rsa.sa, &len) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(conn, "%s: getsockname() failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn->client.is_ssl = use_ssl; 
														 | 
														
														 | 
														
															         conn->client.is_ssl = use_ssl; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         (void) pthread_mutex_init(&conn->mutex, NULL); 
														 | 
														
														 | 
														
															         (void) pthread_mutex_init(&conn->mutex, NULL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #ifndef NO_SSL 
														 | 
														
														 | 
														
															 #ifndef NO_SSL 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5260,6 +5457,7 @@ struct mg_connection *mg_download(const char *host, int port, int use_ssl, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         mg_close_connection(conn); 
														 | 
														
														 | 
														
															         mg_close_connection(conn); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         conn = NULL; 
														 | 
														
														 | 
														
															         conn = NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    va_end(ap); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return conn; 
														 | 
														
														 | 
														
															     return conn; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5353,7 +5551,7 @@ static int consume_socket(struct mg_context *ctx, struct socket *sp) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return !ctx->stop_flag; 
														 | 
														
														 | 
														
															     return !ctx->stop_flag; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static void *worker_thread(void *thread_func_param) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void *worker_thread_run(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_context *ctx = (struct mg_context *) thread_func_param; 
														 | 
														
														 | 
														
															     struct mg_context *ctx = (struct mg_context *) thread_func_param; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_connection *conn; 
														 | 
														
														 | 
														
															     struct mg_connection *conn; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5409,6 +5607,22 @@ static void *worker_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return NULL; 
														 | 
														
														 | 
														
															     return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Threads have different return types on Windows and Unix. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#ifdef _WIN32 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static unsigned __stdcall worker_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    worker_thread_run(thread_func_param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void *worker_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    worker_thread_run(thread_func_param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#endif /* _WIN32 */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // Master thread adds accepted socket to a queue 
														 | 
														
														 | 
														
															 // Master thread adds accepted socket to a queue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void produce_socket(struct mg_context *ctx, const struct socket *sp) 
														 | 
														
														 | 
														
															 static void produce_socket(struct mg_context *ctx, const struct socket *sp) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5460,27 +5674,36 @@ static void accept_new_connection(const struct socket *listener, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else { 
														 | 
														
														 | 
														
															     } else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Put so socket structure into the queue 
														 | 
														
														 | 
														
															         // Put so socket structure into the queue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         DEBUG_TRACE(("Accepted socket %d", (int) so.sock)); 
														 | 
														
														 | 
														
															         DEBUG_TRACE(("Accepted socket %d", (int) so.sock)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        set_close_on_exec(so.sock); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        set_close_on_exec(so.sock, fc(ctx)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         so.is_ssl = listener->is_ssl; 
														 | 
														
														 | 
														
															         so.is_ssl = listener->is_ssl; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         so.ssl_redir = listener->ssl_redir; 
														 | 
														
														 | 
														
															         so.ssl_redir = listener->ssl_redir; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        getsockname(so.sock, &so.lsa.sa, &len); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (getsockname(so.sock, &so.lsa.sa, &len) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(fc(ctx), "%s: getsockname() failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Set TCP keep-alive. This is needed because if HTTP-level keep-alive 
														 | 
														
														 | 
														
															         // Set TCP keep-alive. This is needed because if HTTP-level keep-alive 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // is enabled, and client resets the connection, server won't get 
														 | 
														
														 | 
														
															         // is enabled, and client resets the connection, server won't get 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // TCP FIN or RST and will keep the connection open forever. With TCP 
														 | 
														
														 | 
														
															         // TCP FIN or RST and will keep the connection open forever. With TCP 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // keep-alive, next keep-alive handshake will figure out that the client 
														 | 
														
														 | 
														
															         // keep-alive, next keep-alive handshake will figure out that the client 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // is down and will close the server end. 
														 | 
														
														 | 
														
															         // is down and will close the server end. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Thanks to Igor Klopov who suggested the patch. 
														 | 
														
														 | 
														
															         // Thanks to Igor Klopov who suggested the patch. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        setsockopt(so.sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &on, sizeof(on)); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (setsockopt(so.sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &on, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                       sizeof(on)) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(fc(ctx), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   "%s: setsockopt(SOL_SOCKET SO_KEEPALIVE) failed: %s", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                   __func__, strerror(ERRNO)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         set_sock_timeout(so.sock, atoi(ctx->config[REQUEST_TIMEOUT])); 
														 | 
														
														 | 
														
															         set_sock_timeout(so.sock, atoi(ctx->config[REQUEST_TIMEOUT])); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         produce_socket(ctx, &so); 
														 | 
														
														 | 
														
															         produce_socket(ctx, &so); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-static void *master_thread(void *thread_func_param) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void master_thread_run(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_context *ctx = (struct mg_context *) thread_func_param; 
														 | 
														
														 | 
														
															     struct mg_context *ctx = (struct mg_context *) thread_func_param; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct pollfd *pfd; 
														 | 
														
														 | 
														
															     struct pollfd *pfd; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int i; 
														 | 
														
														 | 
														
															     int i; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int workerthreadcount; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Increase priority of the master thread 
														 | 
														
														 | 
														
															     // Increase priority of the master thread 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if defined(_WIN32) 
														 | 
														
														 | 
														
															 #if defined(_WIN32) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5528,6 +5751,12 @@ static void *master_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_mutex_unlock(&ctx->mutex); 
														 | 
														
														 | 
														
															     (void) pthread_mutex_unlock(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    // Join all worker threads to avoid leaking threads. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    workerthreadcount = ctx->workerthreadcount; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    for (i = 0; i < workerthreadcount; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        mg_join_thread(ctx->workerthreadids[i]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // All threads exited, no sync is needed. Destroy mutex and condvars 
														 | 
														
														 | 
														
															     // All threads exited, no sync is needed. Destroy mutex and condvars 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_mutex_destroy(&ctx->mutex); 
														 | 
														
														 | 
														
															     (void) pthread_mutex_destroy(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_cond_destroy(&ctx->cond); 
														 | 
														
														 | 
														
															     (void) pthread_cond_destroy(&ctx->cond); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5543,8 +5772,23 @@ static void *master_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // WARNING: This must be the very last thing this 
														 | 
														
														 | 
														
															     // WARNING: This must be the very last thing this 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // thread does, as ctx becomes invalid after this line. 
														 | 
														
														 | 
														
															     // thread does, as ctx becomes invalid after this line. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     ctx->stop_flag = 2; 
														 | 
														
														 | 
														
															     ctx->stop_flag = 2; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+/* Threads have different return types on Windows and Unix. */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#ifdef _WIN32 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static unsigned __stdcall master_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    master_thread_run(thread_func_param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void *master_thread(void *thread_func_param) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    master_thread_run(thread_func_param); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return NULL; 
														 | 
														
														 | 
														
															     return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#endif /* _WIN32 */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static void free_context(struct mg_context *ctx) 
														 | 
														
														 | 
														
															 static void free_context(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5582,6 +5826,11 @@ static void free_context(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif // !NO_SSL 
														 | 
														
														 | 
														
															 #endif // !NO_SSL 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    // Deallocate worker thread ID array 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (ctx->workerthreadids != NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        free(ctx->workerthreadids); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Deallocate context itself 
														 | 
														
														 | 
														
															     // Deallocate context itself 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     free(ctx); 
														 | 
														
														 | 
														
															     free(ctx); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5594,6 +5843,7 @@ void mg_stop(struct mg_context *ctx) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     while (ctx->stop_flag != 2) { 
														 | 
														
														 | 
														
															     while (ctx->stop_flag != 2) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         (void) mg_sleep(10); 
														 | 
														
														 | 
														
															         (void) mg_sleep(10); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    mg_join_thread(ctx->masterthreadid); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     free_context(ctx); 
														 | 
														
														 | 
														
															     free_context(ctx); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if defined(_WIN32) && !defined(__SYMBIAN32__) 
														 | 
														
														 | 
														
															 #if defined(_WIN32) && !defined(__SYMBIAN32__) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5608,6 +5858,7 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     struct mg_context *ctx; 
														 | 
														
														 | 
														
															     struct mg_context *ctx; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     const char *name, *value, *default_value; 
														 | 
														
														 | 
														
															     const char *name, *value, *default_value; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int i; 
														 | 
														
														 | 
														
															     int i; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    int workerthreadcount; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if defined(_WIN32) && !defined(__SYMBIAN32__) 
														 | 
														
														 | 
														
															 #if defined(_WIN32) && !defined(__SYMBIAN32__) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     WSADATA data; 
														 | 
														
														 | 
														
															     WSADATA data; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -5677,15 +5928,31 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_cond_init(&ctx->sq_empty, NULL); 
														 | 
														
														 | 
														
															     (void) pthread_cond_init(&ctx->sq_empty, NULL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     (void) pthread_cond_init(&ctx->sq_full, NULL); 
														 | 
														
														 | 
														
															     (void) pthread_cond_init(&ctx->sq_full, NULL); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    workerthreadcount = atoi(ctx->config[NUM_THREADS]); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (workerthreadcount > 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        ctx->workerthreadcount = workerthreadcount; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        ctx->workerthreadids = calloc(workerthreadcount, sizeof(pthread_t)); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (ctx->workerthreadids == NULL) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            mg_cry(fc(ctx), "Not enough memory for worker thread ID array"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            free_context(ctx); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            return NULL; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Start master (listening) thread 
														 | 
														
														 | 
														
															     // Start master (listening) thread 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    mg_start_thread(master_thread, ctx); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    mg_start_thread_with_id(master_thread, ctx, &ctx->masterthreadid); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     // Start worker threads 
														 | 
														
														 | 
														
															     // Start worker threads 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    for (i = 0; i < atoi(ctx->config[NUM_THREADS]); i++) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        if (mg_start_thread(worker_thread, ctx) != 0) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    for (i = 0; i < workerthreadcount; i++) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        (void) pthread_mutex_lock(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        ctx->num_threads++; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        (void) pthread_mutex_unlock(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (mg_start_thread_with_id(worker_thread, ctx, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                                    &ctx->workerthreadids[i]) != 0) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            (void) pthread_mutex_lock(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            ctx->num_threads--; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            (void) pthread_mutex_unlock(&ctx->mutex); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             mg_cry(fc(ctx), "Cannot start worker thread: %ld", (long) ERRNO); 
														 | 
														
														 | 
														
															             mg_cry(fc(ctx), "Cannot start worker thread: %ld", (long) ERRNO); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        } else { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            ctx->num_threads++; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 |