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 "core/loader/BeaconLoader.h" | 6 #include "core/loader/BeaconLoader.h" |
7 | 7 |
8 #include "core/dom/DOMArrayBufferView.h" | 8 #include "core/dom/DOMArrayBufferView.h" |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/fetch/CrossOriginAccessControl.h" |
10 #include "core/fetch/FetchContext.h" | 11 #include "core/fetch/FetchContext.h" |
11 #include "core/fetch/FetchInitiatorTypeNames.h" | 12 #include "core/fetch/FetchInitiatorTypeNames.h" |
12 #include "core/fetch/ResourceFetcher.h" | 13 #include "core/fetch/ResourceFetcher.h" |
13 #include "core/fileapi/File.h" | 14 #include "core/fileapi/File.h" |
14 #include "core/frame/LocalFrame.h" | 15 #include "core/frame/LocalFrame.h" |
15 #include "core/html/DOMFormData.h" | 16 #include "core/html/DOMFormData.h" |
| 17 #include "core/inspector/ConsoleMessage.h" |
| 18 #include "core/loader/MixedContentChecker.h" |
| 19 #include "platform/exported/WrappedResourceRequest.h" |
| 20 #include "platform/exported/WrappedResourceResponse.h" |
16 #include "platform/network/FormData.h" | 21 #include "platform/network/FormData.h" |
17 #include "platform/network/ParsedContentType.h" | 22 #include "platform/network/ParsedContentType.h" |
18 #include "platform/network/ResourceRequest.h" | 23 #include "platform/network/ResourceRequest.h" |
19 #include "public/platform/WebURLRequest.h" | 24 #include "public/platform/WebURLRequest.h" |
20 #include "wtf/Functional.h" | 25 #include "wtf/Functional.h" |
21 | 26 |
22 namespace blink { | 27 namespace blink { |
23 | 28 |
24 namespace { | 29 namespace { |
25 | 30 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 private: | 66 private: |
62 const typename WTF::ParamStorageTraits<Payload>::StorageType m_data; | 67 const typename WTF::ParamStorageTraits<Payload>::StorageType m_data; |
63 }; | 68 }; |
64 | 69 |
65 } // namespace | 70 } // namespace |
66 | 71 |
67 class BeaconLoader::Sender { | 72 class BeaconLoader::Sender { |
68 public: | 73 public: |
69 static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, co
nst Beacon& beacon, int& payloadLength) | 74 static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, co
nst Beacon& beacon, int& payloadLength) |
70 { | 75 { |
| 76 if (!frame->document()) |
| 77 return false; |
| 78 |
71 unsigned long long entitySize = beacon.size(); | 79 unsigned long long entitySize = beacon.size(); |
72 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entity
Size) | 80 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entity
Size) |
73 return false; | 81 return false; |
74 | 82 |
75 ResourceRequest request(beaconURL); | 83 ResourceRequest request(beaconURL); |
76 request.setRequestContext(WebURLRequest::RequestContextBeacon); | 84 request.setRequestContext(WebURLRequest::RequestContextBeacon); |
77 request.setHTTPMethod("POST"); | 85 request.setHTTPMethod("POST"); |
78 request.setHTTPHeaderField("Cache-Control", "max-age=0"); | 86 request.setHTTPHeaderField("Cache-Control", "max-age=0"); |
79 request.setAllowStoredCredentials(true); | 87 request.setAllowStoredCredentials(true); |
80 frame->document()->fetcher()->context().addAdditionalRequestHeaders(requ
est, FetchSubresource); | 88 frame->document()->fetcher()->context().addAdditionalRequestHeaders(requ
est, FetchSubresource); |
81 frame->document()->fetcher()->context().setFirstPartyForCookies(request)
; | 89 frame->document()->fetcher()->context().setFirstPartyForCookies(request)
; |
82 | 90 |
| 91 if (MixedContentChecker::shouldBlockFetch(frame, request, request.url())
) |
| 92 return false; |
| 93 |
83 payloadLength = entitySize; | 94 payloadLength = entitySize; |
84 if (!beacon.serialize(request, allowance, payloadLength)) | 95 if (!beacon.serialize(request, allowance, payloadLength)) |
85 return false; | 96 return false; |
86 | 97 |
87 FetchInitiatorInfo initiatorInfo; | 98 FetchInitiatorInfo initiatorInfo; |
88 initiatorInfo.name = FetchInitiatorTypeNames::beacon; | 99 initiatorInfo.name = FetchInitiatorTypeNames::beacon; |
89 | 100 |
90 PingLoader::start(frame, request, initiatorInfo); | 101 // Leak the loader, since it will kill itself as soon as it receives a r
esponse. |
| 102 RefPtrWillBeRawPtr<BeaconLoader> loader = adoptRefWillBeNoop(new BeaconL
oader(frame, request, initiatorInfo, AllowStoredCredentials)); |
| 103 loader->ref(); |
91 return true; | 104 return true; |
92 } | 105 } |
93 }; | 106 }; |
94 | 107 |
95 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, const String& data, int& payloadLength) | 108 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, const String& data, int& payloadLength) |
96 { | 109 { |
97 BeaconData<decltype(data)> beacon(data); | 110 BeaconData<decltype(data)> beacon(data); |
98 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 111 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
99 } | 112 } |
100 | 113 |
101 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, PassRefPtr<DOMArrayBufferView> data, int& payloadLength) | 114 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, PassRefPtr<DOMArrayBufferView> data, int& payloadLength) |
102 { | 115 { |
103 BeaconData<decltype(data)> beacon(data); | 116 BeaconData<decltype(data)> beacon(data); |
104 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 117 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
105 } | 118 } |
106 | 119 |
107 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, PassRefPtrWillBeRawPtr<DOMFormData> data, int& payloadLength) | 120 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, PassRefPtrWillBeRawPtr<DOMFormData> data, int& payloadLength) |
108 { | 121 { |
109 BeaconData<decltype(data)> beacon(data); | 122 BeaconData<decltype(data)> beacon(data); |
110 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 123 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
111 } | 124 } |
112 | 125 |
113 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, Blob* data, int& payloadLength) | 126 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac
onURL, Blob* data, int& payloadLength) |
114 { | 127 { |
115 BeaconData<decltype(data)> beacon(data); | 128 BeaconData<decltype(data)> beacon(data); |
116 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 129 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
117 } | 130 } |
118 | 131 |
| 132 BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const Fe
tchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed) |
| 133 : PingLoader(frame, request, initiatorInfo, credentialsAllowed) |
| 134 , m_beaconOrigin(frame->document()->securityOrigin()) |
| 135 { |
| 136 } |
| 137 |
| 138 void BeaconLoader::willSendRequest(WebURLLoader*, WebURLRequest& passedNewReques
t, const WebURLResponse& passedRedirectResponse) |
| 139 { |
| 140 passedNewRequest.setAllowStoredCredentials(true); |
| 141 ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); |
| 142 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe
sponse()); |
| 143 |
| 144 ASSERT(!newRequest.isNull()); |
| 145 ASSERT(!redirectResponse.isNull()); |
| 146 |
| 147 String errorDescription; |
| 148 StoredCredentials withCredentials = AllowStoredCredentials; |
| 149 ResourceLoaderOptions options; |
| 150 if (!CrossOriginAccessControl::handleRedirect(m_beaconOrigin.get(), newReque
st, redirectResponse, withCredentials, options, errorDescription)) { |
| 151 if (page() && page()->mainFrame()) { |
| 152 if (page()->mainFrame()->isLocalFrame()) { |
| 153 LocalFrame* localFrame = toLocalFrame(page()->mainFrame()); |
| 154 if (localFrame->document()) |
| 155 localFrame->document()->addConsoleMessage(ConsoleMessage::cr
eate(JSMessageSource, ErrorMessageLevel, errorDescription)); |
| 156 } |
| 157 } |
| 158 // Cancel the load and self destruct. |
| 159 dispose(); |
| 160 return; |
| 161 } |
| 162 // FIXME: http://crbug.com/427429 is needed to correctly propagate |
| 163 // updates of Origin: following this successful redirect. |
| 164 } |
| 165 |
119 namespace { | 166 namespace { |
120 | 167 |
121 unsigned long long Beacon::beaconSize(const String& data) | 168 unsigned long long Beacon::beaconSize(const String& data) |
122 { | 169 { |
123 return data.sizeInBytes(); | 170 return data.sizeInBytes(); |
124 } | 171 } |
125 | 172 |
126 bool Beacon::serialize(const String& data, ResourceRequest& request, int, int&) | 173 bool Beacon::serialize(const String& data, ResourceRequest& request, int, int&) |
127 { | 174 { |
128 RefPtr<FormData> entityBody = FormData::create(data.utf8()); | 175 RefPtr<FormData> entityBody = FormData::create(data.utf8()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 request.setHTTPBody(entityBody.release()); | 237 request.setHTTPBody(entityBody.release()); |
191 request.setHTTPContentType(contentType); | 238 request.setHTTPContentType(contentType); |
192 | 239 |
193 payloadLength = entitySize; | 240 payloadLength = entitySize; |
194 return true; | 241 return true; |
195 } | 242 } |
196 | 243 |
197 } // namespace | 244 } // namespace |
198 | 245 |
199 } // namespace blink | 246 } // namespace blink |
OLD | NEW |