Parcourir la source

Add support for access_control_allow_headers

bel2125 il y a 8 ans
Parent
commit
158e71c8e6
2 fichiers modifiés avec 45 ajouts et 14 suppressions
  1. 31 13
      src/civetweb.c
  2. 14 1
      test/cors.reply.lua

+ 31 - 13
src/civetweb.c

@@ -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;
 		}
 	}

+ 14 - 1
test/cors.reply.lua

@@ -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")
+