فهرست منبع

Allow using sub-domains in absolute URIs

This allows to match bucketA.s3.example.com and bucketB.s3.example.com if the authentication domain is set to s3.example.com
See comment https://github.com/civetweb/civetweb/issues/197#issuecomment-255186417
bel 8 سال پیش
والد
کامیت
3b4792d691
2فایلهای تغییر یافته به همراه59 افزوده شده و 5 حذف شده
  1. 32 4
      src/civetweb.c
  2. 27 1
      test/public_server.c

+ 32 - 4
src/civetweb.c

@@ -12496,6 +12496,8 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
 		return 0;
 	}
 
+/* Check if the request is directed to a different server. */
+/* First check if the port is the same (IPv4 and IPv6). */
 #if defined(USE_IPV6)
 	if (conn->client.lsa.sa.sa_family == AF_INET6) {
 		if (ntohs(conn->client.lsa.sin6.sin6_port) != port) {
@@ -12511,10 +12513,36 @@ get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
 		}
 	}
 
-	if ((request_domain_len != server_domain_len)
-	    || (0 != memcmp(server_domain, hostbegin, server_domain_len))) {
-		/* Request is directed to another server */
-		return 0;
+	/* Finally check if the server corresponds to the authentication
+	 * domain of the server (the server domain).
+	 * Allow full matches (like http://mydomain.com/path/file.ext), and
+	 * allow subdomain matches (like http://www.mydomain.com/path/file.ext),
+	 * but do not allow substrings (like http://notmydomain.com/path/file.ext
+	 * or http://mydomain.com.fake/path/file.ext).
+	 */
+	if ((request_domain_len == server_domain_len)
+	    && (!memcmp(server_domain, hostbegin, server_domain_len))) {
+		/* Request is directed to this server - full name match. */
+	} else {
+		if (request_domain_len < (server_domain_len + 2)) {
+			/* Request is directed to another server: The server name is longer
+			 * than
+			 * the request name. Drop this case here to avoid overflows in the
+			 * following checks. */
+			return 0;
+		}
+		if (hostbegin[request_domain_len - server_domain_len - 1] != '.') {
+			/* Request is directed to another server: It could be a substring
+			 * like notmyserver.com */
+			return 0;
+		}
+		if (0 != memcmp(server_domain,
+		                hostbegin + request_domain_len - server_domain_len,
+		                server_domain_len)) {
+			/* Request is directed to another server:
+			 * The server name is different. */
+			return 0;
+		}
 	}
 
 	return hostend;

+ 27 - 1
test/public_server.c

@@ -1455,6 +1455,32 @@ START_TEST(test_request_handlers)
 	ck_assert_str_eq(buf, expected);
 	mg_close_connection(client_conn);
 
+	/* Get data from callback using mg_connect_client and absolute URI with a
+	 * sub-domain */
+	memset(ebuf, 0, sizeof(ebuf));
+	client_conn =
+	    mg_connect_client("localhost", ipv4_port, 0, ebuf, sizeof(ebuf));
+	ck_assert(client_conn != NULL);
+	ck_assert_str_eq(ebuf, "");
+
+	mg_printf(client_conn,
+	          "GET http://subdomain.test.domain:%d/U7 HTTP/1.0\r\n\r\n",
+	          ipv4_port);
+
+	i = mg_get_response(client_conn, ebuf, sizeof(ebuf), 10000);
+	ck_assert_int_ge(i, 0);
+	ck_assert_str_eq(ebuf, "");
+
+	ri = mg_get_request_info(client_conn);
+
+	ck_assert(ri != NULL);
+	ck_assert_str_eq(ri->uri, "200");
+	i = mg_read(client_conn, buf, sizeof(buf));
+	ck_assert_int_eq(i, (int)strlen(expected));
+	buf[i] = 0;
+	ck_assert_str_eq(buf, expected);
+	mg_close_connection(client_conn);
+
 
 /* Websocket test */
 #ifdef USE_WEBSOCKET
@@ -2940,7 +2966,7 @@ MAIN_PUBLIC_SERVER(void)
 	test_threading(0);
 	test_mg_start_stop_http_server(0);
 	// test_mg_start_stop_https_server(0);
-	// test_request_handlers(0);
+	test_request_handlers(0);
 	// test_mg_server_and_client_tls(0);
 	// test_handle_form(0);
 	// test_http_auth(0);