Title: [281961] trunk/Source/WebKit
Revision
281961
Author
achristen...@apple.com
Date
2021-09-02 16:03:37 -0700 (Thu, 02 Sep 2021)

Log Message

Move PrivateClickMeasurementManager and PrivateClickMeasurementNetworkLoader into PrivateClickMeasurement directory
https://bugs.webkit.org/show_bug.cgi?id=229835

Reviewed by Tim Horton.

* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp.
(WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h.
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp.
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.h: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h.
* Sources.txt:
* WebKit.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (281960 => 281961)


--- trunk/Source/WebKit/ChangeLog	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/ChangeLog	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1,3 +1,18 @@
+2021-09-02  Alex Christensen  <achristen...@webkit.org>
+
+        Move PrivateClickMeasurementManager and PrivateClickMeasurementNetworkLoader into PrivateClickMeasurement directory
+        https://bugs.webkit.org/show_bug.cgi?id=229835
+
+        Reviewed by Tim Horton.
+
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp.
+        (WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h.
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp.
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.h: Renamed from Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h.
+        * Sources.txt:
+        * WebKit.xcodeproj/project.pbxproj:
+
 2021-09-02  Per Arne  <pvol...@apple.com>
 
         [iOS] Gather logs for IOKit class

Added: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp (0 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp	2021-09-02 23:03:37 UTC (rev 281961)
@@ -0,0 +1,567 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "PrivateClickMeasurementManager.h"
+
+#include "Logging.h"
+#include "NetworkSession.h"
+#include "PrivateClickMeasurementDebugInfo.h"
+#include <_javascript_Core/ConsoleTypes.h>
+#include <WebCore/FetchOptions.h>
+#include <WebCore/FormData.h>
+#include <WebCore/HTTPHeaderValues.h>
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/ResourceResponse.h>
+#include <WebCore/RuntimeApplicationChecks.h>
+#include <WebCore/RuntimeEnabledFeatures.h>
+#include <pal/crypto/CryptoDigest.h>
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+using SourceSite = PrivateClickMeasurement::SourceSite;
+using AttributionDestinationSite = PrivateClickMeasurement::AttributionDestinationSite;
+using AttributionTriggerData = PrivateClickMeasurement::AttributionTriggerData;
+using EphemeralSourceNonce = PrivateClickMeasurement::EphemeralSourceNonce;
+
+constexpr Seconds debugModeSecondsUntilSend { 10_s };
+
+PrivateClickMeasurementManager::PrivateClickMeasurementManager(UniqueRef<PCM::Client>&& client, const String& storageDirectory)
+    : m_firePendingAttributionRequestsTimer(*this, &PrivateClickMeasurementManager::firePendingAttributionRequests)
+    , m_storageDirectory(storageDirectory)
+    , m_client(WTFMove(client))
+{
+    // We should send any pending attributions on session-start in case their
+    // send delay has expired while the session was closed. Waiting 5 seconds accounts for the
+    // delay in database startup.
+    startTimer(5_s);
+}
+
+void PrivateClickMeasurementManager::storeUnattributed(PrivateClickMeasurement&& measurement)
+{
+    if (!featureEnabled())
+        return;
+
+    clearExpired();
+
+    if (measurement.ephemeralSourceNonce()) {
+        auto measurementCopy = measurement;
+        // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
+        getTokenPublicKey(WTFMove(measurementCopy), PrivateClickMeasurement::AttributionReportEndpoint::Source, PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& measurement, const String& publicKeyBase64URL) {
+            if (!weakThis)
+                return;
+
+            if (publicKeyBase64URL.isEmpty())
+                return;
+
+            if (m_fraudPreventionValuesForTesting)
+                measurement.setSourceUnlinkableTokenValue(m_fraudPreventionValuesForTesting->unlinkableToken);
+#if PLATFORM(COCOA)
+            else {
+                if (auto errorMessage = measurement.calculateAndUpdateSourceUnlinkableToken(publicKeyBase64URL)) {
+                    RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceUnlinkableToken(): '%{public}s", errorMessage->utf8().data());
+                    m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
+                    return;
+                }
+            }
+#endif
+
+            getSignedUnlinkableToken(WTFMove(measurement));
+            return;
+        });
+    }
+
+    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Storing a click."_s);
+
+    insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
+}
+
+static NetworkLoadParameters generateNetworkLoadParameters(URL&& url, const String& httpMethod, RefPtr<JSON::Object>&& jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
+{
+    ResourceRequest request { WTFMove(url) };
+    request.setHTTPMethod(httpMethod);
+    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, WebCore::HTTPHeaderValues::maxAge0());
+    if (jsonPayload) {
+        request.setHTTPContentType(WebCore::HTTPHeaderValues::applicationJSONContentType());
+        request.setHTTPBody(WebCore::FormData::create(jsonPayload->toJSONString().utf8().data()));
+    }
+
+    NetworkLoadParameters loadParameters;
+    loadParameters.request = request;
+    loadParameters.parentPID = presentingApplicationPID();
+    loadParameters.storedCredentialsPolicy = StoredCredentialsPolicy::EphemeralStateless;
+    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = true;
+    loadParameters.pcmDataCarried = UNLIKELY(isDebugModeEnabled) ? PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable : dataTypeCarried;
+
+    return loadParameters;
+}
+
+static NetworkLoadParameters generateNetworkLoadParametersForHttpPost(URL&& url, Ref<JSON::Object>&& jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
+{
+    return generateNetworkLoadParameters(WTFMove(url), "POST"_s, WTFMove(jsonPayload), dataTypeCarried, isDebugModeEnabled);
+}
+
+static NetworkLoadParameters generateNetworkLoadParametersForHttpGet(URL&& url, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
+{
+    return generateNetworkLoadParameters(WTFMove(url), "GET"_s, nullptr, dataTypeCarried, isDebugModeEnabled);
+}
+
+void PrivateClickMeasurementManager::getTokenPublicKey(PrivateClickMeasurement&& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried pcmDataCarried, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&& callback)
+{
+    if (!featureEnabled())
+        return;
+
+    auto tokenPublicKeyURL = attribution.tokenPublicKeyURL();
+    if (m_tokenPublicKeyURLForTesting) {
+        if (attributionReportEndpoint == PrivateClickMeasurement::AttributionReportEndpoint::Destination)
+            return;
+        tokenPublicKeyURL = *m_tokenPublicKeyURLForTesting;
+        // FIXME(225364)
+        pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
+    }
+
+    if (tokenPublicKeyURL.isEmpty() || !tokenPublicKeyURL.isValid())
+        return;
+
+    auto loadParameters = generateNetworkLoadParametersForHttpGet(WTFMove(tokenPublicKeyURL), pcmDataCarried, debugModeEnabled());
+
+    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a token public key request.");
+    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire a token public key request."_s);
+
+    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, attribution = WTFMove(attribution), callback = WTFMove(callback)] (auto& error, auto& response, auto& jsonObject) mutable {
+        if (!weakThis)
+            return;
+
+        if (!error.isNull()) {
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for token public key request."_s));
+            return;
+        }
+
+        if (!jsonObject) {
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response is empty for token public key request."_s));
+            return;
+        }
+
+        m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Got JSON response for token public key request."_s));
+
+        callback(WTFMove(attribution), jsonObject->getString("token_public_key"_s));
+    });
+
+}
+
+void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& measurement)
+{
+    if (!featureEnabled())
+        return;
+
+    // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
+    auto pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable;
+    auto tokenSignatureURL = measurement.tokenSignatureURL();
+    if (m_tokenSignatureURLForTesting) {
+        tokenSignatureURL = *m_tokenSignatureURLForTesting;
+        // FIXME(225364)
+        pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
+    }
+
+    if (tokenSignatureURL.isEmpty() || !tokenSignatureURL.isValid())
+        return;
+
+    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(tokenSignatureURL), measurement.tokenSignatureJSON(), pcmDataCarried, debugModeEnabled());
+
+    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
+    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
+
+    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, measurement = WTFMove(measurement)] (auto& error, auto& response, auto& jsonObject) mutable {
+        if (!weakThis)
+            return;
+
+        if (!error.isNull()) {
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for secret token signing request."_s));
+            return;
+        }
+
+        if (!jsonObject) {
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response is empty for token signing request."_s));
+            return;
+        }
+
+        auto signatureBase64URL = jsonObject->getString("unlinkable_token"_s);
+        if (signatureBase64URL.isEmpty()) {
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response doesn't have the key 'unlinkable_token' for token signing request."_s));
+            return;
+        }
+        // FIX NOW!
+        if (m_fraudPreventionValuesForTesting)
+            measurement.setSourceSecretToken({ m_fraudPreventionValuesForTesting->secretToken, m_fraudPreventionValuesForTesting->signature, m_fraudPreventionValuesForTesting->keyID });
+#if PLATFORM(COCOA)
+        else {
+            if (auto errorMessage = measurement.calculateAndUpdateSourceSecretToken(signatureBase64URL)) {
+                RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceSecretToken(): '%{public}s", errorMessage->utf8().data());
+                m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
+                return;
+            }
+        }
+#endif
+
+        m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Storing a secret token."_s);
+
+        insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
+    });
+
+}
+
+void PrivateClickMeasurementManager::insertPrivateClickMeasurement(PrivateClickMeasurement&& measurement, PrivateClickMeasurementAttributionType type)
+{
+    if (m_isRunningEphemeralMeasurementTest)
+        measurement.setEphemeral(PrivateClickMeasurementAttributionEphemeral::Yes);
+    if (measurement.isEphemeral()) {
+        m_ephemeralMeasurement = WTFMove(measurement);
+        return;
+    }
+    store().insertPrivateClickMeasurement(WTFMove(measurement), type);
+}
+
+void PrivateClickMeasurementManager::handleAttribution(AttributionTriggerData&& attributionTriggerData, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
+{
+    if (!featureEnabled())
+        return;
+
+    RegistrableDomain redirectDomain { redirectRequest.url() };
+    auto& firstPartyURL = redirectRequest.firstPartyForCookies();
+
+    if (!redirectDomain.matches(requestURL)) {
+        m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because the HTTP redirect was not same-site."_s);
+        return;
+    }
+
+    if (redirectDomain.matches(firstPartyURL)) {
+        m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because it was requested in an HTTP redirect that is same-site as the first-party."_s);
+        return;
+    }
+
+    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Triggering event accepted."_s);
+
+    attribute(SourceSite { WTFMove(redirectDomain) }, AttributionDestinationSite { firstPartyURL }, WTFMove(attributionTriggerData));
+}
+
+void PrivateClickMeasurementManager::startTimer(Seconds seconds)
+{
+    m_firePendingAttributionRequestsTimer.startOneShot(m_isRunningTest ? 0_s : seconds);
+}
+
+void PrivateClickMeasurementManager::attribute(const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, AttributionTriggerData&& attributionTriggerData)
+{
+    if (!featureEnabled())
+        return;
+
+    if (m_ephemeralMeasurement) {
+        // Ephemeral measurement can only have one pending click.
+        if (m_ephemeralMeasurement->sourceSite() != sourceSite)
+            return;
+        if (m_ephemeralMeasurement->destinationSite() != destinationSite)
+            return;
+    }
+        
+    store().attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), std::exchange(m_ephemeralMeasurement, std::nullopt), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData, auto debugInfo) {
+        if (!weakThis)
+            return;
+        
+        if (!attributionSecondsUntilSendData)
+            return;
+
+        if (UNLIKELY(debugModeEnabled())) {
+            for (auto& message : debugInfo.messages)
+                m_client->broadcastConsoleMessage(message.messageLevel, message.message);
+        }
+
+        if (attributionSecondsUntilSendData.value().hasValidSecondsUntilSendValues()) {
+            auto minSecondsUntilSend = attributionSecondsUntilSendData.value().minSecondsUntilSend();
+
+            ASSERT(minSecondsUntilSend);
+            if (!minSecondsUntilSend)
+                return;
+
+            if (m_firePendingAttributionRequestsTimer.isActive() && m_firePendingAttributionRequestsTimer.nextFireInterval() < *minSecondsUntilSend)
+                return;
+
+            if (UNLIKELY(debugModeEnabled())) {
+                m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Setting timer for firing attribution request to the debug mode timeout of "_s, debugModeSecondsUntilSend.seconds(), " seconds where the regular timeout would have been "_s, minSecondsUntilSend.value().seconds(), " seconds."_s));
+                minSecondsUntilSend = debugModeSecondsUntilSend;
+            } else
+                m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Setting timer for firing attribution request to the timeout of "_s, minSecondsUntilSend.value().seconds(), " seconds."_s));
+
+            startTimer(*minSecondsUntilSend);
+        }
+    });
+}
+
+void PrivateClickMeasurementManager::fireConversionRequest(const PrivateClickMeasurement& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
+{
+    if (!featureEnabled())
+        return;
+
+    if (!attribution.sourceUnlinkableToken()) {
+        fireConversionRequestImpl(attribution, attributionReportEndpoint);
+        return;
+    }
+
+    auto attributionCopy = attribution;
+    // This happens out of webpage context and with a long delay and is thus unlikely to be personally identifiable.
+    getTokenPublicKey(WTFMove(attributionCopy), attributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this, attributionReportEndpoint] (PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL) {
+        if (!weakThis)
+            return;
+
+        auto publicKeyData = base64URLDecode(publicKeyBase64URL);
+        if (!publicKeyData)
+            return;
+
+        auto crypto = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
+        crypto->addBytes(publicKeyData->data(), publicKeyData->size());
+        auto publicKeyDataHash = crypto->computeHash();
+
+        auto keyID = base64URLEncodeToString(publicKeyDataHash.data(), publicKeyDataHash.size());
+        if (keyID != attribution.sourceUnlinkableToken()->keyIDBase64URL)
+            return;
+
+        fireConversionRequestImpl(attribution, attributionReportEndpoint);
+    });
+}
+
+void PrivateClickMeasurementManager::fireConversionRequestImpl(const PrivateClickMeasurement& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
+{
+    URL attributionURL;
+    switch (attributionReportEndpoint) {
+    case PrivateClickMeasurement::AttributionReportEndpoint::Source:
+        attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportSourceURL : attribution.attributionReportSourceURL();
+        break;
+    case PrivateClickMeasurement::AttributionReportEndpoint::Destination:
+        attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportAttributeOnURL : attribution.attributionReportAttributeOnURL();
+    }
+
+    if (attributionURL.isEmpty() || !attributionURL.isValid())
+        return;
+
+    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(attributionURL), attribution.attributionReportJSON(), PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable, debugModeEnabled());
+
+    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire an attribution request.");
+    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire an attribution request."_s);
+
+    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this](auto& error, auto& response, auto&) {
+        if (!weakThis)
+            return;
+
+        if (!error.isNull())
+            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for ad click attribution request."_s));
+    });
+}
+
+void PrivateClickMeasurementManager::clearSentAttribution(PrivateClickMeasurement&& sentConversion, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
+{
+    if (!featureEnabled())
+        return;
+
+    store().clearSentAttribution(WTFMove(sentConversion), attributionReportEndpoint);
+}
+
+void PrivateClickMeasurementManager::firePendingAttributionRequests()
+{
+    if (!featureEnabled())
+        return;
+
+    store().allAttributedPrivateClickMeasurement([this, weakThis = makeWeakPtr(*this)] (auto&& attributions) {
+        if (!weakThis)
+            return;
+        auto nextTimeToFire = Seconds::infinity();
+        bool hasSentAttribution = false;
+
+        for (auto& attribution : attributions) {
+            std::optional<WallTime> earliestTimeToSend = attribution.timesToSend().earliestTimeToSend();
+            std::optional<WebCore::PrivateClickMeasurement::AttributionReportEndpoint> attributionReportEndpoint = attribution.timesToSend().attributionReportEndpoint();
+
+            if (!earliestTimeToSend || !attributionReportEndpoint) {
+                ASSERT_NOT_REACHED();
+                continue;
+            }
+
+            auto now = WallTime::now();
+            if (*earliestTimeToSend <= now || m_isRunningTest || debugModeEnabled()) {
+                if (hasSentAttribution) {
+                    // We've already sent an attribution this round. We should send additional overdue attributions at
+                    // a random time between 15 and 30 minutes to avoid a burst of simultaneous attributions. If debug
+                    // mode is enabled, this should be much shorter for easy testing.
+                    auto interval = debugModeEnabled() ? debugModeSecondsUntilSend : 15_min + Seconds(cryptographicallyRandomNumber() % 900);
+                    startTimer(interval);
+                    return;
+                }
+
+                auto laterTimeToSend = attribution.timesToSend().latestTimeToSend();
+                fireConversionRequest(attribution, *attributionReportEndpoint);
+                clearSentAttribution(WTFMove(attribution), *attributionReportEndpoint);
+                hasSentAttribution = true;
+
+                // Update nextTimeToFire in case the later report time for this attribution is sooner than the scheduled next time to fire.
+                // Or, if debug mode is enabled, we should send the second report on a much shorter delay for easy testing.
+                if (laterTimeToSend)
+                    nextTimeToFire = debugModeEnabled() ? debugModeSecondsUntilSend : std::min(nextTimeToFire, laterTimeToSend.value().secondsSinceEpoch());
+
+                continue;
+            }
+
+            auto seconds = *earliestTimeToSend - now;
+            nextTimeToFire = std::min(nextTimeToFire, seconds);
+
+            // Attributions are sorted by earliestTimeToSend, so the first time we hit this there can be no further attributions
+            // due for reporting, and nextTimeToFire is the minimum earliestTimeToSend value for any pending attribution.
+            break;
+        }
+
+        if (nextTimeToFire < Seconds::infinity())
+            startTimer(nextTimeToFire);
+    });
+}
+
+void PrivateClickMeasurementManager::clear(CompletionHandler<void()>&& completionHandler)
+{
+    m_firePendingAttributionRequestsTimer.stop();
+    m_ephemeralMeasurement = std::nullopt;
+    m_isRunningEphemeralMeasurementTest = false;
+
+    if (!featureEnabled())
+        return completionHandler();
+
+    store().clearPrivateClickMeasurement(WTFMove(completionHandler));
+}
+
+void PrivateClickMeasurementManager::clearForRegistrableDomain(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
+{
+    if (!featureEnabled())
+        return completionHandler();
+
+    store().clearPrivateClickMeasurementForRegistrableDomain(domain, WTFMove(completionHandler));
+}
+
+void PrivateClickMeasurementManager::clearExpired()
+{
+    if (!featureEnabled())
+        return;
+
+    store().clearExpiredPrivateClickMeasurement();
+}
+
+void PrivateClickMeasurementManager::toStringForTesting(CompletionHandler<void(String)>&& completionHandler) const
+{
+    if (!featureEnabled())
+        return completionHandler("\nNo stored Private Click Measurement data.\n"_s);
+
+    store().privateClickMeasurementToStringForTesting(WTFMove(completionHandler));
+}
+
+void PrivateClickMeasurementManager::setTokenPublicKeyURLForTesting(URL&& testURL)
+{
+    if (testURL.isEmpty())
+        return;
+    m_tokenPublicKeyURLForTesting = WTFMove(testURL);
+}
+
+void PrivateClickMeasurementManager::setTokenSignatureURLForTesting(URL&& testURL)
+{
+    if (testURL.isEmpty())
+        m_tokenSignatureURLForTesting = { };
+    else
+        m_tokenSignatureURLForTesting = WTFMove(testURL);
+}
+
+void PrivateClickMeasurementManager::setAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL)
+{
+    if (sourceURL.isEmpty() || destinationURL.isEmpty())
+        m_attributionReportTestConfig = std::nullopt;
+    else
+        m_attributionReportTestConfig = AttributionReportTestConfig { WTFMove(sourceURL), WTFMove(destinationURL) };
+}
+
+void PrivateClickMeasurementManager::markAllUnattributedAsExpiredForTesting()
+{
+    if (!featureEnabled())
+        return;
+
+    store().markAllUnattributedPrivateClickMeasurementAsExpiredForTesting();
+}
+
+void PrivateClickMeasurementManager::setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID)
+{
+    if (unlinkableToken.isEmpty() || secretToken.isEmpty() || signature.isEmpty() || keyID.isEmpty())
+        return;
+    m_fraudPreventionValuesForTesting = TestingFraudPreventionValues { WTFMove(unlinkableToken), WTFMove(secretToken), WTFMove(signature), WTFMove(keyID) };
+}
+
+bool PrivateClickMeasurementManager::featureEnabled() const
+{
+    return m_client->featureEnabled();
+}
+
+bool PrivateClickMeasurementManager::debugModeEnabled() const
+{
+    return m_client->debugModeEnabled();
+}
+
+void PrivateClickMeasurementManager::markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&& completionHandler)
+{
+    if (!featureEnabled())
+        return completionHandler();
+
+    store().markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));
+}
+
+PCM::Store& PrivateClickMeasurementManager::store()
+{
+    if (!m_store)
+        m_store = PCM::Store::create(m_storageDirectory);
+    return *m_store;
+}
+
+const PCM::Store& PrivateClickMeasurementManager::store() const
+{
+    if (!m_store)
+        m_store = PCM::Store::create(m_storageDirectory);
+    return *m_store;
+}
+
+void PrivateClickMeasurementManager::destroyStoreForTesting(CompletionHandler<void()>&& completionHandler)
+{
+    if (!m_store)
+        return completionHandler();
+    m_store->close([weakThis = makeWeakPtr(*this), completionHandler = WTFMove(completionHandler)] () mutable {
+        if (weakThis)
+            weakThis->m_store = nullptr;
+        return completionHandler();
+    });
+}
+
+} // namespace WebKit

