Changeset 220946 in webkit


Ignore:
Timestamp:
Aug 18, 2017 5:27:59 PM (7 years ago)
Author:
Chris Dumez
Message:

[Beacon] Improve error reporting
https://bugs.webkit.org/show_bug.cgi?id=175723

Reviewed by Darin Adler.

Source/WebCore:

Have Ping loads such as beacons report errors via their completion handler.
The Beacon API is using this error to log a console message when beacon loads
fail, provided that the page is still alive.

Test: http/wpt/beacon/beacon-async-error-logging.html

  • Modules/beacon/NavigatorBeacon.cpp:

(WebCore::NavigatorBeacon::NavigatorBeacon):
(WebCore::NavigatorBeacon::~NavigatorBeacon):
(WebCore::NavigatorBeacon::from):
(WebCore::NavigatorBeacon::supplementName):
(WebCore::NavigatorBeacon::notifyFinished):
(WebCore::NavigatorBeacon::logError):
(WebCore::NavigatorBeacon::sendBeacon):

  • Modules/beacon/NavigatorBeacon.h:
  • loader/LoaderStrategy.h:
  • loader/cache/CachedResource.cpp:

(WebCore::CachedResource::load):

  • loader/cache/CachedResourceLoader.cpp:

(WebCore::CachedResourceLoader::requestBeaconResource):

  • loader/cache/CachedResourceLoader.h:
  • platform/network/PingHandle.h:

Source/WebKit:

Have Ping loads such as beacons report errors via their completion handler.
The Beacon API is using this error to log a console message when beacon loads
fail, provided that the page is still alive.

  • NetworkProcess/NetworkConnectionToWebProcess.cpp:

(WebKit::NetworkConnectionToWebProcess::loadPing):
(WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):

  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/PingLoad.cpp:

(WebKit::PingLoad::~PingLoad):
(WebKit::PingLoad::didFinish):
(WebKit::PingLoad::willPerformHTTPRedirection):
(WebKit::PingLoad::didReceiveChallenge):
(WebKit::PingLoad::didReceiveResponseNetworkSession):
(WebKit::PingLoad::didCompleteWithError):
(WebKit::PingLoad::wasBlocked):
(WebKit::PingLoad::cannotShowURL):
(WebKit::PingLoad::timeoutTimerFired):
(WebKit::PingLoad::currentRequest const):
(WebKit::PingLoad::makeCrossOriginAccessRequestWithPreflight):

  • NetworkProcess/PingLoad.h:
  • WebProcess/Network/NetworkProcessConnection.cpp:

(WebKit::NetworkProcessConnection::didFinishPingLoad):

  • WebProcess/Network/NetworkProcessConnection.h:
  • WebProcess/Network/NetworkProcessConnection.messages.in:
  • WebProcess/Network/WebLoaderStrategy.cpp:

(WebKit::WebLoaderStrategy::networkProcessCrashed):
(WebKit::WebLoaderStrategy::startPingLoad):
(WebKit::WebLoaderStrategy::didFinishPingLoad):

  • WebProcess/Network/WebLoaderStrategy.h:

Source/WebKitLegacy:

Have Ping loads such as beacons report errors via their completion handler.
The Beacon API is using this error to log a console message when beacon loads
fail, provided that the page is still alive.

  • WebCoreSupport/WebResourceLoadScheduler.cpp:

(WebResourceLoadScheduler::startPingLoad):

  • WebCoreSupport/WebResourceLoadScheduler.h:

LayoutTests:

Add layout test coverage.

  • http/wpt/beacon/beacon-async-error-logging-expected.txt: Added.
  • http/wpt/beacon/beacon-async-error-logging.html: Added.
