Title: [283427] trunk/Tools
Revision
283427
Author
commit-qu...@webkit.org
Date
2021-10-01 17:22:27 -0700 (Fri, 01 Oct 2021)

Log Message

Implement HTTPS proxy in HTTPServer
https://bugs.webkit.org/show_bug.cgi?id=231109

Patch by Alex Christensen <achristen...@webkit.org> on 2021-10-01
Reviewed by Geoff Garen.

Previously we used TCPServer for this, which is picky about the exact number of connections, requests, and replies.
If everything isn't perfect, it hangs in the TCPServer destructor.
It also doesn't run the server logic on the main thread.
This will allow migration to HTTPServer, the replacement for TCPServer.

* TestWebKitAPI/Tests/WebKitCocoa/Proxy.mm:
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/HTTPServer.h:
* TestWebKitAPI/cocoa/HTTPServer.mm:
(TestWebKitAPI::proxyDefinition):
(TestWebKitAPI::HTTPServer::listenerParameters):
(TestWebKitAPI::HTTPServer::respondWithOK):
(TestWebKitAPI::HTTPServer::request const):

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (283426 => 283427)


--- trunk/Tools/ChangeLog	2021-10-01 23:52:38 UTC (rev 283426)
+++ trunk/Tools/ChangeLog	2021-10-02 00:22:27 UTC (rev 283427)
@@ -1,3 +1,24 @@
+2021-10-01  Alex Christensen  <achristen...@webkit.org>
+
+        Implement HTTPS proxy in HTTPServer
+        https://bugs.webkit.org/show_bug.cgi?id=231109
+
+        Reviewed by Geoff Garen.
+
+        Previously we used TCPServer for this, which is picky about the exact number of connections, requests, and replies.
+        If everything isn't perfect, it hangs in the TCPServer destructor.
+        It also doesn't run the server logic on the main thread.
+        This will allow migration to HTTPServer, the replacement for TCPServer.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/Proxy.mm:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/cocoa/HTTPServer.h:
+        * TestWebKitAPI/cocoa/HTTPServer.mm:
+        (TestWebKitAPI::proxyDefinition):
+        (TestWebKitAPI::HTTPServer::listenerParameters):
+        (TestWebKitAPI::HTTPServer::respondWithOK):
+        (TestWebKitAPI::HTTPServer::request const):
+
 2021-10-01  Jonathan Bedard  <jbed...@apple.com>
 
         [webkitcorepy] Add TaskPool (Follow-up fix)

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Proxy.mm (283426 => 283427)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Proxy.mm	2021-10-01 23:52:38 UTC (rev 283426)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Proxy.mm	2021-10-02 00:22:27 UTC (rev 283427)
@@ -78,7 +78,7 @@
 
 TEST(WebKit, HTTPSProxy)
 {
-    TCPServer server(TCPServer::Protocol::HTTPSProxy, TCPServer::respondWithOK);
+    HTTPServer server(HTTPServer::respondWithOK, HTTPServer::Protocol::HttpsProxy);
 
     auto storeConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
     [storeConfiguration setHTTPSProxy:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]];

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h (283426 => 283427)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2021-10-01 23:52:38 UTC (rev 283426)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2021-10-02 00:22:27 UTC (rev 283427)
@@ -41,7 +41,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     struct RequestData;
-    enum class Protocol : uint8_t { Http, Https, HttpsWithLegacyTLS, Http2 };
+    enum class Protocol : uint8_t { Http, Https, HttpsWithLegacyTLS, Http2, HttpsProxy };
     using CertificateVerifier = Function<void(sec_protocol_metadata_t, sec_trust_t, sec_protocol_verify_complete_t)>;
 
     HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>>, Protocol = Protocol::Http, CertificateVerifier&& = nullptr, RetainPtr<SecIdentityRef>&& = nullptr, std::optional<uint16_t> port = { });

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (283426 => 283427)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2021-10-01 23:52:38 UTC (rev 283426)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2021-10-02 00:22:27 UTC (rev 283427)
@@ -52,11 +52,34 @@
     Vector<Connection> connections;
 };
 