Added: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h (0 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h	2021-09-02 23:03:37 UTC (rev 281961)
@@ -0,0 +1,118 @@
+/*
+ * 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
+
+#include "NetworkLoadParameters.h"
+#include "NetworkProcess.h"
+#include "PrivateClickMeasurementClient.h"
+#include "PrivateClickMeasurementStore.h"
+#include <WebCore/PrivateClickMeasurement.h>
+#include <WebCore/RegistrableDomain.h>
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceResponse.h>
+#include <WebCore/Timer.h>
+#include <pal/SessionID.h>
+#include <wtf/CompletionHandler.h>
+#include <wtf/JSONValues.h>
+#include <wtf/WeakPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+enum class PrivateClickMeasurementAttributionType : bool { Unattributed, Attributed };
+
+class PrivateClickMeasurementManager : public CanMakeWeakPtr<PrivateClickMeasurementManager> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+
+    using AttributionDestinationSite = WebCore::PrivateClickMeasurement::AttributionDestinationSite;
+    using AttributionTriggerData = WebCore::PrivateClickMeasurement::AttributionTriggerData;
+    using PrivateClickMeasurement = WebCore::PrivateClickMeasurement;
+    using RegistrableDomain = WebCore::RegistrableDomain;
+    using SourceSite = WebCore::PrivateClickMeasurement::SourceSite;
+    explicit PrivateClickMeasurementManager(UniqueRef<PCM::Client>&&, const String& storageDirectory);
+
+    void storeUnattributed(PrivateClickMeasurement&&);
+    void handleAttribution(AttributionTriggerData&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest);
+    void clear(CompletionHandler<void()>&&);
+    void clearForRegistrableDomain(const RegistrableDomain&, CompletionHandler<void()>&&);
+    void toStringForTesting(CompletionHandler<void(String)>&&) const;
+    void setOverrideTimerForTesting(bool value) { m_isRunningTest = value; }
+    void setTokenPublicKeyURLForTesting(URL&&);
+    void setTokenSignatureURLForTesting(URL&&);
+    void setAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL);
+    void markAllUnattributedAsExpiredForTesting();
+    void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
+    void setEphemeralMeasurementForTesting(bool value) { m_isRunningEphemeralMeasurementTest = value; }
+    void setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID);
+    void startTimer(Seconds);
+
+    void destroyStoreForTesting(CompletionHandler<void()>&&);
+
+    PCM::Store& store();
+    const PCM::Store& store() const;
+
+private:
+    void getTokenPublicKey(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&&);
+    void getSignedUnlinkableToken(PrivateClickMeasurement&&);
+    void insertPrivateClickMeasurement(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType);
+    void clearSentAttribution(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint);
+    void attribute(const SourceSite&, const AttributionDestinationSite&, AttributionTriggerData&&);
+    void fireConversionRequest(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint);
+    void fireConversionRequestImpl(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint);
+    void firePendingAttributionRequests();
+    void clearExpired();
+    bool featureEnabled() const;
+    bool debugModeEnabled() const;
+
+    std::optional<PrivateClickMeasurement> m_ephemeralMeasurement;
+    WebCore::Timer m_firePendingAttributionRequestsTimer;
+    bool m_isRunningTest { false };
+    bool m_isRunningEphemeralMeasurementTest { false };
+    std::optional<URL> m_tokenPublicKeyURLForTesting;
+    std::optional<URL> m_tokenSignatureURLForTesting;
+    mutable RefPtr<PCM::Store> m_store;
+    String m_storageDirectory;
+    UniqueRef<PCM::Client> m_client;
+
+    struct AttributionReportTestConfig {
+        URL attributionReportSourceURL;
+        URL attributionReportAttributeOnURL;
+    };
+
+    std::optional<AttributionReportTestConfig> m_attributionReportTestConfig;
+
+    struct TestingFraudPreventionValues {
+        String unlinkableToken;
+        String secretToken;
+        String signature;
+        String keyID;
+    };
+
+    std::optional<TestingFraudPreventionValues> m_fraudPreventionValuesForTesting;
+};
+    
+} // namespace WebKit

Added: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp (0 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp	2021-09-02 23:03:37 UTC (rev 281961)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "config.h"
+#include "PrivateClickMeasurementNetworkLoader.h"
+
+#include "NetworkLoad.h"
+#include "NetworkSession.h"
+#include <WebCore/MIMETypeRegistry.h>
+#include <WebCore/TextResourceDecoder.h>
+
+#include <wtf/JSONValues.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+void PrivateClickMeasurementNetworkLoader::start(NetworkSession& session, NetworkLoadParameters&& parameters, Callback&& completionHandler)
+{
+    auto loader = std::unique_ptr<PrivateClickMeasurementNetworkLoader>(new PrivateClickMeasurementNetworkLoader(session, WTFMove(parameters), WTFMove(completionHandler)));
+    session.addPrivateClickMeasurementNetworkLoader(WTFMove(loader));
+}
+
+PrivateClickMeasurementNetworkLoader::PrivateClickMeasurementNetworkLoader(NetworkSession& session, NetworkLoadParameters&& parameters, Callback&& completionHandler)
+    : m_session(makeWeakPtr(session))
+    , m_completionHandler(WTFMove(completionHandler))
+{
+    m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), *m_session);
+    m_networkLoad->start();
+}
+
+PrivateClickMeasurementNetworkLoader::~PrivateClickMeasurementNetworkLoader()
+{
+    cancel();
+}
+
+void PrivateClickMeasurementNetworkLoader::fail(ResourceError&& error)
+{
+    if (!m_completionHandler)
+        return;
+
+    m_completionHandler(WTFMove(error), { }, nullptr);
+    didComplete();
+}
+
+void PrivateClickMeasurementNetworkLoader::cancel()
+{
+    fail(ResourceError { ResourceError::Type::Cancellation });
+}
+
+void PrivateClickMeasurementNetworkLoader::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&&, ResourceResponse&&)
+{
+    cancel();
+}
+
+void PrivateClickMeasurementNetworkLoader::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
+{
+    if (!MIMETypeRegistry::isSupportedJSONMIMEType(response.mimeType())) {
+        fail({ errorDomainWebKitInternal, 0, response.url(), "MIME Type is not a JSON MIME type"_s });
+        completionHandler(PolicyAction::Ignore);
+        return;
+    }
+
+    m_response = WTFMove(response);
+    completionHandler(PolicyAction::Use);
+}
+
+void PrivateClickMeasurementNetworkLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength)
+{
+    if (!m_decoder)
+        m_decoder = TextResourceDecoder::create("application/json"_s, m_response.textEncodingName().isEmpty() ? WebCore::TextEncoding("UTF-8") : WebCore::TextEncoding(m_response.textEncodingName()));
+
+    if (auto size = buffer->size())
+        m_jsonString.append(m_decoder->decode(buffer->data(), size));
+}
+
+void PrivateClickMeasurementNetworkLoader::didFinishLoading(const WebCore::NetworkLoadMetrics&)
+{
+    if (m_decoder)
+        m_jsonString.append(m_decoder->flush());
+
+    if (auto jsonValue = JSON::Value::parseJSON(m_jsonString.toString()))
+        m_completionHandler({ }, m_response, jsonValue->asObject());
+    else
+        m_completionHandler({ }, m_response, nullptr);
+
+    didComplete();
+}
+
+void PrivateClickMeasurementNetworkLoader::didFailLoading(const ResourceError& error)
+{
+    fail(ResourceError(error));
+}
+
+void PrivateClickMeasurementNetworkLoader::didComplete()
+{
+    m_networkLoad = nullptr;
+    if (m_session)
+        m_session->removePrivateClickMeasurementNetworkLoader(this);
+}
+
+} // namespace WebKit

Added: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.h (0 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.h	2021-09-02 23:03:37 UTC (rev 281961)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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
+
+#include "NetworkLoad.h"
+#include "NetworkLoadClient.h"
+#include "NetworkLoadParameters.h"
+#include <WebCore/TextResourceDecoder.h>
+#include <wtf/CompletionHandler.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebKit {
+
+class NetworkSession;
+
+class PrivateClickMeasurementNetworkLoader final : public NetworkLoadClient {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    using Callback = CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&, const RefPtr<JSON::Object>&)>;
+    static void start(NetworkSession&, NetworkLoadParameters&&, Callback&&);
+
+    ~PrivateClickMeasurementNetworkLoader();
+
+private:
+    PrivateClickMeasurementNetworkLoader(NetworkSession&, NetworkLoadParameters&&, Callback&&);
+
+    // NetworkLoadClient.
+    void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final { }
+    bool isSynchronous() const final { return false; }
+    bool isAllowedToAskUserForCredentials() const final { return false; }
+    void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) final;
+    void didFinishLoading(const WebCore::NetworkLoadMetrics&) final;
+    void didFailLoading(const WebCore::ResourceError&) final;
+
+    void fail(WebCore::ResourceError&&);
+    void cancel();
+    void didComplete();
+
+    WeakPtr<NetworkSession> m_session;
+    std::unique_ptr<NetworkLoad> m_networkLoad;
+    Callback m_completionHandler;
+
+    WebCore::ResourceResponse m_response;
+    RefPtr<WebCore::TextResourceDecoder> m_decoder;
+    StringBuilder m_jsonString;
+};
+
+} // namespace WebKit

Deleted: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (281960 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1,568 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-#include "PrivateClickMeasurementManager.h"
-
-#include "Logging.h"
-#include "NetworkSession.h"
-#include "PrivateClickMeasurementDebugInfo.h"
-#include <_javascript_Core/ConsoleTypes.h>
-#include <WebCore/FetchOptions.h>
-#include <WebCore/FormData.h>
-#include <WebCore/HTTPHeaderValues.h>
-#include <WebCore/ResourceError.h>
-#include <WebCore/ResourceRequest.h>
-#include <WebCore/ResourceResponse.h>
-#include <WebCore/RuntimeApplicationChecks.h>
-#include <WebCore/RuntimeEnabledFeatures.h>
-#include <pal/crypto/CryptoDigest.h>
-#include <wtf/CryptographicallyRandomNumber.h>
-#include <wtf/text/StringBuilder.h>
-#include <wtf/text/StringHash.h>
-
-namespace WebKit {
-using namespace WebCore;
-
-using SourceSite = PrivateClickMeasurement::SourceSite;
-using AttributionDestinationSite = PrivateClickMeasurement::AttributionDestinationSite;
-using AttributionTriggerData = PrivateClickMeasurement::AttributionTriggerData;
-using EphemeralSourceNonce = PrivateClickMeasurement::EphemeralSourceNonce;
-
-constexpr Seconds debugModeSecondsUntilSend { 10_s };
-
-PrivateClickMeasurementManager::PrivateClickMeasurementManager(UniqueRef<PCM::Client>&& client, const String& storageDirectory)
-    : m_firePendingAttributionRequestsTimer(*this, &PrivateClickMeasurementManager::firePendingAttributionRequests)
-    , m_storageDirectory(storageDirectory)
-    , m_client(WTFMove(client))
-{
-    // We should send any pending attributions on session-start in case their
-    // send delay has expired while the session was closed. Waiting 5 seconds accounts for the
-    // delay in database startup.
-    startTimer(5_s);
-}
-
-void PrivateClickMeasurementManager::storeUnattributed(PrivateClickMeasurement&& measurement)
-{
-    if (!featureEnabled())
-        return;
-
-    clearExpired();
-
-    if (measurement.ephemeralSourceNonce()) {
-        auto measurementCopy = measurement;
-        // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
-        getTokenPublicKey(WTFMove(measurementCopy), PrivateClickMeasurement::AttributionReportEndpoint::Source, PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this] (PrivateClickMeasurement&& measurement, const String& publicKeyBase64URL) {
-            if (!weakThis)
-                return;
-
-            if (publicKeyBase64URL.isEmpty())
-                return;
-
-            if (m_fraudPreventionValuesForTesting)
-                measurement.setSourceUnlinkableTokenValue(m_fraudPreventionValuesForTesting->unlinkableToken);
-#if PLATFORM(COCOA)
-            else {
-                if (auto errorMessage = measurement.calculateAndUpdateSourceUnlinkableToken(publicKeyBase64URL)) {
-                    RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceUnlinkableToken(): '%{public}s", errorMessage->utf8().data());
-                    m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
-                    return;
-                }
-            }
-#endif
-
-            getSignedUnlinkableToken(WTFMove(measurement));
-            return;
-        });
-    }
-
-    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Storing a click."_s);
-
-    insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
-}
-
-static NetworkLoadParameters generateNetworkLoadParameters(URL&& url, const String& httpMethod, RefPtr<JSON::Object>&& jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
-{
-    ResourceRequest request { WTFMove(url) };
-    request.setHTTPMethod(httpMethod);
-    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, WebCore::HTTPHeaderValues::maxAge0());
-    if (jsonPayload) {
-        request.setHTTPContentType(WebCore::HTTPHeaderValues::applicationJSONContentType());
-        request.setHTTPBody(WebCore::FormData::create(jsonPayload->toJSONString().utf8().data()));
-    }
-
-    NetworkLoadParameters loadParameters;
-    loadParameters.request = request;
-    loadParameters.parentPID = presentingApplicationPID();
-    loadParameters.storedCredentialsPolicy = StoredCredentialsPolicy::EphemeralStateless;
-    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = true;
-    loadParameters.pcmDataCarried = UNLIKELY(isDebugModeEnabled) ? PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable : dataTypeCarried;
-
-    return loadParameters;
-}
-
-static NetworkLoadParameters generateNetworkLoadParametersForHttpPost(URL&& url, Ref<JSON::Object>&& jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
-{
-    return generateNetworkLoadParameters(WTFMove(url), "POST"_s, WTFMove(jsonPayload), dataTypeCarried, isDebugModeEnabled);
-}
-
-static NetworkLoadParameters generateNetworkLoadParametersForHttpGet(URL&& url, PrivateClickMeasurement::PcmDataCarried dataTypeCarried, bool isDebugModeEnabled)
-{
-    return generateNetworkLoadParameters(WTFMove(url), "GET"_s, nullptr, dataTypeCarried, isDebugModeEnabled);
-}
-
-void PrivateClickMeasurementManager::getTokenPublicKey(PrivateClickMeasurement&& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried pcmDataCarried, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&& callback)
-{
-    if (!featureEnabled())
-        return;
-
-    auto tokenPublicKeyURL = attribution.tokenPublicKeyURL();
-    if (m_tokenPublicKeyURLForTesting) {
-        if (attributionReportEndpoint == PrivateClickMeasurement::AttributionReportEndpoint::Destination)
-            return;
-        tokenPublicKeyURL = *m_tokenPublicKeyURLForTesting;
-        // FIXME(225364)
-        pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
-    }
-
-    if (tokenPublicKeyURL.isEmpty() || !tokenPublicKeyURL.isValid())
-        return;
-
-    auto loadParameters = generateNetworkLoadParametersForHttpGet(WTFMove(tokenPublicKeyURL), pcmDataCarried, debugModeEnabled());
-
-    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a token public key request.");
-    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire a token public key request."_s);
-
-    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, attribution = WTFMove(attribution), callback = WTFMove(callback)] (auto& error, auto& response, auto& jsonObject) mutable {
-        if (!weakThis)
-            return;
-
-        if (!error.isNull()) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for token public key request."_s));
-            return;
-        }
-
-        if (!jsonObject) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response is empty for token public key request."_s));
-            return;
-        }
-
-        m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Got JSON response for token public key request."_s));
-
-        callback(WTFMove(attribution), jsonObject->getString("token_public_key"_s));
-    });
-
-}
-
-void PrivateClickMeasurementManager::getSignedUnlinkableToken(PrivateClickMeasurement&& measurement)
-{
-    if (!featureEnabled())
-        return;
-
-    // This is guaranteed to be close in time to the navigational click which makes it likely to be personally identifiable.
-    auto pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable;
-    auto tokenSignatureURL = measurement.tokenSignatureURL();
-    if (m_tokenSignatureURLForTesting) {
-        tokenSignatureURL = *m_tokenSignatureURLForTesting;
-        // FIXME(225364)
-        pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
-    }
-
-    if (tokenSignatureURL.isEmpty() || !tokenSignatureURL.isValid())
-        return;
-
-    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(tokenSignatureURL), measurement.tokenSignatureJSON(), pcmDataCarried, debugModeEnabled());
-
-    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
-    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
-
-    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this, measurement = WTFMove(measurement)] (auto& error, auto& response, auto& jsonObject) mutable {
-        if (!weakThis)
-            return;
-
-        if (!error.isNull()) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for secret token signing request."_s));
-            return;
-        }
-
-        if (!jsonObject) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response is empty for token signing request."_s));
-            return;
-        }
-
-        auto signatureBase64URL = jsonObject->getString("unlinkable_token"_s);
-        if (signatureBase64URL.isEmpty()) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] JSON response doesn't have the key 'unlinkable_token' for token signing request."_s));
-            return;
-        }
-        // FIX NOW!
-        if (m_fraudPreventionValuesForTesting)
-            measurement.setSourceSecretToken({ m_fraudPreventionValuesForTesting->secretToken, m_fraudPreventionValuesForTesting->signature, m_fraudPreventionValuesForTesting->keyID });
-#if PLATFORM(COCOA)
-        else {
-            if (auto errorMessage = measurement.calculateAndUpdateSourceSecretToken(signatureBase64URL)) {
-                RELEASE_LOG_INFO(PrivateClickMeasurement, "Got the following error in calculateAndUpdateSourceSecretToken(): '%{public}s", errorMessage->utf8().data());
-                m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] "_s, *errorMessage));
-                return;
-            }
-        }
-#endif
-
-        m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Storing a secret token."_s);
-
-        insertPrivateClickMeasurement(WTFMove(measurement), PrivateClickMeasurementAttributionType::Unattributed);
-    });
-
-}
-
-void PrivateClickMeasurementManager::insertPrivateClickMeasurement(PrivateClickMeasurement&& measurement, PrivateClickMeasurementAttributionType type)
-{
-    if (m_isRunningEphemeralMeasurementTest)
-        measurement.setEphemeral(PrivateClickMeasurementAttributionEphemeral::Yes);
-    if (measurement.isEphemeral()) {
-        m_ephemeralMeasurement = WTFMove(measurement);
-        return;
-    }
-    store().insertPrivateClickMeasurement(WTFMove(measurement), type);
-}
-
-void PrivateClickMeasurementManager::handleAttribution(AttributionTriggerData&& attributionTriggerData, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
-{
-    if (!featureEnabled())
-        return;
-
-    RegistrableDomain redirectDomain { redirectRequest.url() };
-    auto& firstPartyURL = redirectRequest.firstPartyForCookies();
-
-    if (!redirectDomain.matches(requestURL)) {
-        m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because the HTTP redirect was not same-site."_s);
-        return;
-    }
-
-    if (redirectDomain.matches(firstPartyURL)) {
-        m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because it was requested in an HTTP redirect that is same-site as the first-party."_s);
-        return;
-    }
-
-    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Triggering event accepted."_s);
-
-    attribute(SourceSite { WTFMove(redirectDomain) }, AttributionDestinationSite { firstPartyURL }, WTFMove(attributionTriggerData));
-}
-
-void PrivateClickMeasurementManager::startTimer(Seconds seconds)
-{
-    m_firePendingAttributionRequestsTimer.startOneShot(m_isRunningTest ? 0_s : seconds);
-}
-
-void PrivateClickMeasurementManager::attribute(const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, AttributionTriggerData&& attributionTriggerData)
-{
-    if (!featureEnabled())
-        return;
-
-    if (m_ephemeralMeasurement) {
-        // Ephemeral measurement can only have one pending click.
-        if (m_ephemeralMeasurement->sourceSite() != sourceSite)
-            return;
-        if (m_ephemeralMeasurement->destinationSite() != destinationSite)
-            return;
-    }
-        
-    store().attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), std::exchange(m_ephemeralMeasurement, std::nullopt), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData, auto debugInfo) {
-        if (!weakThis)
-            return;
-        
-        if (!attributionSecondsUntilSendData)
-            return;
-
-        if (UNLIKELY(debugModeEnabled())) {
-            for (auto& message : debugInfo.messages)
-                m_client->broadcastConsoleMessage(message.messageLevel, message.message);
-        }
-
-        if (attributionSecondsUntilSendData.value().hasValidSecondsUntilSendValues()) {
-            auto minSecondsUntilSend = attributionSecondsUntilSendData.value().minSecondsUntilSend();
-
-            ASSERT(minSecondsUntilSend);
-            if (!minSecondsUntilSend)
-                return;
-
-            if (m_firePendingAttributionRequestsTimer.isActive() && m_firePendingAttributionRequestsTimer.nextFireInterval() < *minSecondsUntilSend)
-                return;
-
-            if (UNLIKELY(debugModeEnabled())) {
-                m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Setting timer for firing attribution request to the debug mode timeout of "_s, debugModeSecondsUntilSend.seconds(), " seconds where the regular timeout would have been "_s, minSecondsUntilSend.value().seconds(), " seconds."_s));
-                minSecondsUntilSend = debugModeSecondsUntilSend;
-            } else
-                m_client->broadcastConsoleMessage(MessageLevel::Log, makeString("[Private Click Measurement] Setting timer for firing attribution request to the timeout of "_s, minSecondsUntilSend.value().seconds(), " seconds."_s));
-
-            startTimer(*minSecondsUntilSend);
-        }
-    });
-}
-
-void PrivateClickMeasurementManager::fireConversionRequest(const PrivateClickMeasurement& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
-{
-    if (!featureEnabled())
-        return;
-
-    if (!attribution.sourceUnlinkableToken()) {
-        fireConversionRequestImpl(attribution, attributionReportEndpoint);
-        return;
-    }
-
-    auto attributionCopy = attribution;
-    // This happens out of webpage context and with a long delay and is thus unlikely to be personally identifiable.
-    getTokenPublicKey(WTFMove(attributionCopy), attributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable, [weakThis = makeWeakPtr(*this), this, attributionReportEndpoint] (PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL) {
-        if (!weakThis)
-            return;
-
-        auto publicKeyData = base64URLDecode(publicKeyBase64URL);
-        if (!publicKeyData)
-            return;
-
-        auto crypto = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
-        crypto->addBytes(publicKeyData->data(), publicKeyData->size());
-        auto publicKeyDataHash = crypto->computeHash();
-
-        auto keyID = base64URLEncodeToString(publicKeyDataHash.data(), publicKeyDataHash.size());
-        if (keyID != attribution.sourceUnlinkableToken()->keyIDBase64URL)
-            return;
-
-        fireConversionRequestImpl(attribution, attributionReportEndpoint);
-    });
-}
-
-void PrivateClickMeasurementManager::fireConversionRequestImpl(const PrivateClickMeasurement& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
-{
-    URL attributionURL;
-    switch (attributionReportEndpoint) {
-    case PrivateClickMeasurement::AttributionReportEndpoint::Source:
-        attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportSourceURL : attribution.attributionReportSourceURL();
-        break;
-    case PrivateClickMeasurement::AttributionReportEndpoint::Destination:
-        attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportAttributeOnURL : attribution.attributionReportAttributeOnURL();
-    }
-
-    if (attributionURL.isEmpty() || !attributionURL.isValid())
-        return;
-
-    auto loadParameters = generateNetworkLoadParametersForHttpPost(WTFMove(attributionURL), attribution.attributionReportJSON(), PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable, debugModeEnabled());
-
-    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire an attribution request.");
-    m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] About to fire an attribution request."_s);
-
-    m_client->loadFromNetwork(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this), this](auto& error, auto& response, auto&) {
-        if (!weakThis)
-            return;
-
-        if (!error.isNull()) {
-            m_client->broadcastConsoleMessage(MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for ad click attribution request."_s));
-        }
-    });
-}
-
-void PrivateClickMeasurementManager::clearSentAttribution(PrivateClickMeasurement&& sentConversion, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)
-{
-    if (!featureEnabled())
-        return;
-
-    store().clearSentAttribution(WTFMove(sentConversion), attributionReportEndpoint);
-}
-
-void PrivateClickMeasurementManager::firePendingAttributionRequests()
-{
-    if (!featureEnabled())
-        return;
-
-    store().allAttributedPrivateClickMeasurement([this, weakThis = makeWeakPtr(*this)] (auto&& attributions) {
-        if (!weakThis)
-            return;
-        auto nextTimeToFire = Seconds::infinity();
-        bool hasSentAttribution = false;
-
-        for (auto& attribution : attributions) {
-            std::optional<WallTime> earliestTimeToSend = attribution.timesToSend().earliestTimeToSend();
-            std::optional<WebCore::PrivateClickMeasurement::AttributionReportEndpoint> attributionReportEndpoint = attribution.timesToSend().attributionReportEndpoint();
-
-            if (!earliestTimeToSend || !attributionReportEndpoint) {
-                ASSERT_NOT_REACHED();
-                continue;
-            }
-
-            auto now = WallTime::now();
-            if (*earliestTimeToSend <= now || m_isRunningTest || debugModeEnabled()) {
-                if (hasSentAttribution) {
-                    // We've already sent an attribution this round. We should send additional overdue attributions at
-                    // a random time between 15 and 30 minutes to avoid a burst of simultaneous attributions. If debug
-                    // mode is enabled, this should be much shorter for easy testing.
-                    auto interval = debugModeEnabled() ? debugModeSecondsUntilSend : 15_min + Seconds(cryptographicallyRandomNumber() % 900);
-                    startTimer(interval);
-                    return;
-                }
-
-                auto laterTimeToSend = attribution.timesToSend().latestTimeToSend();
-                fireConversionRequest(attribution, *attributionReportEndpoint);
-                clearSentAttribution(WTFMove(attribution), *attributionReportEndpoint);
-                hasSentAttribution = true;
-
-                // Update nextTimeToFire in case the later report time for this attribution is sooner than the scheduled next time to fire.
-                // Or, if debug mode is enabled, we should send the second report on a much shorter delay for easy testing.
-                if (laterTimeToSend)
-                    nextTimeToFire = debugModeEnabled() ? debugModeSecondsUntilSend : std::min(nextTimeToFire, laterTimeToSend.value().secondsSinceEpoch());
-
-                continue;
-            }
-
-            auto seconds = *earliestTimeToSend - now;
-            nextTimeToFire = std::min(nextTimeToFire, seconds);
-
-            // Attributions are sorted by earliestTimeToSend, so the first time we hit this there can be no further attributions
-            // due for reporting, and nextTimeToFire is the minimum earliestTimeToSend value for any pending attribution.
-            break;
-        }
-
-        if (nextTimeToFire < Seconds::infinity())
-            startTimer(nextTimeToFire);
-    });
-}
-
-void PrivateClickMeasurementManager::clear(CompletionHandler<void()>&& completionHandler)
-{
-    m_firePendingAttributionRequestsTimer.stop();
-    m_ephemeralMeasurement = std::nullopt;
-    m_isRunningEphemeralMeasurementTest = false;
-
-    if (!featureEnabled())
-        return completionHandler();
-
-    store().clearPrivateClickMeasurement(WTFMove(completionHandler));
-}
-
-void PrivateClickMeasurementManager::clearForRegistrableDomain(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
-{
-    if (!featureEnabled())
-        return completionHandler();
-
-    store().clearPrivateClickMeasurementForRegistrableDomain(domain, WTFMove(completionHandler));
-}
-
-void PrivateClickMeasurementManager::clearExpired()
-{
-    if (!featureEnabled())
-        return;
-
-    store().clearExpiredPrivateClickMeasurement();
-}
-
-void PrivateClickMeasurementManager::toStringForTesting(CompletionHandler<void(String)>&& completionHandler) const
-{
-    if (!featureEnabled())
-        return completionHandler("\nNo stored Private Click Measurement data.\n"_s);
-
-    store().privateClickMeasurementToStringForTesting(WTFMove(completionHandler));
-}
-
-void PrivateClickMeasurementManager::setTokenPublicKeyURLForTesting(URL&& testURL)
-{
-    if (testURL.isEmpty())
-        return;
-    m_tokenPublicKeyURLForTesting = WTFMove(testURL);
-}
-
-void PrivateClickMeasurementManager::setTokenSignatureURLForTesting(URL&& testURL)
-{
-    if (testURL.isEmpty())
-        m_tokenSignatureURLForTesting = { };
-    else
-        m_tokenSignatureURLForTesting = WTFMove(testURL);
-}
-
-void PrivateClickMeasurementManager::setAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL)
-{
-    if (sourceURL.isEmpty() || destinationURL.isEmpty())
-        m_attributionReportTestConfig = std::nullopt;
-    else
-        m_attributionReportTestConfig = AttributionReportTestConfig { WTFMove(sourceURL), WTFMove(destinationURL) };
-}
-
-void PrivateClickMeasurementManager::markAllUnattributedAsExpiredForTesting()
-{
-    if (!featureEnabled())
-        return;
-
-    store().markAllUnattributedPrivateClickMeasurementAsExpiredForTesting();
-}
-
-void PrivateClickMeasurementManager::setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID)
-{
-    if (unlinkableToken.isEmpty() || secretToken.isEmpty() || signature.isEmpty() || keyID.isEmpty())
-        return;
-    m_fraudPreventionValuesForTesting = TestingFraudPreventionValues { WTFMove(unlinkableToken), WTFMove(secretToken), WTFMove(signature), WTFMove(keyID) };
-}
-
-bool PrivateClickMeasurementManager::featureEnabled() const
-{
-    return m_client->featureEnabled();
-}
-
-bool PrivateClickMeasurementManager::debugModeEnabled() const
-{
-    return m_client->debugModeEnabled();
-}
-
-void PrivateClickMeasurementManager::markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&& completionHandler)
-{
-    if (!featureEnabled())
-        return completionHandler();
-
-    store().markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));
-}
-
-PCM::Store& PrivateClickMeasurementManager::store()
-{
-    if (!m_store)
-        m_store = PCM::Store::create(m_storageDirectory);
-    return *m_store;
-}
-
-const PCM::Store& PrivateClickMeasurementManager::store() const
-{
-    if (!m_store)
-        m_store = PCM::Store::create(m_storageDirectory);
-    return *m_store;
-}
-
-void PrivateClickMeasurementManager::destroyStoreForTesting(CompletionHandler<void()>&& completionHandler)
-{
-    if (!m_store)
-        return completionHandler();
-    m_store->close([weakThis = makeWeakPtr(*this), completionHandler = WTFMove(completionHandler)] () mutable {
-        if (weakThis)
-            weakThis->m_store = nullptr;
-        return completionHandler();
-    });
-}
-
-} // namespace WebKit

Deleted: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (281960 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1,118 +0,0 @@
-/*
- * 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
-
-#include "NetworkLoadParameters.h"
-#include "NetworkProcess.h"
-#include "PrivateClickMeasurementClient.h"
-#include "PrivateClickMeasurementStore.h"
-#include <WebCore/PrivateClickMeasurement.h>
-#include <WebCore/RegistrableDomain.h>
-#include <WebCore/ResourceError.h>
-#include <WebCore/ResourceResponse.h>
-#include <WebCore/Timer.h>
-#include <pal/SessionID.h>
-#include <wtf/CompletionHandler.h>
-#include <wtf/JSONValues.h>
-#include <wtf/WeakPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebKit {
-
-enum class PrivateClickMeasurementAttributionType : bool { Unattributed, Attributed };
-
-class PrivateClickMeasurementManager : public CanMakeWeakPtr<PrivateClickMeasurementManager> {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-
-    using AttributionDestinationSite = WebCore::PrivateClickMeasurement::AttributionDestinationSite;
-    using AttributionTriggerData = WebCore::PrivateClickMeasurement::AttributionTriggerData;
-    using PrivateClickMeasurement = WebCore::PrivateClickMeasurement;
-    using RegistrableDomain = WebCore::RegistrableDomain;
-    using SourceSite = WebCore::PrivateClickMeasurement::SourceSite;
-    explicit PrivateClickMeasurementManager(UniqueRef<PCM::Client>&&, const String& storageDirectory);
-
-    void storeUnattributed(PrivateClickMeasurement&&);
-    void handleAttribution(AttributionTriggerData&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest);
-    void clear(CompletionHandler<void()>&&);
-    void clearForRegistrableDomain(const RegistrableDomain&, CompletionHandler<void()>&&);
-    void toStringForTesting(CompletionHandler<void(String)>&&) const;
-    void setOverrideTimerForTesting(bool value) { m_isRunningTest = value; }
-    void setTokenPublicKeyURLForTesting(URL&&);
-    void setTokenSignatureURLForTesting(URL&&);
-    void setAttributionReportURLsForTesting(URL&& sourceURL, URL&& destinationURL);
-    void markAllUnattributedAsExpiredForTesting();
-    void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
-    void setEphemeralMeasurementForTesting(bool value) { m_isRunningEphemeralMeasurementTest = value; }
-    void setPCMFraudPreventionValuesForTesting(String&& unlinkableToken, String&& secretToken, String&& signature, String&& keyID);
-    void startTimer(Seconds);
-
-    void destroyStoreForTesting(CompletionHandler<void()>&&);
-
-    PCM::Store& store();
-    const PCM::Store& store() const;
-
-private:
-    void getTokenPublicKey(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint, PrivateClickMeasurement::PcmDataCarried, Function<void(PrivateClickMeasurement&& attribution, const String& publicKeyBase64URL)>&&);
-    void getSignedUnlinkableToken(PrivateClickMeasurement&&);
-    void insertPrivateClickMeasurement(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType);
-    void clearSentAttribution(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint);
-    void attribute(const SourceSite&, const AttributionDestinationSite&, AttributionTriggerData&&);
-    void fireConversionRequest(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint);
-    void fireConversionRequestImpl(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint);
-    void firePendingAttributionRequests();
-    void clearExpired();
-    bool featureEnabled() const;
-    bool debugModeEnabled() const;
-
-    std::optional<PrivateClickMeasurement> m_ephemeralMeasurement;
-    WebCore::Timer m_firePendingAttributionRequestsTimer;
-    bool m_isRunningTest { false };
-    bool m_isRunningEphemeralMeasurementTest { false };
-    std::optional<URL> m_tokenPublicKeyURLForTesting;
-    std::optional<URL> m_tokenSignatureURLForTesting;
-    mutable RefPtr<PCM::Store> m_store;
-    String m_storageDirectory;
-    UniqueRef<PCM::Client> m_client;
-
-    struct AttributionReportTestConfig {
-        URL attributionReportSourceURL;
-        URL attributionReportAttributeOnURL;
-    };
-
-    std::optional<AttributionReportTestConfig> m_attributionReportTestConfig;
-
-    struct TestingFraudPreventionValues {
-        String unlinkableToken;
-        String secretToken;
-        String signature;
-        String keyID;
-    };
-
-    std::optional<TestingFraudPreventionValues> m_fraudPreventionValuesForTesting;
-};
-    
-} // namespace WebKit

Deleted: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp (281960 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "config.h"
-#include "PrivateClickMeasurementNetworkLoader.h"
-
-#include "NetworkLoad.h"
-#include "NetworkSession.h"
-#include <WebCore/MIMETypeRegistry.h>
-#include <WebCore/TextResourceDecoder.h>
-
-#include <wtf/JSONValues.h>
-
-namespace WebKit {
-
-using namespace WebCore;
-
-void PrivateClickMeasurementNetworkLoader::start(NetworkSession& session, NetworkLoadParameters&& parameters, Callback&& completionHandler)
-{
-    auto loader = std::unique_ptr<PrivateClickMeasurementNetworkLoader>(new PrivateClickMeasurementNetworkLoader(session, WTFMove(parameters), WTFMove(completionHandler)));
-    session.addPrivateClickMeasurementNetworkLoader(WTFMove(loader));
-}
-
-PrivateClickMeasurementNetworkLoader::PrivateClickMeasurementNetworkLoader(NetworkSession& session, NetworkLoadParameters&& parameters, Callback&& completionHandler)
-    : m_session(makeWeakPtr(session))
-    , m_completionHandler(WTFMove(completionHandler))
-{
-    m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), *m_session);
-    m_networkLoad->start();
-}
-
-PrivateClickMeasurementNetworkLoader::~PrivateClickMeasurementNetworkLoader()
-{
-    cancel();
-}
-
-void PrivateClickMeasurementNetworkLoader::fail(ResourceError&& error)
-{
-    if (!m_completionHandler)
-        return;
-
-    m_completionHandler(WTFMove(error), { }, nullptr);
-    didComplete();
-}
-
-void PrivateClickMeasurementNetworkLoader::cancel()
-{
-    fail(ResourceError { ResourceError::Type::Cancellation });
-}
-
-void PrivateClickMeasurementNetworkLoader::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&&, ResourceResponse&&)
-{
-    cancel();
-}
-
-void PrivateClickMeasurementNetworkLoader::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
-{
-    if (!MIMETypeRegistry::isSupportedJSONMIMEType(response.mimeType())) {
-        fail({ errorDomainWebKitInternal, 0, response.url(), "MIME Type is not a JSON MIME type"_s });
-        completionHandler(PolicyAction::Ignore);
-        return;
-    }
-
-    m_response = WTFMove(response);
-    completionHandler(PolicyAction::Use);
-}
-
-void PrivateClickMeasurementNetworkLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength)
-{
-    if (!m_decoder)
-        m_decoder = TextResourceDecoder::create("application/json"_s, m_response.textEncodingName().isEmpty() ? WebCore::TextEncoding("UTF-8") : WebCore::TextEncoding(m_response.textEncodingName()));
-
-    if (auto size = buffer->size())
-        m_jsonString.append(m_decoder->decode(buffer->data(), size));
-}
-
-void PrivateClickMeasurementNetworkLoader::didFinishLoading(const WebCore::NetworkLoadMetrics&)
-{
-    if (m_decoder)
-        m_jsonString.append(m_decoder->flush());
-
-    if (auto jsonValue = JSON::Value::parseJSON(m_jsonString.toString()))
-        m_completionHandler({ }, m_response, jsonValue->asObject());
-    else
-        m_completionHandler({ }, m_response, nullptr);
-
-    didComplete();
-}
-
-void PrivateClickMeasurementNetworkLoader::didFailLoading(const ResourceError& error)
-{
-    fail(ResourceError(error));
-}
-
-void PrivateClickMeasurementNetworkLoader::didComplete()
-{
-    m_networkLoad = nullptr;
-    if (m_session)
-        m_session->removePrivateClickMeasurementNetworkLoader(this);
-}
-
-} // namespace WebKit

Deleted: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h (281960 => 281961)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 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
-
-#include "NetworkLoad.h"
-#include "NetworkLoadClient.h"
-#include "NetworkLoadParameters.h"
-#include <WebCore/TextResourceDecoder.h>
-#include <wtf/CompletionHandler.h>
-#include <wtf/WeakPtr.h>
-
-namespace WebKit {
-
-class NetworkSession;
-
-class PrivateClickMeasurementNetworkLoader final : public NetworkLoadClient {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    using Callback = CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&, const RefPtr<JSON::Object>&)>;
-    static void start(NetworkSession&, NetworkLoadParameters&&, Callback&&);
-
-    ~PrivateClickMeasurementNetworkLoader();
-
-private:
-    PrivateClickMeasurementNetworkLoader(NetworkSession&, NetworkLoadParameters&&, Callback&&);
-
-    // NetworkLoadClient.
-    void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final { }
-    bool isSynchronous() const final { return false; }
-    bool isAllowedToAskUserForCredentials() const final { return false; }
-    void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse) final;
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
-    void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) final;
-    void didFinishLoading(const WebCore::NetworkLoadMetrics&) final;
-    void didFailLoading(const WebCore::ResourceError&) final;
-
-    void fail(WebCore::ResourceError&&);
-    void cancel();
-    void didComplete();
-
-    WeakPtr<NetworkSession> m_session;
-    std::unique_ptr<NetworkLoad> m_networkLoad;
-    Callback m_completionHandler;
-
-    WebCore::ResourceResponse m_response;
-    RefPtr<WebCore::TextResourceDecoder> m_decoder;
-    StringBuilder m_jsonString;
-};
-
-} // namespace WebKit

Modified: trunk/Source/WebKit/Sources.txt (281960 => 281961)


--- trunk/Source/WebKit/Sources.txt	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/Sources.txt	2021-09-02 23:03:37 UTC (rev 281961)
@@ -58,8 +58,6 @@
 GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp
 
 NetworkProcess/DatabaseUtilities.cpp
-NetworkProcess/PrivateClickMeasurementManager.cpp
-NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp
 NetworkProcess/NetworkActivityTracker.cpp
 NetworkProcess/NetworkBroadcastChannelRegistry.cpp
 NetworkProcess/NetworkCORSPreflightChecker.cpp
@@ -102,6 +100,8 @@
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementClientImpl.cpp
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.cpp
+NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp
+NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementNetworkLoader.cpp
 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp
 
 NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp @no-unify

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (281960 => 281961)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-09-02 22:44:04 UTC (rev 281960)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-09-02 23:03:37 UTC (rev 281961)
@@ -1074,8 +1074,6 @@
 		517CF0E3163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */; };
 		517CF0E3163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */; };
 		517CF0E4163A486C00C2950E /* NetworkProcessConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 517CF0E2163A486C00C2950E /* NetworkProcessConnectionMessages.h */; };
