⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286751 in webkit


Ignore:
Timestamp:
Dec 8, 2021, 4:19:46 PM (5 years ago)
Author:
achristensen@apple.com
Message:

Add SPI to load a resource in the context of a page
https://bugs.webkit.org/show_bug.cgi?id=233908

Reviewed by Tim Horton.

Source/WebKit:

This is similar to startDownloadUsingRequest but you don't have to get the data from the disk.
This is similar to NSURLSession's dataTaskWithRequest:completionHandler: but using the same session as the page.
This is needed because LinkPresentation is currently using _getMainResourceDataWithCompletionHandler after loading
in a WKWebView made with _relatedWebView to get the content of a resource, and that's awful and limited to certain mime types.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::requestResource):

  • NetworkProcess/NetworkProcess.h:
  • NetworkProcess/NetworkProcess.messages.in:
  • NetworkProcess/NetworkSession.h:

(WebKit::NetworkSession::requestResource):

  • NetworkProcess/cocoa/NetworkSessionCocoa.h:
  • NetworkProcess/cocoa/NetworkSessionCocoa.mm:

(WebKit::NetworkSessionCocoa::requestResource):

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _requestResource:completionHandler:]):

  • UIProcess/API/Cocoa/WKWebViewPrivate.h:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::requestResource):

  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::requestResource):

  • UIProcess/WebPageProxy.h:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm:

