|
@@ -2320,9 +2320,10 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
|
|
gmt_time_string(date, sizeof(date), &curtime);
|
|
gmt_time_string(date, sizeof(date), &curtime);
|
|
|
|
|
|
conn->must_close = 1;
|
|
conn->must_close = 1;
|
|
- mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text);
|
|
|
|
|
|
+ mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text);
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ "Cache-Control: no-cache\r\n"
|
|
"Connection: close\r\n\r\n",
|
|
"Connection: close\r\n\r\n",
|
|
date);
|
|
date);
|
|
|
|
|
|
@@ -3183,6 +3184,7 @@ mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */)
|
|
set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */)
|
|
{
|
|
{
|
|
@@ -3196,6 +3198,7 @@ set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
int
|
|
int
|
|
mg_start_thread(mg_thread_func_t func, void *param)
|
|
mg_start_thread(mg_thread_func_t func, void *param)
|
|
{
|
|
{
|
|
@@ -3218,8 +3221,8 @@ mg_start_thread(mg_thread_func_t func, void *param)
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
-/* Start a thread storing the thread context. */
|
|
|
|
|
|
|
|
|
|
+/* Start a thread storing the thread context. */
|
|
static int
|
|
static int
|
|
mg_start_thread_with_id(mg_thread_func_t func,
|
|
mg_start_thread_with_id(mg_thread_func_t func,
|
|
void *param,
|
|
void *param,
|
|
@@ -3245,8 +3248,8 @@ mg_start_thread_with_id(mg_thread_func_t func,
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
-/* Wait for a thread to finish. */
|
|
|
|
|
|
|
|
|
|
+/* Wait for a thread to finish. */
|
|
static int
|
|
static int
|
|
mg_join_thread(pthread_t threadid)
|
|
mg_join_thread(pthread_t threadid)
|
|
{
|
|
{
|
|
@@ -3256,6 +3259,7 @@ mg_join_thread(pthread_t threadid)
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
#ifndef NO_CGI
|
|
#ifndef NO_CGI
|
|
static pid_t
|
|
static pid_t
|
|
spawn_process(struct mg_connection *conn,
|
|
spawn_process(struct mg_connection *conn,
|
|
@@ -3335,6 +3339,7 @@ spawn_process(struct mg_connection *conn,
|
|
}
|
|
}
|
|
#endif /* !NO_CGI */
|
|
#endif /* !NO_CGI */
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
set_non_blocking_mode(SOCKET sock)
|
|
set_non_blocking_mode(SOCKET sock)
|
|
{
|
|
{
|
|
@@ -5198,6 +5203,7 @@ send_authorization_request(struct mg_connection *conn)
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 401 Unauthorized\r\n"
|
|
"HTTP/1.1 401 Unauthorized\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ "Cache-Control: no-cache\r\n"
|
|
"Connection: %s\r\n"
|
|
"Connection: %s\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", "
|
|
"WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", "
|
|
@@ -5852,6 +5858,7 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ /* TODO: Cache-Control */
|
|
"Connection: close\r\n"
|
|
"Connection: close\r\n"
|
|
"Content-Type: text/html; charset=utf-8\r\n\r\n",
|
|
"Content-Type: text/html; charset=utf-8\r\n\r\n",
|
|
date);
|
|
date);
|
|
@@ -6154,6 +6161,7 @@ handle_static_file_request(struct mg_connection *conn,
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"%s%s%s"
|
|
"%s%s%s"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ /* TODO: "Cache-Control" */
|
|
"Last-Modified: %s\r\n"
|
|
"Last-Modified: %s\r\n"
|
|
"Etag: %s\r\n"
|
|
"Etag: %s\r\n"
|
|
"Content-Type: %.*s\r\n"
|
|
"Content-Type: %.*s\r\n"
|
|
@@ -7156,8 +7164,11 @@ mkcol(struct mg_connection *conn, const char *path)
|
|
conn->status_code = 201;
|
|
conn->status_code = 201;
|
|
gmt_time_string(date, sizeof(date), &curtime);
|
|
gmt_time_string(date, sizeof(date), &curtime);
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
- "HTTP/1.1 %d Created\r\nDate: %s\r\nContent-Length: "
|
|
|
|
- "0\r\nConnection: %s\r\n\r\n",
|
|
|
|
|
|
+ "HTTP/1.1 %d Created\r\n"
|
|
|
|
+ "Date: %s\r\n"
|
|
|
|
+ /* TODO: "Cache-Control" */
|
|
|
|
+ "Content-Length: 0\r\n"
|
|
|
|
+ "Connection: %s\r\n\r\n",
|
|
conn->status_code,
|
|
conn->status_code,
|
|
date,
|
|
date,
|
|
suggest_connection_header(conn));
|
|
suggest_connection_header(conn));
|
|
@@ -7240,6 +7251,7 @@ put_file(struct mg_connection *conn, const char *path)
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ "Cache-Control: no-cache\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Connection: %s\r\n\r\n",
|
|
"Connection: %s\r\n\r\n",
|
|
conn->status_code,
|
|
conn->status_code,
|
|
@@ -7302,6 +7314,7 @@ put_file(struct mg_connection *conn, const char *path)
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"HTTP/1.1 %d %s\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ "Cache-Control: no-cache\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Connection: %s\r\n\r\n",
|
|
"Connection: %s\r\n\r\n",
|
|
conn->status_code,
|
|
conn->status_code,
|
|
@@ -7610,6 +7623,7 @@ handle_ssi_file_request(struct mg_connection *conn,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"%s%s%s"
|
|
"%s%s%s"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ "Cache-Control: no-cache\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Content-Type: text/html\r\n"
|
|
"Connection: %s\r\n\r\n",
|
|
"Connection: %s\r\n\r\n",
|
|
cors1,
|
|
cors1,
|
|
@@ -7640,6 +7654,7 @@ send_options(struct mg_connection *conn)
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ /* TODO: "Cache-Control" ? */
|
|
"Connection: %s\r\n"
|
|
"Connection: %s\r\n"
|
|
"Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, OPTIONS, "
|
|
"Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, OPTIONS, "
|
|
"PROPFIND, MKCOL\r\n"
|
|
"PROPFIND, MKCOL\r\n"
|
|
@@ -7723,6 +7738,7 @@ handle_propfind(struct mg_connection *conn,
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
"HTTP/1.1 207 Multi-Status\r\n"
|
|
"HTTP/1.1 207 Multi-Status\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ /* TODO: "Cache-Control" */
|
|
"Connection: %s\r\n"
|
|
"Connection: %s\r\n"
|
|
"Content-Type: text/xml; charset=utf-8\r\n\r\n",
|
|
"Content-Type: text/xml; charset=utf-8\r\n\r\n",
|
|
date,
|
|
date,
|
|
@@ -8777,6 +8793,7 @@ redirect_to_https_port(struct mg_connection *conn, int ssl_index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
mg_set_request_handler_type(struct mg_context *ctx,
|
|
mg_set_request_handler_type(struct mg_context *ctx,
|
|
const char *uri,
|
|
const char *uri,
|
|
@@ -8896,6 +8913,7 @@ mg_set_request_handler_type(struct mg_context *ctx,
|
|
mg_unlock_context(ctx);
|
|
mg_unlock_context(ctx);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
void
|
|
void
|
|
mg_set_request_handler(struct mg_context *ctx,
|
|
mg_set_request_handler(struct mg_context *ctx,
|
|
const char *uri,
|
|
const char *uri,
|
|
@@ -8906,6 +8924,7 @@ mg_set_request_handler(struct mg_context *ctx,
|
|
ctx, uri, 0, handler == NULL, handler, NULL, NULL, NULL, NULL, cbdata);
|
|
ctx, uri, 0, handler == NULL, handler, NULL, NULL, NULL, NULL, cbdata);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
void
|
|
void
|
|
mg_set_websocket_handler(struct mg_context *ctx,
|
|
mg_set_websocket_handler(struct mg_context *ctx,
|
|
const char *uri,
|
|
const char *uri,
|
|
@@ -8930,6 +8949,7 @@ mg_set_websocket_handler(struct mg_context *ctx,
|
|
cbdata);
|
|
cbdata);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
get_request_handler(struct mg_connection *conn,
|
|
get_request_handler(struct mg_connection *conn,
|
|
int is_websocket_request,
|
|
int is_websocket_request,
|
|
@@ -9018,6 +9038,7 @@ get_request_handler(struct mg_connection *conn,
|
|
return 0; /* none found */
|
|
return 0; /* none found */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
#if defined(USE_WEBSOCKET) && defined(MG_LEGACY_INTERFACE)
|
|
#if defined(USE_WEBSOCKET) && defined(MG_LEGACY_INTERFACE)
|
|
static int
|
|
static int
|
|
deprecated_websocket_connect_wrapper(const struct mg_connection *conn,
|
|
deprecated_websocket_connect_wrapper(const struct mg_connection *conn,
|
|
@@ -9031,6 +9052,7 @@ deprecated_websocket_connect_wrapper(const struct mg_connection *conn,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
deprecated_websocket_ready_wrapper(struct mg_connection *conn, void *cbdata)
|
|
deprecated_websocket_ready_wrapper(struct mg_connection *conn, void *cbdata)
|
|
{
|
|
{
|
|
@@ -9040,6 +9062,7 @@ deprecated_websocket_ready_wrapper(struct mg_connection *conn, void *cbdata)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
deprecated_websocket_data_wrapper(struct mg_connection *conn,
|
|
deprecated_websocket_data_wrapper(struct mg_connection *conn,
|
|
int bits,
|
|
int bits,
|
|
@@ -9056,6 +9079,7 @@ deprecated_websocket_data_wrapper(struct mg_connection *conn,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+
|
|
/* This is the heart of the Civetweb's logic.
|
|
/* This is the heart of the Civetweb's logic.
|
|
* This function is called when the request is read, parsed and validated,
|
|
* This function is called when the request is read, parsed and validated,
|
|
* and Civetweb must decide what action to take: serve a file, or
|
|
* and Civetweb must decide what action to take: serve a file, or
|
|
@@ -9368,6 +9392,7 @@ handle_request(struct mg_connection *conn)
|
|
"HTTP/1.1 301 Moved Permanently\r\n"
|
|
"HTTP/1.1 301 Moved Permanently\r\n"
|
|
"Location: %s/\r\n"
|
|
"Location: %s/\r\n"
|
|
"Date: %s\r\n"
|
|
"Date: %s\r\n"
|
|
|
|
+ /* TODO: "Cache-Control" ? */
|
|
"Content-Length: 0\r\n"
|
|
"Content-Length: 0\r\n"
|
|
"Connection: %s\r\n\r\n",
|
|
"Connection: %s\r\n\r\n",
|
|
ri->request_uri,
|
|
ri->request_uri,
|
|
@@ -9436,6 +9461,7 @@ handle_request(struct mg_connection *conn)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
handle_file_based_request(struct mg_connection *conn,
|
|
handle_file_based_request(struct mg_connection *conn,
|
|
const char *path,
|
|
const char *path,
|
|
@@ -9488,6 +9514,7 @@ handle_file_based_request(struct mg_connection *conn,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
close_all_listening_sockets(struct mg_context *ctx)
|
|
close_all_listening_sockets(struct mg_context *ctx)
|
|
{
|
|
{
|
|
@@ -11527,6 +11554,7 @@ produce_socket(struct mg_context *ctx, const struct socket *sp)
|
|
#undef QUEUE_SIZE
|
|
#undef QUEUE_SIZE
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
accept_new_connection(const struct socket *listener, struct mg_context *ctx)
|
|
accept_new_connection(const struct socket *listener, struct mg_context *ctx)
|
|
{
|
|
{
|
|
@@ -11596,6 +11624,7 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
master_thread_run(void *thread_func_param)
|
|
master_thread_run(void *thread_func_param)
|
|
{
|
|
{
|
|
@@ -11716,6 +11745,7 @@ master_thread(void *thread_func_param)
|
|
}
|
|
}
|
|
#endif /* _WIN32 */
|
|
#endif /* _WIN32 */
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
free_context(struct mg_context *ctx)
|
|
free_context(struct mg_context *ctx)
|
|
{
|
|
{
|
|
@@ -11797,6 +11827,7 @@ free_context(struct mg_context *ctx)
|
|
mg_free(ctx);
|
|
mg_free(ctx);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
void
|
|
void
|
|
mg_stop(struct mg_context *ctx)
|
|
mg_stop(struct mg_context *ctx)
|
|
{
|
|
{
|
|
@@ -11828,6 +11859,7 @@ mg_stop(struct mg_context *ctx)
|
|
#endif /* _WIN32 && !__SYMBIAN32__ */
|
|
#endif /* _WIN32 && !__SYMBIAN32__ */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
get_system_name(char **sysName)
|
|
get_system_name(char **sysName)
|
|
{
|
|
{
|
|
@@ -11870,6 +11902,7 @@ get_system_name(char **sysName)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
struct mg_context *
|
|
struct mg_context *
|
|
mg_start(const struct mg_callbacks *callbacks,
|
|
mg_start(const struct mg_callbacks *callbacks,
|
|
void *user_data,
|
|
void *user_data,
|
|
@@ -12087,6 +12120,7 @@ mg_start(const struct mg_callbacks *callbacks,
|
|
return ctx;
|
|
return ctx;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
/* Feature check API function */
|
|
/* Feature check API function */
|
|
unsigned
|
|
unsigned
|
|
mg_check_feature(unsigned feature)
|
|
mg_check_feature(unsigned feature)
|
|
@@ -12137,3 +12171,4 @@ mg_check_feature(unsigned feature)
|
|
;
|
|
;
|
|
return (feature & feature_set);
|
|
return (feature & feature_set);
|
|
}
|
|
}
|
|
|
|
+
|