Changeset 269489 in webkit


Ignore:
Timestamp:
Nov 5, 2020 4:16:56 PM (21 months ago)
Author:
wilander@apple.com
Message:

PCM: Switch to JSON report format
https://bugs.webkit.org/show_bug.cgi?id=218634
<rdar://problem/70469923>

Reviewed by Brent Fulgham.

The standards conversation has landed in attribution reports in a JSON
format as opposed to the currently implemented URL format. Discussion
here: https://github.com/privacycg/private-click-measurement/issues/30

Source/WebCore:

No new tests. Existing layout and API tests were updated.

  • Headers.cmake:

Added platform/network/HTTPHeaderValues.h to be able to expose it
to WebKit.

  • WebCore.xcodeproj/project.pbxproj:

Now exporting platform/network/HTTPHeaderValues.h.

  • html/HTMLAnchorElement.cpp:

(WebCore::HTMLAnchorElement::handleClick):

Changed a function call from AdClickAttribution::url() to
AdClickAttribution::reportURL().

  • loader/AdClickAttribution.cpp:

(WebCore::AdClickAttribution::reportURL const):

The URL no longer carries the report values.
Renamed from AdClickAttribution::url().

(WebCore::AdClickAttribution::json const):

New function to generate and return the report JSON.

(WebCore::AdClickAttribution::url const): Deleted.

Renamed to AdClickAttribution::reportURL().

(WebCore::AdClickAttribution::referrer const): Deleted.

The referrer is now part of the report JSON.

(WebCore::AdClickAttribution::urlForTesting const): Deleted.

This class no longer needs to help generate test URLs
since report values are now in JSON.

  • loader/AdClickAttribution.h:
  • platform/network/FormData.h:

Added export of create(const CString&).

  • platform/network/HTTPHeaderValues.cpp:

(WebCore::HTTPHeaderValues::applicationJSONContentType):

Used create the new JSON report request.

  • platform/network/HTTPHeaderValues.h:

Added export of maxAge0().

Source/WebKit:

  • NetworkProcess/AdClickAttributionManager.cpp:

(WebKit::AdClickAttributionManager::fireConversionRequest):

Tools:

  • TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp:

(TestWebKitAPI::TEST):

