|
@@ -579,7 +579,12 @@ typedef const char *SOCK_OPT_TYPE;
|
|
#define strtoull(x, y, z) (_strtoui64(x, y, z))
|
|
#define strtoull(x, y, z) (_strtoui64(x, y, z))
|
|
#define strtoll(x, y, z) (_strtoi64(x, y, z))
|
|
#define strtoll(x, y, z) (_strtoi64(x, y, z))
|
|
#endif
|
|
#endif
|
|
-#define qsort_r(base, num, with, comp, arg) qsort_s(base, num, with, comp, arg)
|
|
|
|
|
|
+#define qsort_r(base, num, with, comp, arg) \
|
|
|
|
+ qsort_s(base, \
|
|
|
|
+ num, \
|
|
|
|
+ with, \
|
|
|
|
+ (int(__cdecl *)(void *, const void *, const void *))comp, \
|
|
|
|
+ arg)
|
|
#endif /* _MSC_VER */
|
|
#endif /* _MSC_VER */
|
|
|
|
|
|
#define ERRNO ((int)(GetLastError()))
|
|
#define ERRNO ((int)(GetLastError()))
|
|
@@ -4158,6 +4163,26 @@ send_additional_header(struct mg_connection *conn)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+send_cors_header(struct mg_connection *conn)
|
|
|
|
+{
|
|
|
|
+ const char *origin_hdr = mg_get_header(conn, "Origin");
|
|
|
|
+ const char *cors_orig_cfg =
|
|
|
|
+ conn->dom_ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN];
|
|
|
|
+
|
|
|
|
+ if (cors_orig_cfg && *cors_orig_cfg && origin_hdr && *origin_hdr) {
|
|
|
|
+ /* Cross-origin resource sharing (CORS), see
|
|
|
|
+ * http://www.html5rocks.com/en/tutorials/cors/,
|
|
|
|
+ * http://www.html5rocks.com/static/images/cors_server_flowchart.png
|
|
|
|
+ * CORS preflight is not supported for files. */
|
|
|
|
+ mg_response_header_add(conn,
|
|
|
|
+ "Access-Control-Allow-Origin",
|
|
|
|
+ cors_orig_cfg,
|
|
|
|
+ -1);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
#if !defined(NO_FILESYSTEMS)
|
|
#if !defined(NO_FILESYSTEMS)
|
|
static void handle_file_based_request(struct mg_connection *conn,
|
|
static void handle_file_based_request(struct mg_connection *conn,
|
|
const char *path,
|
|
const char *path,
|
|
@@ -4526,6 +4551,7 @@ mg_send_http_error_impl(struct mg_connection *conn,
|
|
mg_response_header_start(conn, status);
|
|
mg_response_header_start(conn, status);
|
|
send_no_cache_header(conn);
|
|
send_no_cache_header(conn);
|
|
send_additional_header(conn);
|
|
send_additional_header(conn);
|
|
|
|
+ send_cors_header(conn);
|
|
if (has_body) {
|
|
if (has_body) {
|
|
mg_response_header_add(conn,
|
|
mg_response_header_add(conn,
|
|
"Content-Type",
|
|
"Content-Type",
|
|
@@ -4577,6 +4603,7 @@ mg_send_http_ok(struct mg_connection *conn,
|
|
mg_response_header_start(conn, 200);
|
|
mg_response_header_start(conn, 200);
|
|
send_no_cache_header(conn);
|
|
send_no_cache_header(conn);
|
|
send_additional_header(conn);
|
|
send_additional_header(conn);
|
|
|
|
+ send_cors_header(conn);
|
|
mg_response_header_add(conn, "Content-Type", mime_type, -1);
|
|
mg_response_header_add(conn, "Content-Type", mime_type, -1);
|
|
if (content_length < 0) {
|
|
if (content_length < 0) {
|
|
/* Size not known. Use chunked encoding (HTTP/1.x) */
|
|
/* Size not known. Use chunked encoding (HTTP/1.x) */
|
|
@@ -4621,11 +4648,11 @@ mg_send_http_redirect(struct mg_connection *conn,
|
|
* 307 | temporary | always keep method | HTTP/1.1
|
|
* 307 | temporary | always keep method | HTTP/1.1
|
|
* 308 | permanent | always keep method | HTTP/1.1
|
|
* 308 | permanent | always keep method | HTTP/1.1
|
|
*/
|
|
*/
|
|
- const char *redirect_text;
|
|
|
|
- int ret;
|
|
|
|
size_t content_len = 0;
|
|
size_t content_len = 0;
|
|
|
|
+
|
|
#if defined(MG_SEND_REDIRECT_BODY)
|
|
#if defined(MG_SEND_REDIRECT_BODY)
|
|
- char reply[MG_BUF_LEN];
|
|
|
|
|
|
+ char redirect_body[MG_BUF_LEN];
|
|
|
|
+ char content_len_text[32];
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* In case redirect_code=0, use 307. */
|
|
/* In case redirect_code=0, use 307. */
|
|
@@ -4641,9 +4668,6 @@ mg_send_http_redirect(struct mg_connection *conn,
|
|
return -2;
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Get proper text for response code */
|
|
|
|
- redirect_text = mg_get_response_code_text(conn, redirect_code);
|
|
|
|
-
|
|
|
|
/* If target_url is not defined, redirect to "/". */
|
|
/* If target_url is not defined, redirect to "/". */
|
|
if ((target_url == NULL) || (*target_url == 0)) {
|
|
if ((target_url == NULL) || (*target_url == 0)) {
|
|
target_url = "/";
|
|
target_url = "/";
|
|
@@ -4675,8 +4699,8 @@ mg_send_http_redirect(struct mg_connection *conn,
|
|
mg_snprintf(
|
|
mg_snprintf(
|
|
conn,
|
|
conn,
|
|
NULL /* ignore truncation */,
|
|
NULL /* ignore truncation */,
|
|
- reply,
|
|
|
|
- sizeof(reply),
|
|
|
|
|
|
+ redirect_body,
|
|
|
|
+ sizeof(redirect_body),
|
|
"<html><head>%s</head><body><a href=\"%s\">%s</a></body></html>",
|
|
"<html><head>%s</head><body><a href=\"%s\">%s</a></body></html>",
|
|
redirect_text,
|
|
redirect_text,
|
|
target_url,
|
|
target_url,
|
|
@@ -4684,30 +4708,39 @@ mg_send_http_redirect(struct mg_connection *conn,
|
|
content_len = strlen(reply);
|
|
content_len = strlen(reply);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- /* Do not send any additional header. For all other options,
|
|
|
|
- * including caching, there are suitable defaults. */
|
|
|
|
- ret = mg_printf(conn,
|
|
|
|
- "HTTP/1.1 %i %s\r\n"
|
|
|
|
- "Location: %s\r\n"
|
|
|
|
- "Content-Length: %u\r\n"
|
|
|
|
- "Connection: %s\r\n\r\n",
|
|
|
|
- redirect_code,
|
|
|
|
- redirect_text,
|
|
|
|
- target_url,
|
|
|
|
- (unsigned int)content_len,
|
|
|
|
- suggest_connection_header(conn));
|
|
|
|
|
|
+ /* Do not send a cache header, there are suitable defaults.
|
|
|
|
+ * Thus, send_(no)_cache_header is not called here.xxxxxx
|
|
|
|
+ */
|
|
|
|
+ mg_response_header_start(conn, redirect_code);
|
|
|
|
+ mg_response_header_add(conn, "Location", target_url, -1);
|
|
|
|
+ if ((redirect_code == 301) || (redirect_code == 308)) {
|
|
|
|
+ /* Permanent redirect */
|
|
|
|
+ send_static_cache_header(conn);
|
|
|
|
+ } else {
|
|
|
|
+ /* Temporary redirect */
|
|
|
|
+ send_no_cache_header(conn);
|
|
|
|
+ }
|
|
|
|
+ send_additional_header(conn);
|
|
|
|
+ send_cors_header(conn);
|
|
|
|
+#if defined(MG_SEND_REDIRECT_BODY)
|
|
|
|
+ mg_response_header_add(conn, "Content-Type", "text/html", -1);
|
|
|
|
+ sprintf(content_len_text, "%lu", (unsigned long)content_len_text);
|
|
|
|
+ mg_response_header_add(conn, "Content-Length", content_len_text, -1);
|
|
|
|
+#else
|
|
|
|
+ mg_response_header_add(conn, "Content-Length", "0", 1);
|
|
|
|
+#endif
|
|
|
|
+ mg_response_header_send(conn);
|
|
|
|
+
|
|
|
|
|
|
#if defined(MG_SEND_REDIRECT_BODY)
|
|
#if defined(MG_SEND_REDIRECT_BODY)
|
|
/* Send response body */
|
|
/* Send response body */
|
|
- if (ret > 0) {
|
|
|
|
- /* ... unless it is a HEAD request */
|
|
|
|
- if (0 != strcmp(conn->request_info.request_method, "HEAD")) {
|
|
|
|
- ret = mg_write(conn, reply, content_len);
|
|
|
|
- }
|
|
|
|
|
|
+ /* ... unless it is a HEAD request */
|
|
|
|
+ if (0 != strcmp(conn->request_info.request_method, "HEAD")) {
|
|
|
|
+ ret = mg_write(conn, redirect_body, content_len);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- return (ret > 0) ? ret : -1;
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -10055,9 +10088,6 @@ handle_static_file_request(struct mg_connection *conn,
|
|
int n, truncated;
|
|
int n, truncated;
|
|
char gz_path[UTF8_PATH_MAX];
|
|
char gz_path[UTF8_PATH_MAX];
|
|
const char *encoding = 0;
|
|
const char *encoding = 0;
|
|
- const char *origin_hdr;
|
|
|
|
- const char *cors_orig_cfg;
|
|
|
|
- const char *cors1, *cors2;
|
|
|
|
int is_head_request;
|
|
int is_head_request;
|
|
|
|
|
|
#if defined(USE_ZLIB)
|
|
#if defined(USE_ZLIB)
|
|
@@ -10198,21 +10228,6 @@ handle_static_file_request(struct mg_connection *conn,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- /* Standard CORS header */
|
|
|
|
- cors_orig_cfg = conn->dom_ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN];
|
|
|
|
- origin_hdr = mg_get_header(conn, "Origin");
|
|
|
|
- if (cors_orig_cfg && *cors_orig_cfg && origin_hdr) {
|
|
|
|
- /* Cross-origin resource sharing (CORS), see
|
|
|
|
- * http://www.html5rocks.com/en/tutorials/cors/,
|
|
|
|
- * http://www.html5rocks.com/static/images/cors_server_flowchart.png
|
|
|
|
- * -
|
|
|
|
- * preflight is not supported for files. */
|
|
|
|
- cors1 = "Access-Control-Allow-Origin";
|
|
|
|
- cors2 = cors_orig_cfg;
|
|
|
|
- } else {
|
|
|
|
- cors1 = cors2 = "";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* Prepare Etag, and Last-Modified headers. */
|
|
/* Prepare Etag, and Last-Modified headers. */
|
|
gmt_time_string(lm, sizeof(lm), &filep->stat.last_modified);
|
|
gmt_time_string(lm, sizeof(lm), &filep->stat.last_modified);
|
|
construct_etag(etag, sizeof(etag), &filep->stat);
|
|
construct_etag(etag, sizeof(etag), &filep->stat);
|
|
@@ -10221,13 +10236,11 @@ handle_static_file_request(struct mg_connection *conn,
|
|
mg_response_header_start(conn, conn->status_code);
|
|
mg_response_header_start(conn, conn->status_code);
|
|
send_static_cache_header(conn);
|
|
send_static_cache_header(conn);
|
|
send_additional_header(conn);
|
|
send_additional_header(conn);
|
|
|
|
+ send_cors_header(conn);
|
|
mg_response_header_add(conn,
|
|
mg_response_header_add(conn,
|
|
"Content-Type",
|
|
"Content-Type",
|
|
mime_vec.ptr,
|
|
mime_vec.ptr,
|
|
(int)mime_vec.len);
|
|
(int)mime_vec.len);
|
|
- if (cors1[0] != 0) {
|
|
|
|
- mg_response_header_add(conn, cors1, cors2, -1);
|
|
|
|
- }
|
|
|
|
mg_response_header_add(conn, "Last-Modified", lm, -1);
|
|
mg_response_header_add(conn, "Last-Modified", lm, -1);
|
|
mg_response_header_add(conn, "Etag", etag, -1);
|
|
mg_response_header_add(conn, "Etag", etag, -1);
|
|
|
|
|
|
@@ -12406,22 +12419,11 @@ handle_ssi_file_request(struct mg_connection *conn,
|
|
{
|
|
{
|
|
char date[64];
|
|
char date[64];
|
|
time_t curtime = time(NULL);
|
|
time_t curtime = time(NULL);
|
|
- const char *cors_orig_cfg;
|
|
|
|
- const char *cors1, *cors2;
|
|
|
|
|
|
|
|
if ((conn == NULL) || (path == NULL) || (filep == NULL)) {
|
|
if ((conn == NULL) || (path == NULL) || (filep == NULL)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- cors_orig_cfg = conn->dom_ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN];
|
|
|
|
- if (cors_orig_cfg && *cors_orig_cfg && mg_get_header(conn, "Origin")) {
|
|
|
|
- /* Cross-origin resource sharing (CORS). */
|
|
|
|
- cors1 = "Access-Control-Allow-Origin";
|
|
|
|
- cors2 = cors_orig_cfg;
|
|
|
|
- } else {
|
|
|
|
- cors1 = cors2 = "";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (!mg_fopen(conn, path, MG_FOPEN_MODE_READ, filep)) {
|
|
if (!mg_fopen(conn, path, MG_FOPEN_MODE_READ, filep)) {
|
|
/* File exists (precondition for calling this function),
|
|
/* File exists (precondition for calling this function),
|
|
* but can not be opened by the server. */
|
|
* but can not be opened by the server. */
|
|
@@ -12441,10 +12443,8 @@ handle_ssi_file_request(struct mg_connection *conn,
|
|
mg_response_header_start(conn, 200);
|
|
mg_response_header_start(conn, 200);
|
|
send_no_cache_header(conn);
|
|
send_no_cache_header(conn);
|
|
send_additional_header(conn);
|
|
send_additional_header(conn);
|
|
|
|
+ send_cors_header(conn);
|
|
mg_response_header_add(conn, "Content-Type", "text/html", -1);
|
|
mg_response_header_add(conn, "Content-Type", "text/html", -1);
|
|
- if (cors1[0]) {
|
|
|
|
- mg_response_header_add(conn, cors1, cors2, -1);
|
|
|
|
- }
|
|
|
|
mg_response_header_send(conn);
|
|
mg_response_header_send(conn);
|
|
|
|
|
|
/* Header sent, now send body */
|
|
/* Header sent, now send body */
|