Title: [252476] trunk/Tools
Revision
252476
Author
[email protected]
Date
2019-11-14 18:57:26 -0800 (Thu, 14 Nov 2019)

Log Message

Flaky API Test TestWebKitAPI.ServiceWorkers.ThrottleCrash
https://bugs.webkit.org/show_bug.cgi?id=203734

Patch by Alex Christensen <[email protected]> on 2019-11-14
Reviewed by Youenn Fablet.

Some API tests using TCPServer have multiple concurrent HTTP requests in flight at the same time.
When this happens, sometimes NSURLSession will make multiple TCP connections to the same server.
TCPServer is not the right tool for this because it handles all its connections manually.
To make the test server agnostic to how many connections are initiated, I introduce HTTPServer,
which uses the Network framework to handle as many responses and as many connections as happen.

* TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
* TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
(TEST):
* TestWebKitAPI/cocoa/HTTPServer.h: Added.
(TestWebKitAPI::HTTPServer::HTTPResponse::HTTPResponse):
* TestWebKitAPI/cocoa/HTTPServer.mm: Added.
(TestWebKitAPI::HTTPServer::HTTPServer):
(TestWebKitAPI::HTTPServer::respondToRequests):
(TestWebKitAPI::HTTPServer::port const):
(TestWebKitAPI::HTTPServer::request const):
* TestWebKitAPI/config.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (252475 => 252476)


--- trunk/Tools/ChangeLog	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/ChangeLog	2019-11-15 02:57:26 UTC (rev 252476)
@@ -1,3 +1,30 @@
+2019-11-14  Alex Christensen  <[email protected]>
+
+        Flaky API Test TestWebKitAPI.ServiceWorkers.ThrottleCrash
+        https://bugs.webkit.org/show_bug.cgi?id=203734
+
+        Reviewed by Youenn Fablet.
+
+        Some API tests using TCPServer have multiple concurrent HTTP requests in flight at the same time.
+        When this happens, sometimes NSURLSession will make multiple TCP connections to the same server.
+        TCPServer is not the right tool for this because it handles all its connections manually.
+        To make the test server agnostic to how many connections are initiated, I introduce HTTPServer,
+        which uses the Network framework to handle as many responses and as many connections as happen.
+
+        * TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
+        (TEST):
+        * TestWebKitAPI/cocoa/HTTPServer.h: Added.
+        (TestWebKitAPI::HTTPServer::HTTPResponse::HTTPResponse):
+        * TestWebKitAPI/cocoa/HTTPServer.mm: Added.
+        (TestWebKitAPI::HTTPServer::HTTPServer):
+        (TestWebKitAPI::HTTPServer::respondToRequests):
+        (TestWebKitAPI::HTTPServer::port const):
+        (TestWebKitAPI::HTTPServer::request const):
+        * TestWebKitAPI/config.h:
+
 2019-11-14  Jonathan Bedard  <[email protected]>
 
         Python 3: Add support in webkitpy.layout_tests.servers

Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig (252475 => 252476)


--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig	2019-11-15 02:57:26 UTC (rev 252476)
@@ -46,12 +46,18 @@
 WK_AUTHKIT_LDFLAGS_macosx = $(WK_AUTHKIT_LDFLAGS$(WK_MACOS_1015));
 WK_AUTHKIT_LDFLAGS_MACOS_SINCE_1015 = -framework AuthKit;
 
+WK_NETWORK_LDFLAGS = $(WK_NETWORK_LDFLAGS_$(WK_PLATFORM_NAME));
+WK_NETWORK_LDFLAGS_iphoneos = -framework Network;
+WK_NETWORK_LDFLAGS_iphonesimulator = -framework Network;
+WK_NETWORK_LDFLAGS_macosx = $(WK_NETWORK_LDFLAGS$(WK_MACOS_1014));
+WK_NETWORK_LDFLAGS_MACOS_SINCE_1014 = -framework Network;
+
 WK_PDFKIT_LDFLAGS = $(WK_PDFKIT_LDFLAGS_$(WK_PLATFORM_NAME));
 WK_PDFKIT_LDFLAGS_macosx = -framework PDFKit;
 WK_PDFKIT_LDFLAGS_iphoneos = -framework PDFKit;
 WK_PDFKIT_LDFLAGS_iphonesimulator = -framework PDFKit;
 
-OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework _javascript_Core -framework WebKit -lWebCoreTestSupport $(WK_AUTHKIT_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH));
+OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework _javascript_Core -framework WebKit -lWebCoreTestSupport $(WK_AUTHKIT_LDFLAGS) $(WK_NETWORK_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(OTHER_LDFLAGS_PLATFORM_$(WK_COCOA_TOUCH));
 OTHER_LDFLAGS_PLATFORM_ = -framework Cocoa -framework Carbon;
 
 // FIXME: This should not be built on iOS. Instead we should create and use a TestWebKitAPI application.

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (252475 => 252476)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-11-15 02:57:26 UTC (rev 252476)
@@ -386,6 +386,7 @@
 		5C7148952123A40A00FDE3C5 /* WKWebsiteDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C7148942123A40700FDE3C5 /* WKWebsiteDatastore.mm */; };
 		5C75716122124C5200B9E5AC /* BundleRetainPagePlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C75715F221249BD00B9E5AC /* BundleRetainPagePlugIn.mm */; };
 		5C7964101EB0278D0075D74C /* EventModifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C79640F1EB0269B0075D74C /* EventModifiers.cpp */; };
+		5C7C24FC237C975400599C91 /* HTTPServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C7C24FA237C972300599C91 /* HTTPServer.mm */; };
 		5C7C74CB1FB529BA002F9ABE /* WebViewScheduleInRunLoop.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C7C74CA1FB528D4002F9ABE /* WebViewScheduleInRunLoop.mm */; };
 		5C838F7F1DB04F900082858F /* LoadInvalidURLRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57901FAE1CAF137100ED64F9 /* LoadInvalidURLRequest.mm */; };
 		5C8BC799218CF44700813886 /* NetworkProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C8BC798218CF3E900813886 /* NetworkProcess.mm */; };
@@ -1947,6 +1948,8 @@
 		5C73A81A2323059800DEA85A /* TLSDeprecation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TLSDeprecation.mm; sourceTree = "<group>"; };
 		5C75715F221249BD00B9E5AC /* BundleRetainPagePlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundleRetainPagePlugIn.mm; sourceTree = "<group>"; };
 		5C79640F1EB0269B0075D74C /* EventModifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventModifiers.cpp; sourceTree = "<group>"; };
+		5C7C24FA237C972300599C91 /* HTTPServer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = HTTPServer.mm; path = cocoa/HTTPServer.mm; sourceTree = "<group>"; };
+		5C7C24FB237C972300599C91 /* HTTPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPServer.h; path = cocoa/HTTPServer.h; sourceTree = "<group>"; };
 		5C7C74CA1FB528D4002F9ABE /* WebViewScheduleInRunLoop.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewScheduleInRunLoop.mm; sourceTree = "<group>"; };
 		5C8BC798218CF3E900813886 /* NetworkProcess.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkProcess.mm; sourceTree = "<group>"; };
 		5C973F5B1F58EF0A00359C27 /* WebGLPolicy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebGLPolicy.mm; sourceTree = "<group>"; };
@@ -2753,6 +2756,8 @@
 				F46128B4211C861A00D9FADB /* DragAndDropSimulator.h */,
 				F44D06481F3962E3001A0E29 /* EditingTestHarness.h */,
 				F44D06491F3962E3001A0E29 /* EditingTestHarness.mm */,
+				5C7C24FB237C972300599C91 /* HTTPServer.h */,
+				5C7C24FA237C972300599C91 /* HTTPServer.mm */,
 				F44A530D21B8976900DBB99C /* InstanceMethodSwizzler.h */,
 				F44A531021B8976900DBB99C /* InstanceMethodSwizzler.mm */,
 				0F139E721A423A2B00F590F5 /* PlatformUtilitiesCocoa.mm */,
@@ -4666,6 +4671,7 @@
 				7C83E0501D0A641800FEBCF3 /* HTMLParserIdioms.cpp in Sources */,
 				5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */,
 				6B9ABE122086952F00D75DE6 /* HTTPParsers.cpp in Sources */,
+				5C7C24FC237C975400599C91 /* HTTPServer.mm in Sources */,
 				51AF23DF1EF1A3730072F281 /* IconLoadingDelegate.mm in Sources */,
 				510477781D29923B009747EB /* IDBDeleteRecovery.mm in Sources */,
 				5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (252475 => 252476)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2019-11-15 02:57:26 UTC (rev 252476)
@@ -25,6 +25,7 @@
 
 #import "config.h"
 
+#import "HTTPServer.h"
 #import "PlatformUtilities.h"
 #import "ServiceWorkerTCPServer.h"
 #import "Test.h"
@@ -50,7 +51,10 @@
 #import <wtf/text/WTFString.h>
 
 static bool done;
+
+#if HAVE(NETWORK_FRAMEWORK)
 static bool didFinishNavigation;
+#endif
 
 static String expectedMessage;
 static String retrievedString;
@@ -1685,7 +1689,9 @@
 }
 
 
