[iOS] Support pasting item-provider-backed data on the pasteboard as attachment elements
[WebKit-https.git] / Source / WebCore / loader / AdClickAttribution.cpp
1 /*
2  * Copyright (C) 2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "AdClickAttribution.h"
28
29 #include <wtf/RandomNumber.h>
30 #include <wtf/URL.h>
31 #include <wtf/text/StringBuilder.h>
32
33 namespace WebCore {
34
35 bool AdClickAttribution::isValid() const
36 {
37     return m_conversion
38         && m_conversion.value().isValid()
39         && m_campaign.isValid()
40         && !m_source.registrableDomain.isEmpty()
41         && !m_destination.registrableDomain.isEmpty()
42         && m_earliestTimeToSend;
43 }
44
45 void AdClickAttribution::setConversion(Conversion&& conversion)
46 {
47     if (!conversion.isValid() || (m_conversion && m_conversion->priority > conversion.priority))
48         return;
49
50     m_conversion = WTFMove(conversion);
51     // 24-48 hour delay before sending. This helps privacy since the conversion and the attribution
52     // requests are detached and the time of the attribution does not reveal the time of the conversion.
53     m_earliestTimeToSend = m_timeOfAdClick + 24_h + Seconds(randomNumber() * (24_h).value());
54 }
55
56 URL AdClickAttribution::url() const
57 {
58     if (!isValid())
59         return URL();
60
61     StringBuilder builder;
62     builder.appendLiteral("https://");
63     builder.append(m_source.registrableDomain);
64     builder.appendLiteral("/.well-known/ad-click-attribution/");
65     builder.appendNumber(m_conversion.value().data);
66     builder.append('/');
67     builder.appendNumber(m_campaign.id);
68
69     URL url { URL(), builder.toString() };
70     if (url.isValid())
71         return url;
72
73     return URL();
74 }
75
76 URL AdClickAttribution::referrer() const
77 {
78     if (!isValid())
79         return URL();
80
81     StringBuilder builder;
82     builder.appendLiteral("https://");
83     builder.append(m_destination.registrableDomain);
84     builder.append('/');
85
86     URL url { URL(), builder.toString() };
87     if (url.isValid())
88         return url;
89     
90     return URL();
91 }
92
93 String AdClickAttribution::toString() const
94 {
95     StringBuilder builder;
96     builder.appendLiteral("Source: ");
97     builder.append(m_source.registrableDomain);
98     builder.appendLiteral("\nDestination: ");
99     builder.append(m_destination.registrableDomain);
100     builder.appendLiteral("\nCampaign ID: ");
101     builder.appendNumber(m_campaign.id);
102     if (m_conversion) {
103         builder.appendLiteral("\nConversion data: ");
104         builder.appendNumber(m_conversion.value().data);
105     } else
106         builder.appendLiteral("\nNo conversion data.");
107     builder.append('\n');
108
109     return builder.toString();
110 }
111
112 }