(TEST):

Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r286747 r286751  
     12021-12-08  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add SPI to load a resource in the context of a page
     4        https://bugs.webkit.org/show_bug.cgi?id=233908
     5
     6        Reviewed by Tim Horton.
     7
     8        This is similar to startDownloadUsingRequest but you don't have to get the data from the disk.
     9        This is similar to NSURLSession's dataTaskWithRequest:completionHandler: but using the same session as the page.
     10        This is needed because LinkPresentation is currently using _getMainResourceDataWithCompletionHandler after loading
     11        in a WKWebView made with _relatedWebView to get the content of a resource, and that's awful and limited to certain mime types.
     12
     13        * NetworkProcess/NetworkProcess.cpp:
     14        (WebKit::NetworkProcess::requestResource):
     15        * NetworkProcess/NetworkProcess.h:
     16        * NetworkProcess/NetworkProcess.messages.in:
     17        * NetworkProcess/NetworkSession.h:
     18        (WebKit::NetworkSession::requestResource):
     19        * NetworkProcess/cocoa/NetworkSessionCocoa.h:
     20        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     21        (WebKit::NetworkSessionCocoa::requestResource):
     22        * UIProcess/API/Cocoa/WKWebView.mm:
     23        (-[WKWebView _requestResource:completionHandler:]):
     24        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
     25        * UIProcess/Network/NetworkProcessProxy.cpp:
     26        (WebKit::NetworkProcessProxy::requestResource):
     27        * UIProcess/Network/NetworkProcessProxy.h:
     28        * UIProcess/WebPageProxy.cpp:
     29        (WebKit::WebPageProxy::requestResource):
     30        * UIProcess/WebPageProxy.h:
     31
    1322021-12-08  BJ Burg  <bburg@apple.com>
    233
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r286601 r286751  
    21702170}
    21712171
     2172void NetworkProcess::requestResource(WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, IPC::FormDataReference&& httpBody, CompletionHandler<void(IPC::DataReference, WebCore::ResourceResponse, WebCore::ResourceError)>&& completionHandler)
     2173{
     2174    request.setHTTPBody(httpBody.takeData());
     2175    if (auto* networkSession = m_networkSessions.get(sessionID))
     2176        networkSession->requestResource(pageID, WTFMove(request), WTFMove(completionHandler));
     2177    else
     2178        completionHandler({ }, { }, { });
     2179}
     2180
    21722181void NetworkProcess::setCacheModelSynchronouslyForTesting(CacheModel cacheModel, CompletionHandler<void()>&& completionHandler)
    21732182{
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r286012 r286751  
    456456#endif
    457457    void continueWillSendRequest(DownloadID, WebCore::ResourceRequest&&);
     458    void requestResource(WebPageProxyIdentifier, PAL::SessionID, WebCore::ResourceRequest&&, IPC::FormDataReference&&, CompletionHandler<void(IPC::DataReference, WebCore::ResourceResponse, WebCore::ResourceError)>&&);
    458459    void applicationDidEnterBackground();
    459460    void applicationWillEnterForeground();
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in

    r285121 r286751  
    5454    PublishDownloadProgress(WebKit::DownloadID downloadID, URL url, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
    5555#endif
     56    RequestResource(WebKit::WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest request, IPC::FormDataReference requestBody) -> (IPC::DataReference data, WebCore::ResourceResponse response, WebCore::ResourceError error) Async
    5657    ApplicationDidEnterBackground()
    5758    ApplicationWillEnterForeground()
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.h

    r286361 r286751  
    2727
    2828#include "AppPrivacyReport.h"
     29#include "DataReference.h"
    2930#include "NavigatingToAppBoundDomain.h"
    3031#include "NetworkNotificationManager.h"
     
    194195    virtual void removeNetworkWebsiteData(std::optional<WallTime>, std::optional<HashSet<WebCore::RegistrableDomain>>&&, CompletionHandler<void()>&& completionHandler) { completionHandler(); }
    195196
     197    virtual void requestResource(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&) { }
    196198    virtual void addWebPageNetworkParameters(WebPageProxyIdentifier, WebPageNetworkParameters&&) { }
    197199    virtual void removeWebPageNetworkParameters(WebPageProxyIdentifier) { }
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h

    r286355 r286751  
    163163#endif
    164164
     165    void requestResource(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&) final;
    165166    void addWebPageNetworkParameters(WebPageProxyIdentifier, WebPageNetworkParameters&&) final;
    166167    void removeWebPageNetworkParameters(WebPageProxyIdentifier) final;
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r286355 r286751  
    17741774}
    17751775
     1776void NetworkSessionCocoa::requestResource(WebPageProxyIdentifier pageID, WebCore::ResourceRequest&& request, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
     1777{
     1778    auto session = sessionWrapperForTask(pageID, request, WebCore::StoredCredentialsPolicy::Use, std::nullopt).session;
     1779    auto nsRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::UpdateHTTPBody);
     1780    auto completionBlock = makeBlockPtr([completionHandler = WTFMove(completionHandler)] (NSData *data, NSURLResponse *response, NSError *error) mutable {
     1781        completionHandler(IPC::DataReference { static_cast<const uint8_t*>(data.bytes), data.length }, WebCore::ResourceResponse { response }, WebCore::ResourceError { error });
     1782    });
     1783    [[session dataTaskWithRequest:nsRequest completionHandler:completionBlock.get()] resume];
     1784}
     1785
    17761786void NetworkSessionCocoa::removeWebPageNetworkParameters(WebPageProxyIdentifier pageID)
    17771787{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r286461 r286751  
    22182218}
    22192219
     2220- (void)_requestResource:(NSURLRequest *)request completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *))completionHandler
     2221{
     2222    _page->requestResource(request, [completionHandler = makeBlockPtr(completionHandler)] (Ref<WebCore::SharedBuffer>&& buffer, WebCore::ResourceResponse&& response, WebCore::ResourceError&& error) {
     2223        if (error.isNull())
     2224            return completionHandler(buffer->createNSData().get(), response.nsURLResponse(), nil);
     2225        completionHandler(nil, nil, error.nsError());
     2226    });
     2227}
     2228
    22202229- (void)_takeFindStringFromSelection:(id)sender
    22212230{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r286641 r286751  
    423423- (void)_startImageAnalysis:(NSString *)identifier WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    424424
     425- (void)_requestResource:(NSURLRequest *)request completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     426
    425427@end
    426428
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r286484 r286751  
    336336}
    337337
     338void NetworkProcessProxy::requestResource(WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
     339{
     340    sendWithAsyncReply(Messages::NetworkProcess::RequestResource(pageID, sessionID, request, IPC::FormDataReference(request.httpBody())), [completionHandler = WTFMove(completionHandler)] (IPC::DataReference&& data, WebCore::ResourceResponse&& response, WebCore::ResourceError&& error) mutable {
     341        auto buffer = SharedBuffer::create(data.data(), data.size());
     342        completionHandler(WTFMove(buffer), WTFMove(response), WTFMove(error));
     343    });
     344}
     345
    338346void NetworkProcessProxy::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void(WebsiteData)>&& completionHandler)
    339347{
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r286012 r286751  
    123123
    124124    DownloadProxy& createDownloadProxy(WebsiteDataStore&, WebProcessPool&, const WebCore::ResourceRequest&, const FrameInfoData&, WebPageProxy* originatingPage);
     125    void requestResource(WebPageProxyIdentifier, PAL::SessionID, WebCore::ResourceRequest&&, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&);
    125126
    126127    void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, CompletionHandler<void(WebsiteData)>&&);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r286705 r286751  
    63736373}
    63746374
     6375void WebPageProxy::requestResource(WebCore::ResourceRequest&& request, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
     6376{
     6377    websiteDataStore().networkProcess().requestResource(identifier(), sessionID(), WTFMove(request), WTFMove(completionHandler));
     6378}
     6379
    63756380void WebPageProxy::didChangeContentSize(const IntSize& size)
    63766381{
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r286705 r286751  
    13741374    void resumeDownload(const API::Data& resumeData, const String& path, CompletionHandler<void(DownloadProxy*)>&&);
    13751375    void downloadRequest(WebCore::ResourceRequest&&, CompletionHandler<void(DownloadProxy*)>&&);
     1376    void requestResource(WebCore::ResourceRequest&&, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&);
    13761377
    13771378    void advanceToNextMisspelling(bool startBeforeSelection);
  • trunk/Tools/ChangeLog

    r286746 r286751  
     12021-12-08  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add SPI to load a resource in the context of a page
     4        https://bugs.webkit.org/show_bug.cgi?id=233908
     5
     6        Reviewed by Tim Horton.
     7
     8        * TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm:
     9        (TEST):
     10
    1112021-12-08  J Pascoe  <j_pascoe@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm

    r285547 r286751  
    345345    EXPECT_EQ(webPID2, [webView2 _webProcessIdentifier]);
    346346}
     347
     348TEST(NetworkProcess, LoadResource)
     349{
     350    using namespace TestWebKitAPI;
     351    auto html = "<script>document.cookie='testkey=value'</script>";
     352    auto secondResponse = "second response";
     353    Vector<char> secondRequest;
     354    auto server = HTTPServer([&](const Connection& connection) {
     355        connection.receiveHTTPRequest([&, connection](Vector<char>&& request) {
     356            connection.send(HTTPResponse(html).serialize(), [&, connection] {
     357                connection.receiveHTTPRequest([&, connection](Vector<char>&& request) {
     358                    secondRequest = WTFMove(request);
     359                    connection.send(HTTPResponse(secondResponse).serialize());
     360                });
     361            });
     362        });
     363    });
     364    auto webView = adoptNS([TestWKWebView new]);
     365    [webView synchronouslyLoadRequest:server.request()];
     366
     367    __block bool done = false;
     368    RetainPtr<NSMutableURLRequest> postRequest = adoptNS([server.request() mutableCopy]);
     369    [postRequest setMainDocumentURL:postRequest.get().URL];
     370    [postRequest setHTTPMethod:@"POST"];
     371    auto requestBody = "request body";
     372    [postRequest setHTTPBody:[NSData dataWithBytes:requestBody length:strlen(requestBody)]];
     373    [webView _requestResource:postRequest.get() completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
     374        EXPECT_NULL(error);
     375        EXPECT_WK_STREQ(response.URL.absoluteString, postRequest.get().URL.absoluteString);
     376        EXPECT_EQ(data.length, strlen(secondResponse));
     377        EXPECT_TRUE(!memcmp(data.bytes, secondResponse, data.length));
     378        done = true;
     379    }];
     380    Util::run(&done);
     381    EXPECT_TRUE(strnstr(secondRequest.data(), "Cookie: testkey=value\r\n", secondRequest.size()));
     382    EXPECT_WK_STREQ(HTTPServer::parseBody(secondRequest), requestBody);
     383
     384    done = false;
     385    [webView _requestResource:[NSURLRequest requestWithURL:[NSURL URLWithString:@"blob:blank"]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
     386        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
     387        EXPECT_EQ(error.code, NSURLErrorUnsupportedURL);
     388        EXPECT_NULL(data);
     389        EXPECT_NULL(response);
     390        done = true;
     391    }];
     392    Util::run(&done);
     393}
  • trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h

    r284418 r286751  
    6060    static void respondWithChallengeThenOK(Connection);
    6161    static String parsePath(const Vector<char>& request);
    62 
     62    static String parseBody(const Vector<char>&);
    6363    static Vector<uint8_t> testPrivateKey();
    6464    static Vector<uint8_t> testCertificate();
  • trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm

    r284977 r286751  
    323323    size_t pathLength = pathEnd - request.data() - pathPrefixLength;
    324324    return String(request.data() + pathPrefixLength, pathLength);
     325}
     326
     327String HTTPServer::parseBody(const Vector<char>& request)
     328{
     329    const char* headerEndBytes = "\r\n\r\n";
     330    const char* headerEnd = strnstr(request.data(), headerEndBytes, request.size()) + strlen(headerEndBytes);
     331    size_t headerLength = headerEnd - request.data();
     332    return String(headerEnd, request.size() - headerLength);
    325333}
    326334
Note: See TracChangeset for help on using the changeset viewer.