-TEST(ServiceWorkers, DISABLED_ThrottleCrash)
+#if HAVE(NETWORK_FRAMEWORK)
+
+TEST(ServiceWorkers, ThrottleCrash)
 {
     [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
 
@@ -1698,10 +1704,9 @@
 
     auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
 
-    ServiceWorkerTCPServer server({
-        { "text/html", mainBytes },
-        { "application/_javascript_", scriptBytes },
-        { "text/html", mainBytes },
+    TestWebKitAPI::HTTPServer server({
+        { "/", { mainBytes } },
+        { "/sw.js", { scriptBytes, {{ "Content-Type", "application/_javascript_" }} } },
     });
 
     auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
@@ -1750,6 +1755,8 @@
     TestWebKitAPI::Util::run(&didFinishNavigation);
 }
 
+#endif // HAVE(NETWORK_FRAMEWORK)
+
 TEST(ServiceWorkers, LoadData)
 {
     [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm (252475 => 252476)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm	2019-11-15 02:57:26 UTC (rev 252476)
@@ -25,6 +25,7 @@
 
 #import "config.h"
 
+#import "HTTPServer.h"
 #import "PlatformUtilities.h"
 #import "TCPServer.h"
 #import "Test.h"
@@ -570,36 +571,14 @@
     EXPECT_FALSE(error);
 }
 
-TEST(WebKit, DISABLED_ApplicationCacheDirectories)
+#if HAVE(NETWORK_FRAMEWORK)
+
+TEST(WebKit, ApplicationCacheDirectories)
 {
-    using namespace TestWebKitAPI;
-    TCPServer server([] (int socket) {
-        TCPServer::read(socket);
-        const char* firstResponse =
-        "HTTP/1.1 200 OK\r\n"
-        "Content-Length: 31\r\n\r\n"
-        "<html manifest='test.appcache'>";
-        TCPServer::write(socket, firstResponse, strlen(firstResponse));
-        
-        TCPServer::read(socket);
-        const char* secondResponse =
-        "HTTP/1.1 200 OK\r\n"
-        "Content-Length: 35\r\n\r\n"
-        "CACHE MANIFEST\n"
-        "index.html\n"
-        "test.mp4\n";
-        TCPServer::write(socket, secondResponse, strlen(secondResponse));
-
-        TCPServer::read(socket);
-        TCPServer::write(socket, firstResponse, strlen(firstResponse));
-        
-        const char* videoResponse =
-        "HTTP/1.1 200 OK\r\n"
-        "Content-Type: video/test\r\n"
-        "Content-Length: 5\r\n\r\n"
-        "test!";
-        TCPServer::read(socket);
-        TCPServer::write(socket, videoResponse, strlen(videoResponse));
+    TestWebKitAPI::HTTPServer server({
+        { "/index.html", { "<html manifest='test.appcache'>" } },
+        { "/test.appcache", { "CACHE MANIFEST\nindex.html\ntest.mp4\n" } },
+        { "/test.mp4", { "test!", {{ "Content-Type", "video/test" }}}},
     });
     
     NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"CustomPathsTest"] isDirectory:YES];
@@ -620,7 +599,7 @@
     [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/index.html", server.port()]]]];
 
     while (![fileManager fileExistsAtPath:subdirectoryPath])
-        Util::spinRunLoop();
+        TestWebKitAPI::Util::spinRunLoop();
 
     NSError *error = nil;
     [fileManager removeItemAtPath:path error:&error];
@@ -627,6 +606,8 @@
     EXPECT_FALSE(error);
 }
 
+#endif // HAVE(NETWORK_FRAMEWORK)
+
 // FIXME: investigate why this test times out on High Sierra
 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(IOS_FAMILY)
 TEST(WebKit, MediaCache)

Added: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h (0 => 252476)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2019-11-15 02:57:26 UTC (rev 252476)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if HAVE(NETWORK_FRAMEWORK)
+
+#import <Network/Network.h>
+#import <wtf/Forward.h>
+#import <wtf/HashMap.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/text/StringHash.h>
+
+namespace TestWebKitAPI {
+
+class HTTPServer {
+public:
+    struct HTTPResponse;
+    HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>);
+    uint16_t port() const;
+    NSURLRequest *request() const;
+    
+private:
+    void respondToRequests(nw_connection_t);
+    
+    RetainPtr<nw_listener_t> m_listener;
+    const HashMap<String, HTTPResponse> m_requestResponseMap;
+};
+
+struct HTTPServer::HTTPResponse {
+    HTTPResponse(String&& body)
+        : body(WTFMove(body)) { }
+    HTTPResponse(String&& body, HashMap<String, String>&& headerFields)
+        : body(WTFMove(body))
+        , headerFields(WTFMove(headerFields)) { }
+
+    HTTPResponse(const HTTPResponse&) = default;
+    HTTPResponse(HTTPResponse&&) = default;
+    HTTPResponse() = default;
+    HTTPResponse& operator=(const HTTPResponse&) = default;
+    HTTPResponse& operator=(HTTPResponse&&) = default;
+    
+    String body;
+    HashMap<String, String> headerFields;
+};
+
+} // namespace TestWebKitAPI
+
+#endif // HAVE(NETWORK_FRAMEWORK)

Added: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (0 => 252476)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2019-11-15 02:57:26 UTC (rev 252476)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "HTTPServer.h"
+
+#if HAVE(NETWORK_FRAMEWORK)
+
+#import <wtf/text/StringBuilder.h>
+#import <wtf/text/WTFString.h>
+
+namespace TestWebKitAPI {
+
+HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> responses)
+    : m_requestResponseMap([](std::initializer_list<std::pair<String, HTTPServer::HTTPResponse>> list) {
+        HashMap<String, HTTPServer::HTTPResponse> map;
+        for (auto& pair : list)
+            map.add(pair.first, pair.second);
+        return map;
+    }(responses))
+{
+    auto parameters = adoptNS(nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION));
+    m_listener = adoptNS(nw_listener_create(parameters.get()));
+    nw_listener_set_queue(m_listener.get(), dispatch_get_main_queue());
+    nw_listener_set_new_connection_handler(m_listener.get(), ^(nw_connection_t connection) {
+        nw_connection_set_queue(connection, dispatch_get_main_queue());
+        nw_connection_start(connection);
+        respondToRequests(connection);
+    });
+    nw_listener_start(m_listener.get());
+}
+
+void HTTPServer::respondToRequests(nw_connection_t connection)
+{
+    nw_connection_receive(connection, 1, std::numeric_limits<uint32_t>::max(), ^(dispatch_data_t content, nw_content_context_t context, bool complete, nw_error_t error) {
+        ASSERT(!error);
+        if (!content)
+            return;
+        __block Vector<char> request;
+        dispatch_data_apply(content, ^bool(dispatch_data_t, size_t, const void* buffer, size_t size) {
+            request.append(static_cast<const char*>(buffer), size);
+            return true;
+        });
+        request.append(0);
+
+        const char* pathPrefix = "GET ";
+        const char* pathSuffix = " HTTP/1.1\r\n";
+        const char* pathEnd = strstr(request.data(), pathSuffix);
+        ASSERT_WITH_MESSAGE(pathEnd, "HTTPServer assumes request is HTTP 1.1");
+        ASSERT_WITH_MESSAGE(!memcmp(request.data(), pathPrefix, strlen(pathPrefix)), "HTTPServer assumes request is GET");
+        ASSERT_WITH_MESSAGE(strstr(request.data(), "\r\n\r\n"), "HTTPServer assumes entire HTTP request is received at once");
+        size_t pathLength = pathEnd - request.data() - strlen(pathPrefix);
+        String path(request.data() + strlen(pathPrefix), pathLength);
+        ASSERT_WITH_MESSAGE(m_requestResponseMap.contains(path), "This HTTPServer does not know how to respond to a request for %s", path.utf8().data());
+        
+        auto response = m_requestResponseMap.get(path);
+        StringBuilder responseBuilder;
+        responseBuilder.append("HTTP/1.1 200 OK\r\nContent-Length: ");
+        responseBuilder.appendNumber(response.body.length());
+        responseBuilder.append("\r\n");
+        for (auto& pair : response.headerFields) {
+            responseBuilder.append(pair.key);
+            responseBuilder.append(": ");
+            responseBuilder.append(pair.value);
+            responseBuilder.append("\r\n");
+        }
+        responseBuilder.append("\r\n");
+        responseBuilder.append(response.body);
+        auto responseBodyAndHeader = responseBuilder.toString().releaseImpl();
+        auto responseData = adoptNS(dispatch_data_create(responseBodyAndHeader->characters8(), responseBodyAndHeader->length(), dispatch_get_main_queue(), ^{
+            (void)responseBodyAndHeader;
+        }));
+        nw_connection_send(connection, responseData.get(), context, true, ^(nw_error_t error) {
+            ASSERT(!error);
+            respondToRequests(connection);
+        });
+    });
+}
+
+uint16_t HTTPServer::port() const
+{
+    return nw_listener_get_port(m_listener.get());
+}
+
+NSURLRequest *HTTPServer::request() const
+{
+    return [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", port()]]];
+}
+
+} // namespace TestWebKitAPI
+
+#endif // HAVE(NETWORK_FRAMEWORK)

Modified: trunk/Tools/TestWebKitAPI/config.h (252475 => 252476)


--- trunk/Tools/TestWebKitAPI/config.h	2019-11-15 02:56:43 UTC (rev 252475)
+++ trunk/Tools/TestWebKitAPI/config.h	2019-11-15 02:57:26 UTC (rev 252476)
@@ -118,3 +118,7 @@
 #if (PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)) || (PLATFORM(MACCATALYST) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101600)
 #define HAVE_UIWEBVIEW 1
 #endif
+
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(IOS)
+#define HAVE_NETWORK_FRAMEWORK 1
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to