-		5183247C26168C62003F239E /* NetworkURLSchemeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 51832475261599CC003F239E /* NetworkURLSchemeHandler.h */; };
-		5183247D26168FF7003F239E /* NetworkURLSchemeTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5183247A26168675003F239E /* NetworkURLSchemeTask.h */; };
 		5183722223CE97410003CF83 /* APIContentWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 5183722023CE973A0003CF83 /* APIContentWorld.h */; };
 		51871B5C127CB89D00F76232 /* WebContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 51871B5A127CB89D00F76232 /* WebContextMenu.h */; };
 		518ACAEA12AEE6BB00B04B83 /* WKProtectionSpaceTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 518ACAE912AEE6BB00B04B83 /* WKProtectionSpaceTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4112,12 +4110,8 @@
 		517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkProcessConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkProcessConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
 		517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheStorageEngineConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/CacheStorageEngineConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
 		517CF0E2163A486C00C2950E /* NetworkProcessConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkProcessConnectionMessages.h; path = DerivedSources/WebKit2/NetworkProcessConnectionMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
-		51832475261599CC003F239E /* NetworkURLSchemeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkURLSchemeHandler.h; sourceTree = "<group>"; };
-		51832476261599CC003F239E /* NetworkURLSchemeHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkURLSchemeHandler.cpp; sourceTree = "<group>"; };
 		518324782615B00D003F239E /* NetworkSchemeURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkSchemeURLProtocol.h; sourceTree = "<group>"; };
 		518324792615B00D003F239E /* NetworkSchemeURLProtocol.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkSchemeURLProtocol.mm; sourceTree = "<group>"; };
-		5183247A26168675003F239E /* NetworkURLSchemeTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkURLSchemeTask.h; sourceTree = "<group>"; };
-		5183247B26168675003F239E /* NetworkURLSchemeTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkURLSchemeTask.cpp; sourceTree = "<group>"; };
 		5183722023CE973A0003CF83 /* APIContentWorld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIContentWorld.h; sourceTree = "<group>"; };
 		5183722123CE973A0003CF83 /* APIContentWorld.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIContentWorld.cpp; sourceTree = "<group>"; };
 		5183B3931379F85C00E8754E /* Shim.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shim.xcconfig; sourceTree = "<group>"; };
@@ -8747,18 +8741,10 @@
 				5C0B177E1E7C886700E9123C /* NetworkSocketStream.h */,
 				5C0B177F1E7C886700E9123C /* NetworkSocketStream.messages.in */,
 				5C9EF2E721F058F9003BDC56 /* NetworkStorageSessionProvider.h */,
