Add support for access_control_allow_headers

This commit is contained in:
bel2125 2017-06-15 23:56:43 +02:00
parent a5c3f6514a
commit 158e71c8e6
2 changed files with 45 additions and 14 deletions

View File

@ -1880,7 +1880,8 @@ enum {
#endif
ACCESS_CONTROL_ALLOW_ORIGIN,
ACCESS_CONTROL_ALLOW_METHOD,
ACCESS_CONTROL_ALLOW_METHODS,
ACCESS_CONTROL_ALLOW_HEADERS,
ERROR_PAGES,
CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the
* socket option typedef TCP_NODELAY. */
@ -1977,7 +1978,8 @@ static struct mg_option config_options[] = {
{"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
#endif
{"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
{"access_control_allow_method", CONFIG_TYPE_STRING, "*"},
{"access_control_allow_methods", CONFIG_TYPE_STRING, "*"},
{"access_control_allow_headers", CONFIG_TYPE_STRING, "*"},
{"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
{"tcp_nodelay", CONFIG_TYPE_NUMBER, "0"},
#if !defined(NO_CACHING)
@ -11473,14 +11475,20 @@ handle_request(struct mg_connection *conn)
*/
if (!strcmp(ri->request_method, "OPTIONS")) {
/* Send a response to CORS preflights only if
* access_control_allow_method is not NULL and not an empty string.
* access_control_allow_methods is not NULL and not an empty string.
* In this case, scripts can still handle CORS. */
const char *cors_server_cfg =
conn->ctx->config[ACCESS_CONTROL_ALLOW_METHOD];
const char *cors_meth_cfg =
conn->ctx->config[ACCESS_CONTROL_ALLOW_METHODS];
const char *cors_orig_cfg =
conn->ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN];
const char *cors_origin = get_header(ri, "Origin");
const char *cors_acrm = get_header(ri, "Access-Control-Request-Method");
if ((cors_server_cfg != NULL) && (*cors_server_cfg != 0)
/* Todo: check if cors_origin is in cors_orig_cfg.
* Or, let the client check this. */
(void)cors_origin;
if ((cors_meth_cfg != NULL) && (*cors_meth_cfg != 0)
&& (cors_origin != NULL) && (cors_acrm != NULL)) {
/* This is a valid CORS preflight, and the server is configured to
* handle it automatically. */
@ -11496,20 +11504,30 @@ handle_request(struct mg_connection *conn)
"Content-Length: 0\r\n"
"Connection: %s\r\n",
date,
cors_origin,
((cors_server_cfg[0] == '*') ? cors_acrm
: cors_server_cfg),
cors_orig_cfg,
((cors_meth_cfg[0] == '*') ? cors_acrm : cors_meth_cfg),
suggest_connection_header(conn));
if (cors_acrh != NULL) {
mg_printf(conn,
"Access-Control-Allow-Headers: %s\r\n",
cors_acrh);
/* CORS request is asking for additional headers */
const char *cors_hdr_cfg =
conn->ctx->config[ACCESS_CONTROL_ALLOW_HEADERS];
if ((cors_hdr_cfg != NULL) && (*cors_hdr_cfg != 0)) {
/* Allow only if access_control_allow_headers is
* not NULL and not an empty string. If this
* configuration is set to *, allow everything.
* Otherwise this configuration must be a list
* of allowed HTTP header names. */
mg_printf(conn,
"Access-Control-Allow-Headers: %s\r\n",
((cors_hdr_cfg[0] == '*') ? cors_acrh
: cors_hdr_cfg));
}
}
mg_printf(conn, "Access-Control-Max-Age: 60\r\n");
mg_printf(conn, "\r\n");
return;
}
}

View File

@ -1,6 +1,7 @@
-- http://www.html5rocks.com/static/images/cors_server_flowchart.png
if not mg.request_info.http_headers.Origin then
if not mg.request_info.http_headers.Origin and not mg.request_info.http_headers.origin then
mg.write("HTTP/1.0 200 OK\r\n")
mg.write("Connection: close\r\n")
mg.write("Content-Type: text/html; charset=utf-8\r\n")
@ -11,6 +12,13 @@ end
if mg.request_info.request_method == "OPTIONS" then
-- Note: This is a test example showing how a script could handle
-- a preflight request directly. However, now the server is able
-- to handle preflight requests, so scripts do no longer need to
-- do this - except it has been disabled in the server by setting
-- the access_control_allow_methods configuration parameter to
-- an empty string.
local acrm = mg.request_info.http_headers['Access-Control-Request-Method'];
if (acrm) then
local acrh = nil -- mg.request_info.http_headers['Access-Control-Request-Header'];
@ -36,8 +44,10 @@ if mg.request_info.request_method == "OPTIONS" then
end
end
-- actual request
if mg.request_info.request_method == "GET" then
mg.write("HTTP/1.0 200 OK\r\n")
mg.write("Access-Control-Allow-Origin: *\r\n")
mg.write("Connection: close\r\n")
@ -54,6 +64,7 @@ end
if mg.request_info.request_method == "PUT" then
mg.write("HTTP/1.0 200 OK\r\n")
mg.write("Access-Control-Allow-Origin: *\r\n")
mg.write("Connection: close\r\n")
@ -68,6 +79,8 @@ if mg.request_info.request_method == "PUT" then
return
end
-- other HTTP method
mg.write("HTTP/1.0 403 Forbidden\r\n")
mg.write("Connection: close\r\n")
mg.write("\r\n")