Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: Source/modules/beacon/NavigatorBeacon.cpp

Issue 232053005: Implement navigator.sendBeacon() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Restructured ping loader code + added size restriction Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "modules/beacon/NavigatorBeacon.h"
7
8 #include "bindings/v8/ExceptionState.h"
9 #include "core/dom/ExceptionCode.h"
10 #include "core/dom/ExecutionContext.h"
11 #include "core/fileapi/Blob.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/frame/Settings.h"
14 #include "core/frame/csp/ContentSecurityPolicy.h"
15 #include "core/html/DOMFormData.h"
16 #include "core/loader/BeaconLoader.h"
17 #include "wtf/ArrayBufferView.h"
18
19 namespace WebCore {
20
21 NavigatorBeacon::NavigatorBeacon(Navigator& navigator)
22 : m_transmittedBytes(0)
23 , m_navigator(navigator)
24 {
25 }
26
27 const char* NavigatorBeacon::supplementName()
28 {
29 return "NavigatorBeacon";
30 }
31
32 NavigatorBeacon& NavigatorBeacon::from(Navigator& navigator)
33 {
34 NavigatorBeacon* supplement = static_cast<NavigatorBeacon*>(WillBeHeapSupple ment<Navigator>::from(navigator, supplementName()));
35 if (!supplement) {
36 supplement = new NavigatorBeacon(navigator);
37 provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement));
38 }
39 return *supplement;
40 }
41
42 bool NavigatorBeacon::isAllowedAccess(ExecutionContext* context, const KURL& url , ExceptionState& exceptionState)
abarth-chromium 2014/05/08 13:15:25 s/isAllowedAccess/canSendBeacon/ ?
sof 2014/05/08 20:47:07 That captures purpose more precisely, I like it. A
43 {
44 if (!url.isValid()) {
45 exceptionState.throwDOMException(SyntaxError, "The URL argument is ill-f ormed or unsupported.");
46 return false;
47 }
48 // For now, only support HTTP and related.
49 if (!url.protocolIsInHTTPFamily()) {
50 exceptionState.throwDOMException(SyntaxError, "Beacons are only supporte d over HTTP(S).");
51 return false;
52 }
53 if (!ContentSecurityPolicy::shouldBypassMainWorld(context) && !context->cont entSecurityPolicy()->allowConnectToSource(url)) {
54 // We can safely expose the URL to JavaScript, as these checks happen sy nchronously before redirection. JavaScript receives no new information.
55 exceptionState.throwSecurityError("Refused to send beacon to '" + url.el idedString() + "' because it violates the document's Content Security Policy.");
56 return false;
57 }
58
59 // Do not allow sending Beacons over a Navigator that is detached.
60 if (!m_navigator.frame())
61 return false;
62
63 return true;
64 }
65
66 int NavigatorBeacon::maxAllowance() const
67 {
68 const Settings* settings = m_navigator.frame() ? m_navigator.frame()->settin gs() : 0;
69 if (settings) {
abarth-chromium 2014/05/08 13:15:25 We usually combine these lines. I don't think we
sof 2014/05/08 20:47:07 Yes, removed the null check.
70 int maxAllowed = settings->maxBeaconTransmission();
71 if (maxAllowed < m_transmittedBytes)
72 return 0;
73 return maxAllowed - m_transmittedBytes;
74 }
75 return m_transmittedBytes;
76 }
77
78 void NavigatorBeacon::updateTransmittedBytes(int length)
79 {
80 ASSERT(length >= 0);
81 m_transmittedBytes += length;
82 }
83
84 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, Navigator& navigator , const String& urlstring, const String& data, ExceptionState& exceptionState)
85 {
86 return NavigatorBeacon::from(navigator).sendBeacon(context, urlstring, data, exceptionState);
87 }
88
89 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, const String& urlstr ing, const String& data, ExceptionState& exceptionState)
90 {
91 KURL url = context->completeURL(urlstring);
92 if (!isAllowedAccess(context, url, exceptionState))
93 return false;
94
95 int bytes = 0;
96 bool result = BeaconLoader::sendBeacon(m_navigator.frame(), maxAllowance(), url, data, bytes);
97 if (result)
98 updateTransmittedBytes(bytes);
99
100 return result;
101 }
102
103 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, Navigator& navigator , const String& urlstring, PassRefPtr<ArrayBufferView> data, ExceptionState& exc eptionState)
104 {
105 return NavigatorBeacon::from(navigator).sendBeacon(context, urlstring, data, exceptionState);
106 }
107
108 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, const String& urlstr ing, PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState)
109 {
110 KURL url = context->completeURL(urlstring);
111 if (!isAllowedAccess(context, url, exceptionState))
112 return false;
113
114 int bytes = 0;
115 bool result = BeaconLoader::sendBeacon(m_navigator.frame(), maxAllowance(), url, data, bytes);
116 if (result)
117 updateTransmittedBytes(bytes);
118
119 return result;
120 }
121
122 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, Navigator& navigator , const String& urlstring, PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& ex ceptionState)
123 {
124 return NavigatorBeacon::from(navigator).sendBeacon(context, urlstring, data, exceptionState);
125 }
126
127 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, const String& urlstr ing, PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exceptionState)
128 {
129 KURL url = context->completeURL(urlstring);
130 if (!isAllowedAccess(context, url, exceptionState))
131 return false;
132
133 int bytes = 0;
134 bool result = BeaconLoader::sendBeacon(m_navigator.frame(), maxAllowance(), url, data, bytes);
135 if (result)
136 updateTransmittedBytes(bytes);
137
138 return result;
139 }
140
141 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, Navigator& navigator , const String& urlstring, PassRefPtrWillBeRawPtr<DOMFormData> data, ExceptionSt ate& exceptionState)
142 {
143 return NavigatorBeacon::from(navigator).sendBeacon(context, urlstring, data, exceptionState);
144 }
145
146 bool NavigatorBeacon::sendBeacon(ExecutionContext* context, const String& urlstr ing, PassRefPtrWillBeRawPtr<DOMFormData> data, ExceptionState& exceptionState)
147 {
148 KURL url = context->completeURL(urlstring);
149 if (!isAllowedAccess(context, url, exceptionState))
150 return false;
151
152 int bytes = 0;
153 bool result = BeaconLoader::sendBeacon(m_navigator.frame(), maxAllowance(), url, data, bytes);
154 if (result)
155 updateTransmittedBytes(bytes);
156
157 return result;
158 }
159
160 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698