-				51832476261599CC003F239E /* NetworkURLSchemeHandler.cpp */,
-				51832475261599CC003F239E /* NetworkURLSchemeHandler.h */,
-				5183247B26168675003F239E /* NetworkURLSchemeTask.cpp */,
-				5183247A26168675003F239E /* NetworkURLSchemeTask.h */,
 				462107D71F38DBD300DD7810 /* PingLoad.cpp */,
 				5CE85B1F1C88E6430070BFCE /* PingLoad.h */,
 				83A0ED331F747CC7003299EB /* PreconnectTask.cpp */,
 				83A0ED321F747CC6003299EB /* PreconnectTask.h */,
-				6BD05864220CE8C2000BED5C /* PrivateClickMeasurementManager.cpp */,
-				6BD05863220CE8C2000BED5C /* PrivateClickMeasurementManager.h */,
-				57FE688B260ABB3D00BF45E4 /* PrivateClickMeasurementNetworkLoader.cpp */,
-				57FE688A260ABB3D00BF45E4 /* PrivateClickMeasurementNetworkLoader.h */,
 				E1B78470163F24690007B692 /* RemoteNetworkingContext.h */,
 				41287D4D225C161F009A3E26 /* WebSocketTask.h */,
 			);
@@ -9272,6 +9258,10 @@
 				5C826D6926D482EA008AEC91 /* PrivateClickMeasurementDatabase.h */,
 				5CBE909026D7FB7C005A2E95 /* PrivateClickMeasurementDebugInfo.cpp */,
 				5CBE908F26D7FB62005A2E95 /* PrivateClickMeasurementDebugInfo.h */,
+				6BD05864220CE8C2000BED5C /* PrivateClickMeasurementManager.cpp */,
+				6BD05863220CE8C2000BED5C /* PrivateClickMeasurementManager.h */,
+				57FE688B260ABB3D00BF45E4 /* PrivateClickMeasurementNetworkLoader.cpp */,
+				57FE688A260ABB3D00BF45E4 /* PrivateClickMeasurementNetworkLoader.h */,
 				5C826D6726D46B43008AEC91 /* PrivateClickMeasurementStore.cpp */,
 				5C826D6826D46B44008AEC91 /* PrivateClickMeasurementStore.h */,
 			);
@@ -12275,8 +12265,6 @@
 				5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */,
 				532159551DBAE7290054AA3C /* NetworkSessionCocoa.h in Headers */,
 				417915B92257046F00D6F97E /* NetworkSocketChannel.h in Headers */,
-				5183247C26168C62003F239E /* NetworkURLSchemeHandler.h in Headers */,
-				5183247D26168FF7003F239E /* NetworkURLSchemeTask.h in Headers */,
 				570DAAC22303730300E8FC04 /* NfcConnection.h in Headers */,
 				570DAAAE23026F5C00E8FC04 /* NfcService.h in Headers */,
 				31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */,
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to