LayoutTests:

  • http/tests/adClickAttribution/resources/conversionReport.php:
  • http/tests/adClickAttribution/send-attribution-conversion-request-expected.txt:
Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r269477 r269489  
     12020-11-05  John Wilander  <wilander@apple.com>
     2
     3        PCM: Switch to JSON report format
     4        https://bugs.webkit.org/show_bug.cgi?id=218634
     5        <rdar://problem/70469923>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        The standards conversation has landed in attribution reports in a JSON
     10        format as opposed to the currently implemented URL format. Discussion
     11        here: https://github.com/privacycg/private-click-measurement/issues/30
     12
     13        * http/tests/adClickAttribution/resources/conversionReport.php:
     14        * http/tests/adClickAttribution/send-attribution-conversion-request-expected.txt:
     15
    1162020-11-05  Chris Dumez  <cdumez@apple.com>
    217
  • trunk/LayoutTests/http/tests/adClickAttribution/resources/conversionReport.php

    r244475 r269489  
    99        fwrite($conversionFile, "$name: $value\n");
    1010    } else if ($name === "REQUEST_URI") {
    11         $positionOfNonce = strpos($value, "&nonce=");
     11        $positionOfNonce = strpos($value, "?nonce=");
    1212        if ($positionOfNonce === false)
    1313            $outputURL = $value;
     
    1818        fwrite($conversionFile, "Cookies in conversion request: $value\n");
    1919        $cookiesFound = true;
     20    } else if ($name === "CONTENT_TYPE") {
     21        fwrite($conversionFile, "Content type: $value\n");
    2022    }
    2123}
     
    2325    fwrite($conversionFile, "No cookies in conversion request.\n");
    2426}
     27
     28$requestBody = file_get_contents('php://input');
     29fwrite($conversionFile, "Request body:\n$requestBody\n");
     30
    2531fclose($conversionFile);
    2632rename($conversionFilePath . ".tmp", $conversionFilePath);
  • trunk/LayoutTests/http/tests/adClickAttribution/send-attribution-conversion-request-expected.txt

    r244475 r269489  
    1313Conversion received.
    1414HTTP_HOST: 127.0.0.1:8000
    15 REQUEST_URI: /adClickAttribution/resources/conversionReport.php?conversion=12&campaign=3
     15Content type: application/json
     16REQUEST_URI: /adClickAttribution/resources/conversionReport.php
    1617No cookies in conversion request.
     18Request body:
     19{"content-type":"click","content-site":"127.0.0.1","content-id":3,"conversion-site":"localhost","conversion-data":12,"report-version":1}
    1720
    1821
  • trunk/Source/WebCore/ChangeLog

    r269486 r269489  
     12020-11-05  John Wilander  <wilander@apple.com>
     2
     3        PCM: Switch to JSON report format
     4        https://bugs.webkit.org/show_bug.cgi?id=218634
     5        <rdar://problem/70469923>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        The standards conversation has landed in attribution reports in a JSON
     10        format as opposed to the currently implemented URL format. Discussion
     11        here: https://github.com/privacycg/private-click-measurement/issues/30
     12
     13        No new tests. Existing layout and API tests were updated.
     14
     15        * Headers.cmake:
     16            Added platform/network/HTTPHeaderValues.h to be able to expose it
     17            to WebKit.
     18        * WebCore.xcodeproj/project.pbxproj:
     19            Now exporting platform/network/HTTPHeaderValues.h.
     20        * html/HTMLAnchorElement.cpp:
     21        (WebCore::HTMLAnchorElement::handleClick):
     22            Changed a function call from AdClickAttribution::url() to
     23            AdClickAttribution::reportURL().
     24        * loader/AdClickAttribution.cpp:
     25        (WebCore::AdClickAttribution::reportURL const):
     26            The URL no longer carries the report values.
     27            Renamed from AdClickAttribution::url().
     28        (WebCore::AdClickAttribution::json const):
     29            New function to generate and return the report JSON.
     30        (WebCore::AdClickAttribution::url const): Deleted.
     31            Renamed to AdClickAttribution::reportURL().
     32        (WebCore::AdClickAttribution::referrer const): Deleted.
     33            The referrer is now part of the report JSON.
     34        (WebCore::AdClickAttribution::urlForTesting const): Deleted.
     35            This class no longer needs to help generate test URLs
     36            since report values are now in JSON.
     37        * loader/AdClickAttribution.h:
     38        * platform/network/FormData.h:
     39            Added export of create(const CString&).
     40        * platform/network/HTTPHeaderValues.cpp:
     41        (WebCore::HTTPHeaderValues::applicationJSONContentType):
     42            Used create the new JSON report request.
     43        * platform/network/HTTPHeaderValues.h:
     44            Added export of maxAge0().
     45
    1462020-11-05  Brian Burg  <bburg@apple.com>
    247
  • trunk/Source/WebCore/Headers.cmake

    r269348 r269489  
    13441344    platform/network/HTTPCookieAcceptPolicy.h
    13451345    platform/network/HTTPHeaderMap.h
     1346    platform/network/HTTPHeaderValues.h
    13461347    platform/network/HTTPParsers.h
    13471348    platform/network/NetworkLoadInformation.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r269415 r269489  
    10681068                415864A023BF7CBF00A0A61E /* RealtimeVideoUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D1938F2152C561006F14CA /* RealtimeVideoUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10691069                415CDAF51E6B8F8B004F11EE /* CanvasCaptureMediaStreamTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C7E1061E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.h */; };
    1070                 41614A791DA64241004AD06F /* HTTPHeaderValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 41614A771DA64236004AD06F /* HTTPHeaderValues.h */; };
     1070                41614A791DA64241004AD06F /* HTTPHeaderValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 41614A771DA64236004AD06F /* HTTPHeaderValues.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10711071                4161E2D51FE48DC500EC2E96 /* FetchLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4147E2B51C89912600A7E715 /* FetchLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10721072                4162A451101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A44E101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h */; };
  • trunk/Source/WebCore/html/HTMLAnchorElement.cpp

    r266360 r269489  
    522522    // A matching conversion event needs to happen before the complete ad click attributionURL can be
    523523    // created. Thus, it should be empty for now.
    524     ASSERT(!adClickAttribution || adClickAttribution->url().isNull());
     524    ASSERT(!adClickAttribution || adClickAttribution->reportURL().isNull());
    525525   
    526526    frame->loader().changeLocation(completedURL, effectiveTarget, &event, LockHistory::No, LockBackForwardList::No, referrerPolicy, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo, WTFMove(adClickAttribution));
  • trunk/Source/WebCore/loader/AdClickAttribution.cpp

    r260707 r269489  
    148148}
    149149
    150 URL AdClickAttribution::url() const
     150URL AdClickAttribution::reportURL() const
    151151{
    152152    if (!isValid())
     
    157157    builder.append(m_source.registrableDomain.string());
    158158    builder.appendLiteral(adClickAttributionPathPrefix);
    159     builder.appendNumber(m_conversion.value().data);
    160     builder.append('/');
    161     builder.appendNumber(m_campaign.id);
    162159
    163160    URL url { URL(), builder.toString() };
     
    168165}
    169166
    170 URL AdClickAttribution::referrer() const
    171 {
    172     if (!isValid())
    173         return URL();
    174 
    175     StringBuilder builder;
    176     builder.appendLiteral("https://");
    177     builder.append(m_destination.registrableDomain.string());
    178     builder.append('/');
    179 
    180     URL url { URL(), builder.toString() };
    181     if (url.isValid())
    182         return url;
    183    
    184     return URL();
    185 }
    186 
    187 URL AdClickAttribution::urlForTesting(const URL& baseURL) const
    188 {
    189     auto host = m_source.registrableDomain.string();
    190     if (host != "localhost" && host != "127.0.0.1")
    191         return URL();
    192     String relativeURL;
    193     if (!baseURL.hasQuery())
    194         relativeURL = makeString("?conversion=", m_conversion.value().data, "&campaign=", m_campaign.id);
    195     else
    196         relativeURL = makeString("?conversion=", m_conversion.value().data, "&campaign=", m_campaign.id, '&', baseURL.query());
    197     return URL(baseURL, relativeURL);
     167Ref<JSON::Object> AdClickAttribution::json() const
     168{
     169    auto reportDetails = JSON::Object::create();
     170    if (!m_conversion)
     171        return reportDetails;
     172
     173    reportDetails->setString("content-type"_s, "click"_s);
     174    reportDetails->setString("content-site"_s, m_source.registrableDomain.string());
     175    reportDetails->setInteger("content-id"_s, m_campaign.id);
     176    reportDetails->setString("conversion-site"_s, m_destination.registrableDomain.string());
     177    reportDetails->setInteger("conversion-data"_s, m_conversion->data);
     178    reportDetails->setInteger("report-version"_s, 1);
     179    return reportDetails;
    198180}
    199181
  • trunk/Source/WebCore/loader/AdClickAttribution.h

    r264488 r269489  
    2929#include <wtf/CompletionHandler.h>
    3030#include <wtf/Forward.h>
     31#include <wtf/JSONValues.h>
    3132#include <wtf/Optional.h>
    3233#include <wtf/URL.h>
     
    244245    WEBCORE_EXPORT Optional<Seconds> convertAndGetEarliestTimeToSend(Conversion&&);
    245246    WEBCORE_EXPORT bool hasHigherPriorityThan(const AdClickAttribution&) const;
    246     WEBCORE_EXPORT URL url() const;
    247     WEBCORE_EXPORT URL urlForTesting(const URL& baseURLForTesting) const;
    248     WEBCORE_EXPORT URL referrer() const;
     247    WEBCORE_EXPORT URL reportURL() const;
     248    WEBCORE_EXPORT Ref<JSON::Object> json() const;
    249249    const Source& source() const { return m_source; };
    250250    const Destination& destination() const { return m_destination; };
  • trunk/Source/WebCore/platform/network/FormData.h

    r268904 r269489  
    193193    WEBCORE_EXPORT static Ref<FormData> create();
    194194    WEBCORE_EXPORT static Ref<FormData> create(const void*, size_t);
    195     static Ref<FormData> create(const CString&);
     195    WEBCORE_EXPORT static Ref<FormData> create(const CString&);
    196196    static Ref<FormData> create(Vector<char>&&);
    197197    static Ref<FormData> create(const Vector<char>&);
  • trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp

    r220817 r269489  
    4545}
    4646
     47const String& applicationJSONContentType()
     48{
     49    // The default encoding is UTF-8: https://www.ietf.org/rfc/rfc4627.txt.
     50    static NeverDestroyed<const String> contentType(MAKE_STATIC_STRING_IMPL("application/json"));
     51    return contentType;
     52}
     53
    4754const String& noCache()
    4855{
  • trunk/Source/WebCore/platform/network/HTTPHeaderValues.h

    r220817 r269489  
    3333const String& textPlainContentType();
    3434const String& formURLEncodedContentType();
     35WEBCORE_EXPORT const String& applicationJSONContentType();
    3536const String& noCache();
    36 const String& maxAge0();
     37WEBCORE_EXPORT const String& maxAge0();
    3738}
    3839
  • trunk/Source/WebKit/ChangeLog

    r269486 r269489  
     12020-11-05  John Wilander  <wilander@apple.com>
     2
     3        PCM: Switch to JSON report format
     4        https://bugs.webkit.org/show_bug.cgi?id=218634
     5        <rdar://problem/70469923>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        The standards conversation has landed in attribution reports in a JSON
     10        format as opposed to the currently implemented URL format. Discussion
     11        here: https://github.com/privacycg/private-click-measurement/issues/30
     12
     13        * NetworkProcess/AdClickAttributionManager.cpp:
     14        (WebKit::AdClickAttributionManager::fireConversionRequest):
     15
    1162020-11-05  Brian Burg  <bburg@apple.com>
    217
  • trunk/Source/WebKit/NetworkProcess/AdClickAttributionManager.cpp

    r259236 r269489  
    3131#include <WebCore/FetchOptions.h>
    3232#include <WebCore/FormData.h>
     33#include <WebCore/HTTPHeaderValues.h>
    3334#include <WebCore/ResourceError.h>
    3435#include <WebCore/ResourceRequest.h>
     
    172173void AdClickAttributionManager::fireConversionRequest(const AdClickAttribution& attribution)
    173174{
    174     auto conversionURL = m_conversionBaseURLForTesting ? attribution.urlForTesting(*m_conversionBaseURLForTesting) : attribution.url();
     175    auto conversionURL = m_conversionBaseURLForTesting ? *m_conversionBaseURLForTesting : attribution.reportURL();
    175176    if (conversionURL.isEmpty() || !conversionURL.isValid())
    176177        return;
    177178
    178     auto conversionReferrerURL = attribution.referrer();
    179     if (conversionReferrerURL.isEmpty() || !conversionReferrerURL.isValid())
    180         return;
    181 
    182     ResourceRequest request { conversionURL };
     179    ResourceRequest request { WTFMove(conversionURL) };
    183180   
    184181    request.setHTTPMethod("POST"_s);
    185     request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0"_s);
    186     request.setHTTPReferrer(conversionReferrerURL.string());
     182    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, WebCore::HTTPHeaderValues::maxAge0());
     183
     184    request.setHTTPContentType(WebCore::HTTPHeaderValues::applicationJSONContentType());
     185    request.setHTTPBody(WebCore::FormData::create(attribution.json()->toJSONString().utf8().data()));
    187186
    188187    FetchOptions options;
     
    195194    loadParameters.identifier = ++identifier;
    196195    loadParameters.request = request;
    197     loadParameters.sourceOrigin = SecurityOrigin::create(conversionReferrerURL);
    198196    loadParameters.parentPID = presentingApplicationPID();
    199197    loadParameters.storedCredentialsPolicy = StoredCredentialsPolicy::EphemeralStateless;
     
    201199    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = true;
    202200    loadParameters.shouldRestrictHTTPResponseAccess = false;
    203 
    204 #if ENABLE(CONTENT_EXTENSIONS)
    205     loadParameters.mainDocumentURL = WTFMove(conversionReferrerURL);
    206 #endif
    207201
    208202    if (UNLIKELY(debugModeEnabled())) {
  • trunk/Tools/ChangeLog

    r269486 r269489  
     12020-11-05  John Wilander  <wilander@apple.com>
     2
     3        PCM: Switch to JSON report format
     4        https://bugs.webkit.org/show_bug.cgi?id=218634
     5        <rdar://problem/70469923>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        The standards conversation has landed in attribution reports in a JSON
     10        format as opposed to the currently implemented URL format. Discussion
     11        here: https://github.com/privacycg/private-click-measurement/issues/30
     12
     13        * TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp:
     14        (TestWebKitAPI::TEST):
     15
    1162020-11-05  Brian Burg  <bburg@apple.com>
    217
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/AdClickAttribution.cpp

    r244288 r269489  
    4747    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(min6BitValue, AdClickAttribution::Priority(min6BitValue)));
    4848
    49     auto attributionURL = attribution.url();
    50     auto referrerURL = attribution.referrer();
    51    
    52     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/0/0");
    53     ASSERT_EQ(referrerURL.string(), "https://example.com/");
     49    auto attributionURL = attribution.reportURL();
     50   
     51    ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/");
     52
     53    ASSERT_EQ(attribution.json()->toJSONString(), "{\"content-type\":\"click\",\"content-site\":\"webkit.org\",\"content-id\":0,\"conversion-site\":\"example.com\",\"conversion-data\":0,\"report-version\":1}");
    5454}
    5555
     
    5959    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion((uint32_t)44, AdClickAttribution::Priority((uint32_t)22)));
    6060
    61     auto attributionURL = attribution.url();
    62     auto referrerURL = attribution.referrer();
    63 
    64     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/44/12");
    65     ASSERT_EQ(referrerURL.string(), "https://example.com/");
     61    auto attributionURL = attribution.reportURL();
     62   
     63    ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/");
     64
     65    ASSERT_EQ(attribution.json()->toJSONString(), "{\"content-type\":\"click\",\"content-site\":\"webkit.org\",\"content-id\":12,\"conversion-site\":\"example.com\",\"conversion-data\":44,\"report-version\":1}");
    6666}
    6767
     
    7171    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(AdClickAttribution::MaxEntropy, AdClickAttribution::Priority(AdClickAttribution::MaxEntropy)));
    7272
    73     auto attributionURL = attribution.url();
    74     auto referrerURL = attribution.referrer();
    75 
    76     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/63/63");
    77     ASSERT_EQ(referrerURL.string(), "https://example.com/");
     73    auto attributionURL = attribution.reportURL();
     74   
     75    ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/ad-click-attribution/");
     76
     77    ASSERT_EQ(attribution.json()->toJSONString(), "{\"content-type\":\"click\",\"content-site\":\"webkit.org\",\"content-id\":63,\"conversion-site\":\"example.com\",\"conversion-data\":63,\"report-version\":1}");
    7878}
    7979
     
    131131    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(AdClickAttribution::MaxEntropy, AdClickAttribution::Priority(AdClickAttribution::MaxEntropy)));
    132132
    133     auto attributionURL = attribution.url();
    134     auto referrerURL = attribution.referrer();
    135 
    136     ASSERT_TRUE(attributionURL.string().isEmpty());
    137     ASSERT_TRUE(referrerURL.string().isEmpty());
     133    ASSERT_TRUE(attribution.reportURL().isEmpty());
    138134}
    139135
     
    143139    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(AdClickAttribution::MaxEntropy, AdClickAttribution::Priority(AdClickAttribution::MaxEntropy)));
    144140
    145     auto attributionURL = attribution.url();
    146     auto referrerURL = attribution.referrer();
    147 
    148     ASSERT_TRUE(attributionURL.string().isEmpty());
    149     ASSERT_TRUE(referrerURL.string().isEmpty());
     141    ASSERT_TRUE(attribution.reportURL().isEmpty());
    150142}
    151143
     
    155147    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(AdClickAttribution::MaxEntropy, AdClickAttribution::Priority(AdClickAttribution::MaxEntropy)));
    156148
    157     auto attributionURL = attribution.url();
    158     auto referrerURL = attribution.referrer();
    159 
    160     ASSERT_TRUE(attributionURL.string().isEmpty());
    161     ASSERT_TRUE(referrerURL.string().isEmpty());
     149    ASSERT_TRUE(attribution.reportURL().isEmpty());
    162150}
    163151
     
    167155    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion((AdClickAttribution::MaxEntropy + 1), AdClickAttribution::Priority(AdClickAttribution::MaxEntropy)));
    168156
    169     auto attributionURL = attribution.url();
    170     auto referrerURL = attribution.referrer();
    171 
    172     ASSERT_TRUE(attributionURL.string().isEmpty());
    173     ASSERT_TRUE(referrerURL.string().isEmpty());
     157    ASSERT_TRUE(attribution.reportURL().isEmpty());
    174158}
    175159
     
    179163    attribution.convertAndGetEarliestTimeToSend(AdClickAttribution::Conversion(AdClickAttribution::MaxEntropy, AdClickAttribution::Priority(AdClickAttribution::MaxEntropy + 1)));
    180164
    181     auto attributionURL = attribution.url();
    182     auto referrerURL = attribution.referrer();
    183 
    184     ASSERT_TRUE(attributionURL.string().isEmpty());
    185     ASSERT_TRUE(referrerURL.string().isEmpty());
     165    ASSERT_TRUE(attribution.reportURL().isEmpty());
    186166}
    187167
     
    190170    AdClickAttribution attribution { AdClickAttribution::Campaign(AdClickAttribution::MaxEntropy), AdClickAttribution::Source { webKitURL }, AdClickAttribution::Destination { exampleURL } };
    191171
    192     auto attributionURL = attribution.url();
    193     auto referrerURL = attribution.referrer();
    194 
    195     ASSERT_TRUE(attributionURL.string().isEmpty());
    196     ASSERT_TRUE(referrerURL.string().isEmpty());
     172    ASSERT_TRUE(attribution.reportURL().isEmpty());
    197173    ASSERT_FALSE(attribution.earliestTimeToSend());
    198174}
Note: See TracChangeset for help on using the changeset viewer.