Location:
trunk
Files:
2 added
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r220944 r220946  
     12017-08-18  Chris Dumez  <cdumez@apple.com>
     2
     3        [Beacon] Improve error reporting
     4        https://bugs.webkit.org/show_bug.cgi?id=175723
     5
     6        Reviewed by Darin Adler.
     7
     8        Add layout test coverage.
     9
     10        * http/wpt/beacon/beacon-async-error-logging-expected.txt: Added.
     11        * http/wpt/beacon/beacon-async-error-logging.html: Added.
     12
    1132017-08-18  Matt Lewis  <jlewis3@apple.com>
    214
  • trunk/LayoutTests/http/wpt/beacon/beacon-quota-expected.txt

    r220922 r220946  
    1 CONSOLE MESSAGE: line 44: Reached maximum amount of queued data of 64Kb for keepalive requests
    2 CONSOLE MESSAGE: line 52: Reached maximum amount of queued data of 64Kb for keepalive requests
     1CONSOLE MESSAGE: line 44: Beacon API cannot load http://localhost:8800/. Reached maximum amount of queued data of 64Kb for keepalive requests
     2CONSOLE MESSAGE: line 52: Beacon API cannot load http://localhost:8800/. Reached maximum amount of queued data of 64Kb for keepalive requests
    33
    44PASS Beacon with a body above the Quota Limit should fail.
  • trunk/LayoutTests/http/wpt/beacon/beacon-quota.html

    r220922 r220946  
    5050
    5151        assert_true(navigator.sendBeacon(target, createPayload(expectedQuota)), "Beacon with a body at the Quota Limit should succeed.");
    52         assert_false(navigator.sendBeacon(target, createPayload(1)), "Second beacon should not be sent because we reached the quota");
     52        assert_false(navigator.sendBeacon("/", createPayload(1)), "Second beacon should not be sent because we reached the quota");
    5353        return waitForBeacon(id).then(function() {
    5454            assert_true(navigator.sendBeacon(target, createPayload(1)), "Allocated quota should be returned once the beacon is no longer in flight");
  • trunk/Source/WebCore/ChangeLog

    r220941 r220946  
     12017-08-18  Chris Dumez  <cdumez@apple.com>
     2
     3        [Beacon] Improve error reporting
     4        https://bugs.webkit.org/show_bug.cgi?id=175723
     5
     6        Reviewed by Darin Adler.
     7
     8        Have Ping loads such as beacons report errors via their completion handler.
     9        The Beacon API is using this error to log a console message when beacon loads
     10        fail, provided that the page is still alive.
     11
     12        Test: http/wpt/beacon/beacon-async-error-logging.html
     13
     14        * Modules/beacon/NavigatorBeacon.cpp:
     15        (WebCore::NavigatorBeacon::NavigatorBeacon):
     16        (WebCore::NavigatorBeacon::~NavigatorBeacon):
     17        (WebCore::NavigatorBeacon::from):
     18        (WebCore::NavigatorBeacon::supplementName):
     19        (WebCore::NavigatorBeacon::notifyFinished):
     20        (WebCore::NavigatorBeacon::logError):
     21        (WebCore::NavigatorBeacon::sendBeacon):
     22        * Modules/beacon/NavigatorBeacon.h:
     23        * loader/LoaderStrategy.h:
     24        * loader/cache/CachedResource.cpp:
     25        (WebCore::CachedResource::load):
     26        * loader/cache/CachedResourceLoader.cpp:
     27        (WebCore::CachedResourceLoader::requestBeaconResource):
     28        * loader/cache/CachedResourceLoader.h:
     29        * platform/network/PingHandle.h:
     30
    1312017-08-18  Sam Weinig  <sam@webkit.org>
    232
  • trunk/Source/WebCore/Modules/beacon/NavigatorBeacon.cpp

    r220928 r220946  
    2727#include "NavigatorBeacon.h"
    2828
     29#include "CachedRawResource.h"
    2930#include "CachedResourceLoader.h"
    3031#include "Document.h"
    3132#include "FetchBody.h"
     33#include "Frame.h"
    3234#include "HTTPParsers.h"
    3335#include "Navigator.h"
     
    3638namespace WebCore {
    3739
    38 ExceptionOr<bool> NavigatorBeacon::sendBeacon(Navigator&, Document& document, const String& url, std::optional<FetchBody::Init>&& body)
     40NavigatorBeacon::NavigatorBeacon(Navigator& navigator)
     41    : m_navigator(navigator)
     42{
     43}
     44
     45NavigatorBeacon::~NavigatorBeacon()
     46{
     47    for (auto& beacon : m_inflightBeacons)
     48        beacon->removeClient(*this);
     49}
     50
     51NavigatorBeacon* NavigatorBeacon::from(Navigator& navigator)
     52{
     53    auto* supplement = static_cast<NavigatorBeacon*>(Supplement<Navigator>::from(&navigator, supplementName()));
     54    if (!supplement) {
     55        auto newSupplement = std::make_unique<NavigatorBeacon>(navigator);
     56        supplement = newSupplement.get();
     57        provideTo(&navigator, supplementName(), WTFMove(newSupplement));
     58    }
     59    return supplement;
     60}
     61
     62const char* NavigatorBeacon::supplementName()
     63{
     64    return "NavigatorBeacon";
     65}
     66
     67void NavigatorBeacon::notifyFinished(CachedResource& resource)
     68{
     69    if (!resource.resourceError().isNull())
     70        logError(resource.resourceError());
     71
     72    resource.removeClient(*this);
     73    bool wasRemoved = m_inflightBeacons.removeFirst(&resource);
     74    ASSERT_UNUSED(wasRemoved, wasRemoved);
     75    ASSERT(!m_inflightBeacons.contains(&resource));
     76}
     77
     78void NavigatorBeacon::logError(const ResourceError& error)
     79{
     80    ASSERT(!error.isNull());
     81
     82    auto* frame = m_navigator.frame();
     83    if (!frame)
     84        return;
     85
     86    auto* document = frame->document();
     87    if (!document)
     88        return;
     89
     90    const char* messageMiddle = ". ";
     91    String description = error.localizedDescription();
     92    if (description.isEmpty()) {
     93        if (error.isAccessControl())
     94            messageMiddle = " due to access control checks.";
     95        else
     96            messageMiddle = ".";
     97    }
     98
     99    document->addConsoleMessage(MessageSource::Network, MessageLevel::Error, makeString(ASCIILiteral("Beacon API cannot load "), error.failingURL().string(), ASCIILiteral(messageMiddle), description));
     100}
     101
     102ExceptionOr<bool> NavigatorBeacon::sendBeacon(Document& document, const String& url, std::optional<FetchBody::Init>&& body)
    39103{
    40104    URL parsedUrl = document.completeURL(url);
     
    74138        }
    75139    }
     140
    76141    auto cachedResource = document.cachedResourceLoader().requestBeaconResource({ WTFMove(request), options });
    77     if (cachedResource)
    78         return true;
     142    if (!cachedResource) {
     143        logError(cachedResource.error());
     144        return false;
     145    }
    79146
    80     document.addConsoleMessage(MessageSource::Network, MessageLevel::Error, cachedResource.error().localizedDescription());
    81     return false;
     147    ASSERT(!m_inflightBeacons.contains(cachedResource.value().get()));
     148    m_inflightBeacons.append(cachedResource.value().get());
     149    cachedResource.value()->addClient(*this);
     150    return true;
     151}
     152
     153ExceptionOr<bool> NavigatorBeacon::sendBeacon(Navigator& navigator, Document& document, const String& url, std::optional<FetchBody::Init>&& body)
     154{
     155    return NavigatorBeacon::from(navigator)->sendBeacon(document, url, WTFMove(body));
    82156}
    83157
  • trunk/Source/WebCore/Modules/beacon/NavigatorBeacon.h

    r220303 r220946  
    2626#pragma once
    2727
     28#include "CachedRawResourceClient.h"
     29#include "CachedResourceHandle.h"
    2830#include "ExceptionOr.h"
    2931#include "FetchBody.h"
     32#include "Supplementable.h"
    3033#include <wtf/Forward.h>
    3134
    3235namespace WebCore {
    3336
     37class CachedRawResource;
    3438class Document;
    3539class Navigator;
     40class ResourceError;
    3641
    37 class NavigatorBeacon {
     42class NavigatorBeacon final : public Supplement<Navigator>, private CachedRawResourceClient {
    3843public:
     44    explicit NavigatorBeacon(Navigator&);
     45    ~NavigatorBeacon();
    3946    static ExceptionOr<bool> sendBeacon(Navigator&, Document&, const String& url, std::optional<FetchBody::Init>&&);
     47
     48private:
     49    ExceptionOr<bool> sendBeacon(Document&, const String& url, std::optional<FetchBody::Init>&&);
     50
     51    static NavigatorBeacon* from(Navigator&);
     52    static const char* supplementName();
     53
     54    void notifyFinished(CachedResource&) final;
     55    void logError(const ResourceError&);
     56
     57    Navigator& m_navigator;
     58    Vector<CachedResourceHandle<CachedRawResource>> m_inflightBeacons;
    4059};
    4160
  • trunk/Source/WebCore/loader/LoaderStrategy.h

    r220922 r220946  
    6565    virtual void resumePendingRequests() = 0;
    6666
    67     virtual void startPingLoad(NetworkingContext*, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy*, const FetchOptions&, WTF::Function<void()>&& completionHandler = { }) = 0;
     67    using PingLoadCompletionHandler = WTF::Function<void(const ResourceError&)>;
     68    virtual void startPingLoad(NetworkingContext*, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy*, const FetchOptions&, PingLoadCompletionHandler&& = { }) = 0;
    6869
    6970    virtual void storeDerivedDataToCache(const SHA1::Digest& bodyKey, const String& type, const String& partition, WebCore::SharedBuffer&) = 0;
  • trunk/Source/WebCore/loader/cache/CachedResource.cpp

    r220922 r220946  
    275275            ASSERT(m_originalRequestHeaders);
    276276            CachedResourceHandle<CachedResource> protectedThis(this);
    277             platformStrategies()->loaderStrategy()->startPingLoad(frame.loader().networkingContext(), request, *m_originalRequestHeaders, *m_origin, contentSecurityPolicy, m_options, [this, protectedThis = WTFMove(protectedThis)] {
    278                 finishLoading(nullptr);
     277            platformStrategies()->loaderStrategy()->startPingLoad(frame.loader().networkingContext(), request, *m_originalRequestHeaders, *m_origin, contentSecurityPolicy, m_options, [this, protectedThis = WTFMove(protectedThis)] (const ResourceError& error) {
     278                if (error.isNull())
     279                    finishLoading(nullptr);
     280                else {
     281                    setResourceError(error);
     282                    this->error(LoadError);
     283                }
    279284            });
    280285            return;
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r220888 r220946  
    297297}
    298298
    299 ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requestBeaconResource(CachedResourceRequest&& request)
    300 {
    301     return requestResource(CachedResource::Beacon, WTFMove(request));
     299ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestBeaconResource(CachedResourceRequest&& request)
     300{
     301    return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::Beacon, WTFMove(request)));
    302302}
    303303
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.h

    r220857 r220946  
    8484    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMedia(CachedResourceRequest&&);
    8585    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestIcon(CachedResourceRequest&&);
    86     ResourceErrorOr<CachedResourceHandle<CachedResource>> requestBeaconResource(CachedResourceRequest&&);
     86    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestBeaconResource(CachedResourceRequest&&);
    8787    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestRawResource(CachedResourceRequest&&);
    8888    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMainResource(CachedResourceRequest&&);
  • trunk/Source/WebCore/platform/network/PingHandle.h

    r220922 r220946  
    4444    };
    4545   
    46     PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects, WTF::Function<void()>&& completionHandler)
    47         : m_timeoutTimer(*this, &PingHandle::timeoutTimerFired)
     46    PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects, WTF::Function<void(const ResourceError&)>&& completionHandler)
     47        : m_currentRequest(request)
     48        , m_timeoutTimer(*this, &PingHandle::timeoutTimerFired)
    4849        , m_shouldUseCredentialStorage(shouldUseCredentialStorage)
    4950        , m_shouldFollowRedirects(shouldFollowRedirects)
     
    6566    void willSendRequestAsync(ResourceHandle* handle, ResourceRequest&& request, ResourceResponse&&) final
    6667    {
     68        m_currentRequest = WTFMove(request);
    6769        if (m_shouldFollowRedirects) {
    68             handle->continueWillSendRequest(WTFMove(request));
     70            handle->continueWillSendRequest(ResourceRequest { m_currentRequest });
    6971            return;
    7072        }
     73        pingLoadComplete(ResourceError { String(), 0, m_currentRequest.url(), ASCIILiteral("Not allowed to follow redirects"), ResourceError::Type::AccessControl });
     74    }
     75    void didReceiveResponse(ResourceHandle*, ResourceResponse&&) final { pingLoadComplete(); }
     76    void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int) final { pingLoadComplete(); }
     77    void didFinishLoading(ResourceHandle*) final { pingLoadComplete(); }
     78    void didFail(ResourceHandle*, const ResourceError& error) final { pingLoadComplete(error); }
     79    bool shouldUseCredentialStorage(ResourceHandle*) final { return m_shouldUseCredentialStorage; }
     80    bool usesAsyncCallbacks() final { return m_usesAsyncCallbacks == UsesAsyncCallbacks::Yes; }
     81    void timeoutTimerFired() { pingLoadComplete(ResourceError { String(), 0, m_currentRequest.url(), ASCIILiteral("Load timed out"), ResourceError::Type::Timeout }); }
     82
     83    void pingLoadComplete(const ResourceError& error = { })
     84    {
     85        if (auto completionHandler = std::exchange(m_completionHandler, nullptr))
     86            completionHandler(error);
    7187        delete this;
    7288    }
    73     void didReceiveResponse(ResourceHandle*, ResourceResponse&&) final { delete this; }
    74     void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int) final { delete this; };
    75     void didFinishLoading(ResourceHandle*) final { delete this; }
    76     void didFail(ResourceHandle*, const ResourceError&) final { delete this; }
    77     bool shouldUseCredentialStorage(ResourceHandle*) final { return m_shouldUseCredentialStorage; }
    78     bool usesAsyncCallbacks() final { return m_usesAsyncCallbacks == UsesAsyncCallbacks::Yes; }
    79     void timeoutTimerFired() { delete this; }
    8089
    8190    virtual ~PingHandle()
    8291    {
    83         if (m_completionHandler)
    84             m_completionHandler();
    85 
     92        ASSERT(!m_completionHandler);
    8693        if (m_handle) {
    8794            ASSERT(m_handle->client() == this);
     
    9299
    93100    RefPtr<ResourceHandle> m_handle;
     101    ResourceRequest m_currentRequest;
    94102    Timer m_timeoutTimer;
    95103    bool m_shouldUseCredentialStorage;
    96104    bool m_shouldFollowRedirects;
    97105    UsesAsyncCallbacks m_usesAsyncCallbacks;
    98     WTF::Function<void()> m_completionHandler;
     106    WTF::Function<void(const ResourceError&)> m_completionHandler;
    99107};
    100108
  • trunk/Source/WebKit/ChangeLog

    r220931 r220946  
     12017-08-18  Chris Dumez  <cdumez@apple.com>
     2
     3        [Beacon] Improve error reporting
     4        https://bugs.webkit.org/show_bug.cgi?id=175723
     5
     6        Reviewed by Darin Adler.
     7
     8        Have Ping loads such as beacons report errors via their completion handler.
     9        The Beacon API is using this error to log a console message when beacon loads
     10        fail, provided that the page is still alive.
     11
     12        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     13        (WebKit::NetworkConnectionToWebProcess::loadPing):
     14        (WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):
     15        * NetworkProcess/NetworkConnectionToWebProcess.h:
     16        * NetworkProcess/PingLoad.cpp:
     17        (WebKit::PingLoad::~PingLoad):
     18        (WebKit::PingLoad::didFinish):
     19        (WebKit::PingLoad::willPerformHTTPRedirection):
     20        (WebKit::PingLoad::didReceiveChallenge):
     21        (WebKit::PingLoad::didReceiveResponseNetworkSession):
     22        (WebKit::PingLoad::didCompleteWithError):
     23        (WebKit::PingLoad::wasBlocked):
     24        (WebKit::PingLoad::cannotShowURL):
     25        (WebKit::PingLoad::timeoutTimerFired):
     26        (WebKit::PingLoad::currentRequest const):
     27        (WebKit::PingLoad::makeCrossOriginAccessRequestWithPreflight):
     28        * NetworkProcess/PingLoad.h:
     29        * WebProcess/Network/NetworkProcessConnection.cpp:
     30        (WebKit::NetworkProcessConnection::didFinishPingLoad):
     31        * WebProcess/Network/NetworkProcessConnection.h:
     32        * WebProcess/Network/NetworkProcessConnection.messages.in:
     33        * WebProcess/Network/WebLoaderStrategy.cpp:
     34        (WebKit::WebLoaderStrategy::networkProcessCrashed):
     35        (WebKit::WebLoaderStrategy::startPingLoad):
     36        (WebKit::WebLoaderStrategy::didFinishPingLoad):
     37        * WebProcess/Network/WebLoaderStrategy.h:
     38
    1392017-08-18  Chris Dumez  <cdumez@apple.com>
    240
  • trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r220922 r220946  
    246246
    247247    // PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
    248     new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes, loadParameters.shouldFollowRedirects, [this, protectedThis = makeRef(*this), identifier = loadParameters.identifier] {
    249         didFinishPingLoad(identifier);
     248    new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes, loadParameters.shouldFollowRedirects, [this, protectedThis = makeRef(*this), identifier = loadParameters.identifier] (const ResourceError& error) {
     249        didFinishPingLoad(identifier, error);
    250250    });
    251251#endif
    252252}
    253253
    254 void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier)
     254void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier, const ResourceError& error)
    255255{
    256256    if (!m_connection->isValid())
    257257        return;
    258258
    259     m_connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(pingLoadIdentifier), 0);
     259    m_connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(pingLoadIdentifier, error), 0);
    260260}
    261261
  • trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h

    r220922 r220946  
    3939class BlobDataFileReference;
    4040class HTTPHeaderMap;
     41class ResourceError;
    4142class ResourceRequest;
    4243}
     
    6263
    6364    void didCleanupResourceLoader(NetworkResourceLoader&);
    64     void didFinishPingLoad(uint64_t pingLoadIdentifier);
     65    void didFinishPingLoad(uint64_t pingLoadIdentifier, const WebCore::ResourceError&);
    6566
    6667    bool captureExtraNetworkLoadMetricsEnabled() const { return m_captureExtraNetworkLoadMetricsEnabled; }
  • trunk/Source/WebKit/NetworkProcess/PingLoad.cpp

    r220922 r220946  
    3434#include "NetworkConnectionToWebProcess.h"
    3535#include "SessionTracker.h"
     36#include "WebErrors.h"
    3637#include <WebCore/ContentSecurityPolicy.h>
    3738#include <WebCore/CrossOriginAccessControl.h>
     
    6768PingLoad::~PingLoad()
    6869{
    69     m_connection->didFinishPingLoad(m_parameters.identifier);
    70 
    7170    if (m_redirectHandler)
    7271        m_redirectHandler({ });
     
    7776        m_task->cancel();
    7877    }
     78}
     79
     80void PingLoad::didFinish(const ResourceError& error)
     81{
     82    m_connection->didFinishPingLoad(m_parameters.identifier, error);
     83    delete this;
    7984}
    8085
     
    98103void PingLoad::willPerformHTTPRedirection(ResourceResponse&& redirectResponse, ResourceRequest&& request, RedirectCompletionHandler&& completionHandler)
    99104{
     105    m_lastRedirectionRequest = request;
     106
    100107    RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection - shouldFollowRedirects? %d", m_parameters.shouldFollowRedirects);
    101108    if (!m_parameters.shouldFollowRedirects) {
     
    150157    RELEASE_LOG_IF_ALLOWED("didReceiveChallenge");
    151158    completionHandler(AuthenticationChallengeDisposition::Cancel, { });
    152     delete this;
     159    didFinish(ResourceError { String(), 0, currentRequest().url(), ASCIILiteral("Failed HTTP authentication"), ResourceError::Type::AccessControl });
    153160}
    154161
     
    157164    RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession - httpStatusCode: %d", response.httpStatusCode());
    158165    completionHandler(PolicyAction::PolicyIgnore);
    159     delete this;
     166    didFinish();
    160167}
    161168
     
    172179    else
    173180        RELEASE_LOG_IF_ALLOWED("didCompleteWithError, error_code: %d", error.errorCode());
    174     delete this;
     181
     182    didFinish(error);
    175183}
    176184
     
    182190{
    183191    RELEASE_LOG_IF_ALLOWED("wasBlocked");
    184     delete this;
     192    didFinish(blockedError(currentRequest()));
    185193}
    186194
     
    188196{
    189197    RELEASE_LOG_IF_ALLOWED("cannotShowURL");
    190     delete this;
     198    didFinish(cannotShowURLError(currentRequest()));
    191199}
    192200
     
    194202{
    195203    RELEASE_LOG_IF_ALLOWED("timeoutTimerFired");
    196     delete this;
     204    didFinish(ResourceError { String(), 0, currentRequest().url(), ASCIILiteral("Load timed out"), ResourceError::Type::Timeout });
     205}
     206
     207const ResourceRequest& PingLoad::currentRequest() const
     208{
     209    if (m_lastRedirectionRequest)
     210        return *m_lastRedirectionRequest;
     211
     212    return m_parameters.request;
    197213}
    198214
     
    263279            preflightSuccess(ResourceRequest { corsPreflightChecker->originalRequest() });
    264280        else
    265             delete this;
     281            didFinish(ResourceError { String(), 0, corsPreflightChecker->originalRequest().url(), ASCIILiteral("CORS preflight failed"), ResourceError::Type::AccessControl });
    266282    });
    267283    m_corsPreflightChecker->startPreflight();
  • trunk/Source/WebKit/NetworkProcess/PingLoad.h

    r220922 r220946  
    3030#include "NetworkDataTask.h"
    3131#include "NetworkResourceLoadParameters.h"
     32#include <WebCore/ResourceError.h>
    3233
    3334namespace WebCore {
     
    6970
    7071    WebCore::SecurityOrigin& securityOrigin() const;
     72
     73    const WebCore::ResourceRequest& currentRequest() const;
     74    void didFinish(const WebCore::ResourceError& = { });
    7175   
    7276    NetworkResourceLoadParameters m_parameters;
     
    8185    RedirectCompletionHandler m_redirectHandler;
    8286    mutable std::unique_ptr<WebCore::ContentSecurityPolicy> m_contentSecurityPolicy;
     87    std::optional<WebCore::ResourceRequest> m_lastRedirectionRequest;
    8388};
    8489
  • trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp

    r220922 r220946  
    136136}
    137137
    138 void NetworkProcessConnection::didFinishPingLoad(uint64_t pingLoadIdentifier)
     138void NetworkProcessConnection::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error)
    139139{
    140     WebProcess::singleton().webLoaderStrategy().didFinishPingLoad(pingLoadIdentifier);
     140    WebProcess::singleton().webLoaderStrategy().didFinishPingLoad(pingLoadIdentifier, WTFMove(error));
    141141}
    142142
  • trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.h

    r220922 r220946  
    7474
    7575    void didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames);
    76     void didFinishPingLoad(uint64_t pingLoadIdentifier);
     76    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&);
    7777
    7878#if ENABLE(SHAREABLE_RESOURCE)
  • trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.messages.in

    r220922 r220946  
    2828
    2929    DidWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, Vector<String> filenames)
    30     DidFinishPingLoad(uint64_t pingLoadIdentifier)
     30    DidFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError error)
    3131}
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp

    r220922 r220946  
    354354    auto pingLoadCompletionHandlers = WTFMove(m_pingLoadCompletionHandlers);
    355355    for (auto& pingLoadCompletionHandler : pingLoadCompletionHandlers.values())
    356         pingLoadCompletionHandler();
     356        pingLoadCompletionHandler(internalError(URL()));
    357357}
    358358
     
    397397}
    398398
    399 void WebLoaderStrategy::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy* contentSecurityPolicy, const FetchOptions& options, WTF::Function<void()>&& completionHandler)
     399void WebLoaderStrategy::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy* contentSecurityPolicy, const FetchOptions& options, PingLoadCompletionHandler&& completionHandler)
    400400{
    401401    // It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists.
     
    403403    if (!networkingContext) {
    404404        if (completionHandler)
    405             completionHandler();
     405            completionHandler(internalError(request.url()));
    406406        return;
    407407    }
     
    430430}
    431431
    432 void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier)
     432void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error)
    433433{
    434434    if (auto completionHandler = m_pingLoadCompletionHandlers.take(pingLoadIdentifier))
    435         completionHandler();
     435        completionHandler(WTFMove(error));
    436436}
    437437
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h

    r220922 r220946  
    6060    void resumePendingRequests() final;
    6161
    62     void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, WTF::Function<void()>&& completionHandler) final;
    63     void didFinishPingLoad(uint64_t pingLoadIdentifier);
     62    void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, PingLoadCompletionHandler&&) final;
     63    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&);
    6464
    6565    void storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer&) final;
     
    8686    HashMap<unsigned long, RefPtr<WebResourceLoader>> m_webResourceLoaders;
    8787    HashMap<unsigned long, WebURLSchemeTaskProxy*> m_urlSchemeTasks;
    88     HashMap<unsigned long, WTF::Function<void()>> m_pingLoadCompletionHandlers;
     88    HashMap<unsigned long, PingLoadCompletionHandler> m_pingLoadCompletionHandlers;
    8989};
    9090
  • trunk/Source/WebKitLegacy/ChangeLog

    r220922 r220946  
     12017-08-18  Chris Dumez  <cdumez@apple.com>
     2
     3        [Beacon] Improve error reporting
     4        https://bugs.webkit.org/show_bug.cgi?id=175723
     5
     6        Reviewed by Darin Adler.
     7
     8        Have Ping loads such as beacons report errors via their completion handler.
     9        The Beacon API is using this error to log a console message when beacon loads
     10        fail, provided that the page is still alive.
     11
     12        * WebCoreSupport/WebResourceLoadScheduler.cpp:
     13        (WebResourceLoadScheduler::startPingLoad):
     14        * WebCoreSupport/WebResourceLoadScheduler.h:
     15
    1162017-08-18  Chris Dumez  <cdumez@apple.com>
    217
  • trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp

    r220922 r220946  
    364364}
    365365
    366 void WebResourceLoadScheduler::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap&, Ref<SecurityOrigin>&&, WebCore::ContentSecurityPolicy*, const FetchOptions& options, WTF::Function<void()>&& completionHandler)
     366void WebResourceLoadScheduler::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap&, Ref<SecurityOrigin>&&, WebCore::ContentSecurityPolicy*, const FetchOptions& options, PingLoadCompletionHandler&& completionHandler)
    367367{
    368368    // PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
  • trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h

    r220922 r220946  
    6060    void resumePendingRequests() final;
    6161
    62     void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, WTF::Function<void()>&& completionHandler) final;
     62    void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, PingLoadCompletionHandler&&) final;
    6363
    6464    void storeDerivedDataToCache(const SHA1::Digest&, const String&, const String&, WebCore::SharedBuffer&) final { }
Note: See TracChangeset for help on using the changeset viewer.