OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/beacon/NavigatorBeacon.h" | 6 #include "modules/beacon/NavigatorBeacon.h" |
7 | 7 |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
9 #include "bindings/modules/v8/UnionTypesModules.h" | 9 #include "bindings/modules/v8/UnionTypesModules.h" |
10 #include "core/dom/DOMArrayBufferView.h" | 10 #include "core/dom/DOMArrayBufferView.h" |
11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
12 #include "core/dom/ExecutionContext.h" | 12 #include "core/dom/ExecutionContext.h" |
13 #include "core/fileapi/Blob.h" | 13 #include "core/fileapi/Blob.h" |
14 #include "core/frame/LocalFrame.h" | 14 #include "core/frame/LocalFrame.h" |
15 #include "core/frame/Settings.h" | 15 #include "core/frame/Settings.h" |
16 #include "core/frame/UseCounter.h" | 16 #include "core/frame/UseCounter.h" |
17 #include "core/frame/csp/ContentSecurityPolicy.h" | 17 #include "core/frame/csp/ContentSecurityPolicy.h" |
18 #include "core/html/DOMFormData.h" | 18 #include "core/html/DOMFormData.h" |
19 #include "core/loader/BeaconLoader.h" | 19 #include "core/loader/BeaconLoader.h" |
20 | 20 |
21 namespace blink { | 21 namespace blink { |
22 | 22 |
23 NavigatorBeacon::NavigatorBeacon(Navigator& navigator) | 23 NavigatorBeacon::NavigatorBeacon(Navigator& navigator) |
24 : m_transmittedBytes(0) | 24 : LocalFrameLifecycleObserver(navigator.frame()) |
25 , m_navigator(navigator) | 25 , m_transmittedBytes(0) |
| 26 { |
| 27 } |
| 28 |
| 29 NavigatorBeacon::~NavigatorBeacon() |
26 { | 30 { |
27 } | 31 } |
28 | 32 |
29 DEFINE_TRACE(NavigatorBeacon) | 33 DEFINE_TRACE(NavigatorBeacon) |
30 { | 34 { |
31 WillBeHeapSupplement<Navigator>::trace(visitor); | 35 LocalFrameLifecycleObserver::trace(visitor); |
| 36 HeapSupplement<Navigator>::trace(visitor); |
32 } | 37 } |
33 | 38 |
34 const char* NavigatorBeacon::supplementName() | 39 const char* NavigatorBeacon::supplementName() |
35 { | 40 { |
36 return "NavigatorBeacon"; | 41 return "NavigatorBeacon"; |
37 } | 42 } |
38 | 43 |
39 NavigatorBeacon& NavigatorBeacon::from(Navigator& navigator) | 44 NavigatorBeacon& NavigatorBeacon::from(Navigator& navigator) |
40 { | 45 { |
41 NavigatorBeacon* supplement = static_cast<NavigatorBeacon*>(WillBeHeapSupple
ment<Navigator>::from(navigator, supplementName())); | 46 NavigatorBeacon* supplement = static_cast<NavigatorBeacon*>(HeapSupplement<N
avigator>::from(navigator, supplementName())); |
42 if (!supplement) { | 47 if (!supplement) { |
43 supplement = new NavigatorBeacon(navigator); | 48 supplement = new NavigatorBeacon(navigator); |
44 provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement)); | 49 provideTo(navigator, supplementName(), supplement); |
45 } | 50 } |
46 return *supplement; | 51 return *supplement; |
47 } | 52 } |
48 | 53 |
49 bool NavigatorBeacon::canSendBeacon(ExecutionContext* context, const KURL& url,
ExceptionState& exceptionState) | 54 bool NavigatorBeacon::canSendBeacon(ExecutionContext* context, const KURL& url,
ExceptionState& exceptionState) |
50 { | 55 { |
51 if (!url.isValid()) { | 56 if (!url.isValid()) { |
52 exceptionState.throwDOMException(SyntaxError, "The URL argument is ill-f
ormed or unsupported."); | 57 exceptionState.throwDOMException(SyntaxError, "The URL argument is ill-f
ormed or unsupported."); |
53 return false; | 58 return false; |
54 } | 59 } |
55 // For now, only support HTTP and related. | 60 // For now, only support HTTP and related. |
56 if (!url.protocolIsInHTTPFamily()) { | 61 if (!url.protocolIsInHTTPFamily()) { |
57 exceptionState.throwDOMException(SyntaxError, "Beacons are only supporte
d over HTTP(S)."); | 62 exceptionState.throwDOMException(SyntaxError, "Beacons are only supporte
d over HTTP(S)."); |
58 return false; | 63 return false; |
59 } | 64 } |
60 // FIXME: CSP is not enforced on redirects, crbug.com/372197 | 65 // FIXME: CSP is not enforced on redirects, crbug.com/372197 |
61 if (!ContentSecurityPolicy::shouldBypassMainWorld(context) && !context->cont
entSecurityPolicy()->allowConnectToSource(url)) { | 66 if (!ContentSecurityPolicy::shouldBypassMainWorld(context) && !context->cont
entSecurityPolicy()->allowConnectToSource(url)) { |
62 // We can safely expose the URL to JavaScript, as these checks happen sy
nchronously before redirection. JavaScript receives no new information. | 67 // We can safely expose the URL to JavaScript, as these checks happen sy
nchronously before redirection. JavaScript receives no new information. |
63 exceptionState.throwSecurityError("Refused to send beacon to '" + url.el
idedString() + "' because it violates the document's Content Security Policy."); | 68 exceptionState.throwSecurityError("Refused to send beacon to '" + url.el
idedString() + "' because it violates the document's Content Security Policy."); |
64 return false; | 69 return false; |
65 } | 70 } |
66 | 71 |
67 // Do not allow sending Beacons over a Navigator that is detached. | 72 // If detached from frame, do not allow sending a Beacon. |
68 if (!m_navigator.frame() || !m_navigator.frame()->client()) | 73 if (!frame() || !frame()->client()) |
69 return false; | 74 return false; |
70 | 75 |
71 return true; | 76 return true; |
72 } | 77 } |
73 | 78 |
74 int NavigatorBeacon::maxAllowance() const | 79 int NavigatorBeacon::maxAllowance() const |
75 { | 80 { |
76 const Settings* settings = m_navigator.frame()->settings(); | 81 ASSERT(frame()); |
| 82 const Settings* settings = frame()->settings(); |
77 if (settings) { | 83 if (settings) { |
78 int maxAllowed = settings->maxBeaconTransmission(); | 84 int maxAllowed = settings->maxBeaconTransmission(); |
79 if (maxAllowed < m_transmittedBytes) | 85 if (maxAllowed < m_transmittedBytes) |
80 return 0; | 86 return 0; |
81 return maxAllowed - m_transmittedBytes; | 87 return maxAllowed - m_transmittedBytes; |
82 } | 88 } |
83 return m_transmittedBytes; | 89 return m_transmittedBytes; |
84 } | 90 } |
85 | 91 |
86 bool NavigatorBeacon::beaconResult(ExecutionContext* context, bool allowed, int
sentBytes) | 92 bool NavigatorBeacon::beaconResult(ExecutionContext* context, bool allowed, int
sentBytes) |
(...skipping 13 matching lines...) Expand all Loading... |
100 | 106 |
101 KURL url = context->completeURL(urlstring); | 107 KURL url = context->completeURL(urlstring); |
102 if (!impl.canSendBeacon(context, url, exceptionState)) | 108 if (!impl.canSendBeacon(context, url, exceptionState)) |
103 return false; | 109 return false; |
104 | 110 |
105 int allowance = impl.maxAllowance(); | 111 int allowance = impl.maxAllowance(); |
106 int bytes = 0; | 112 int bytes = 0; |
107 bool allowed; | 113 bool allowed; |
108 | 114 |
109 if (data.isArrayBufferView()) | 115 if (data.isArrayBufferView()) |
110 allowed = BeaconLoader::sendBeacon(navigator.frame(), allowance, url, da
ta.getAsArrayBufferView(), bytes); | 116 allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.ge
tAsArrayBufferView(), bytes); |
111 else if (data.isBlob()) | 117 else if (data.isBlob()) |
112 allowed = BeaconLoader::sendBeacon(navigator.frame(), allowance, url, da
ta.getAsBlob(), bytes); | 118 allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.ge
tAsBlob(), bytes); |
113 else if (data.isString()) | 119 else if (data.isString()) |
114 allowed = BeaconLoader::sendBeacon(navigator.frame(), allowance, url, da
ta.getAsString(), bytes); | 120 allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.ge
tAsString(), bytes); |
115 else if (data.isFormData()) | 121 else if (data.isFormData()) |
116 allowed = BeaconLoader::sendBeacon(navigator.frame(), allowance, url, da
ta.getAsFormData(), bytes); | 122 allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.ge
tAsFormData(), bytes); |
117 else | 123 else |
118 allowed = BeaconLoader::sendBeacon(navigator.frame(), allowance, url, St
ring(), bytes); | 124 allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, String(
), bytes); |
119 | 125 |
120 return impl.beaconResult(context, allowed, bytes); | 126 return impl.beaconResult(context, allowed, bytes); |
121 } | 127 } |
122 | 128 |
123 } // namespace blink | 129 } // namespace blink |
OLD | NEW |