+static RetainPtr<nw_protocol_definition_t> proxyDefinition()
+{
+    return adoptNS(nw_framer_create_definition("HttpsProxy", NW_FRAMER_CREATE_FLAGS_DEFAULT, [] (nw_framer_t framer) -> nw_framer_start_result_t {
+        nw_framer_set_input_handler(framer, [] (nw_framer_t framer) -> size_t {
+            nw_framer_parse_input(framer, 1, std::numeric_limits<uint32_t>::max(), nullptr, [retainedFramer = retainPtr(framer)](uint8_t*, size_t bufferLength, bool) mutable -> size_t {
+                const char* negotiationResponse = ""
+                    "HTTP/1.1 200 Connection Established\r\n"
+                    "Connection: close\r\n\r\n";
+                auto response = adoptNS(dispatch_data_create(negotiationResponse, strlen(negotiationResponse), nullptr, nullptr));
+                nw_framer_write_output_data(retainedFramer.get(), response.get());
+                nw_framer_mark_ready(retainedFramer.get());
+                nw_framer_pass_through_input(retainedFramer.get());
+                nw_framer_pass_through_output(retainedFramer.get());
+                retainedFramer = nullptr;
+                return bufferLength;
+            });
+            return 0;
+        });
+        return nw_framer_start_result_will_mark_ready;
+    }));
+}
+
 RetainPtr<nw_parameters_t> HTTPServer::listenerParameters(Protocol protocol, CertificateVerifier&& verifier, RetainPtr<SecIdentityRef>&& customTestIdentity, std::optional<uint16_t> port)
 {
     if (protocol != Protocol::Http && !customTestIdentity)
         customTestIdentity = testIdentity();
-    auto configureTLS = protocol == Protocol::Http ? makeBlockPtr(NW_PARAMETERS_DISABLE_PROTOCOL) : makeBlockPtr([protocol, verifier = WTFMove(verifier), testIdentity = WTFMove(customTestIdentity)] (nw_protocol_options_t protocolOptions) mutable {
+
+    auto configureTLS = [protocol, verifier = WTFMove(verifier), testIdentity = WTFMove(customTestIdentity)] (nw_protocol_options_t protocolOptions) mutable {
 #if HAVE(TLS_PROTOCOL_VERSION_T)
         auto options = adoptNS(nw_tls_copy_sec_protocol_options(protocolOptions));
         auto identity = adoptNS(sec_identity_create(testIdentity.get()));
@@ -75,10 +98,23 @@
         UNUSED_PARAM(protocolOptions);
         ASSERT_UNUSED(protocol, protocol != Protocol::HttpsWithLegacyTLS);
 #endif
-    });
-    auto parameters = adoptNS(nw_parameters_create_secure_tcp(configureTLS.get(), NW_PARAMETERS_DEFAULT_CONFIGURATION));
+    };
+
+    auto configureTLSBlock = protocol == Protocol::Http || protocol == Protocol::HttpsProxy ? makeBlockPtr(NW_PARAMETERS_DISABLE_PROTOCOL) : makeBlockPtr(WTFMove(configureTLS));
+    auto parameters = adoptNS(nw_parameters_create_secure_tcp(configureTLSBlock.get(), NW_PARAMETERS_DEFAULT_CONFIGURATION));
     if (port)
         nw_parameters_set_local_endpoint(parameters.get(), nw_endpoint_create_host("::", makeString(*port).utf8().data()));
+
+    if (protocol == Protocol::HttpsProxy) {
+        auto stack = adoptNS(nw_parameters_copy_default_protocol_stack(parameters.get()));
+        auto options = adoptNS(nw_framer_create_options(proxyDefinition().get()));
+        nw_protocol_stack_prepend_application_protocol(stack.get(), options.get());
+
+        auto tlsOptions = adoptNS(nw_tls_create_options());
+        configureTLS(tlsOptions.get());
+        nw_protocol_stack_prepend_application_protocol(stack.get(), tlsOptions.get());
+    }
+
     return parameters;
 }
 
@@ -160,8 +196,8 @@
     connection.receiveHTTPRequest([connection] (Vector<char>&&) {
         connection.send(
             "HTTP/1.1 200 OK\r\n"
-            "Content-Length: 13\r\n\r\n"
-            "Hello, World!"
+            "Content-Length: 34\r\n\r\n"
+            "<script>alert('success!')</script>"
         );
     });
 }
@@ -268,7 +304,7 @@
 
 NSURLRequest *HTTPServer::request(const String& path) const
 {
-    NSString *format;
+    NSString *format = nil;
     switch (m_protocol) {
     case Protocol::Http:
         format = @"http://127.0.0.1:%d%s";
@@ -278,6 +314,8 @@
     case Protocol::Http2:
         format = @"https://127.0.0.1:%d%s";
         break;
+    case Protocol::HttpsProxy:
+        RELEASE_ASSERT_NOT_REACHED();
     }
     return [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:format, port(), path.utf8().data()]]];
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to