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 "core/loader/BeaconLoader.h" | 5 #include "core/loader/BeaconLoader.h" |
6 | 6 |
7 #include "core/dom/DOMArrayBufferView.h" | 7 #include "core/dom/DOMArrayBufferView.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/fetch/CrossOriginAccessControl.h" | 9 #include "core/fetch/CrossOriginAccessControl.h" |
10 #include "core/fetch/FetchContext.h" | 10 #include "core/fetch/FetchContext.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "wtf/Functional.h" | 24 #include "wtf/Functional.h" |
25 | 25 |
26 namespace blink { | 26 namespace blink { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 class Beacon { | 30 class Beacon { |
31 public: | 31 public: |
32 virtual bool serialize(ResourceRequest&, int, int&) const = 0; | 32 virtual bool serialize(ResourceRequest&, int, int&) const = 0; |
33 virtual unsigned long long size() const = 0; | 33 virtual unsigned long long size() const = 0; |
34 | |
35 protected: | |
36 static unsigned long long beaconSize(const String&); | |
37 static unsigned long long beaconSize(Blob*); | |
38 static unsigned long long beaconSize(DOMArrayBufferView*); | |
39 static unsigned long long beaconSize(FormData*); | |
40 | |
41 static bool serialize(const String&, ResourceRequest&, int, int&); | |
42 static bool serialize(Blob*, ResourceRequest&, int, int&); | |
43 static bool serialize(DOMArrayBufferView*, ResourceRequest&, int, int&); | |
44 static bool serialize(FormData*, ResourceRequest&, int, int&); | |
45 }; | 34 }; |
46 | 35 |
47 template<typename Payload> | 36 class BeaconString final : public Beacon { |
48 class BeaconData final : public Beacon { | |
49 public: | 37 public: |
50 BeaconData(const Payload& data) | 38 BeaconString(const String& data) |
51 : m_data(data) | 39 : m_data(data) |
52 { | 40 { |
53 } | 41 } |
54 | 42 |
55 bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override | 43 private: |
sof
2016/04/27 14:05:07
let's just have "private:" limit visibility for th
hiroshige
2016/04/28 05:52:10
Done.
| |
44 unsigned long long size() const override | |
56 { | 45 { |
57 return Beacon::serialize(m_data, request, allowance, payloadLength); | 46 return m_data.sizeInBytes(); |
58 } | 47 } |
59 | 48 |
60 unsigned long long size() const override | 49 bool serialize(ResourceRequest& request, int, int&) const override |
61 { | 50 { |
62 return beaconSize(m_data); | 51 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data.utf8 ()); |
52 request.setHTTPBody(entityBody); | |
53 request.setHTTPContentType("text/plain;charset=UTF-8"); | |
54 return true; | |
55 } | |
56 | |
57 const String m_data; | |
58 }; | |
59 | |
60 class BeaconBlob final : public Beacon { | |
61 public: | |
62 BeaconBlob(Blob* data) | |
63 : m_data(data) | |
64 { | |
63 } | 65 } |
64 | 66 |
65 private: | 67 private: |
66 const typename WTF::ParamStorageTraits<Payload>::StorageType m_data; | 68 unsigned long long size() const override |
69 { | |
70 return m_data->size(); | |
71 } | |
72 | |
73 bool serialize(ResourceRequest& request, int, int&) const override | |
74 { | |
75 ASSERT(m_data); | |
76 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(); | |
77 if (m_data->hasBackingFile()) | |
78 entityBody->appendFile(toFile(m_data)->path()); | |
79 else | |
80 entityBody->appendBlob(m_data->uuid(), m_data->blobDataHandle()); | |
81 | |
82 request.setHTTPBody(entityBody.release()); | |
83 | |
84 const String& blobType = m_data->type(); | |
85 if (!blobType.isEmpty() && isValidContentType(blobType)) | |
86 request.setHTTPContentType(AtomicString(blobType)); | |
87 | |
88 return true; | |
89 } | |
90 | |
91 const Persistent<Blob> m_data; | |
92 }; | |
93 | |
94 class BeaconDOMArrayBufferView final : public Beacon { | |
95 public: | |
96 BeaconDOMArrayBufferView(DOMArrayBufferView* data) | |
97 : m_data(data) | |
98 { | |
99 } | |
100 | |
101 private: | |
102 unsigned long long size() const override | |
103 { | |
104 return m_data->byteLength(); | |
105 } | |
106 | |
107 bool serialize(ResourceRequest& request, int, int&) const override | |
108 { | |
109 ASSERT(m_data); | |
110 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data->bas eAddress(), m_data->byteLength()); | |
111 request.setHTTPBody(entityBody.release()); | |
112 | |
113 // FIXME: a reasonable choice, but not in the spec; should it give a def ault? | |
114 AtomicString contentType = AtomicString("application/octet-stream"); | |
115 request.setHTTPContentType(contentType); | |
116 | |
117 return true; | |
118 } | |
119 | |
120 const Persistent<DOMArrayBufferView> m_data; | |
121 }; | |
122 | |
123 class BeaconFormData final : public Beacon { | |
124 public: | |
125 BeaconFormData(FormData* data) | |
126 : m_data(data) | |
127 { | |
128 } | |
129 | |
130 private: | |
131 unsigned long long size() const override | |
132 { | |
133 // FormData's size cannot be determined until serialized. | |
134 return 0; | |
135 } | |
136 | |
137 bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override | |
138 { | |
139 ASSERT(m_data); | |
140 RefPtr<EncodedFormData> entityBody = m_data->encodeMultiPartFormData(); | |
141 unsigned long long entitySize = entityBody->sizeInBytes(); | |
142 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entity Size) | |
143 return false; | |
144 | |
145 AtomicString contentType = AtomicString("multipart/form-data; boundary=" ) + entityBody->boundary().data(); | |
146 request.setHTTPBody(entityBody.release()); | |
147 request.setHTTPContentType(contentType); | |
148 | |
149 payloadLength = entitySize; | |
150 return true; | |
151 } | |
152 | |
153 const Persistent<FormData> m_data; | |
67 }; | 154 }; |
68 | 155 |
69 } // namespace | 156 } // namespace |
70 | 157 |
71 class BeaconLoader::Sender { | 158 class BeaconLoader::Sender { |
72 public: | 159 public: |
73 static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, co nst Beacon& beacon, int& payloadLength) | 160 static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, co nst Beacon& beacon, int& payloadLength) |
74 { | 161 { |
75 if (!frame->document()) | 162 if (!frame->document()) |
76 return false; | 163 return false; |
(...skipping 22 matching lines...) Expand all Loading... | |
99 | 186 |
100 // The loader keeps itself alive until it receives a response and dispos es itself. | 187 // The loader keeps itself alive until it receives a response and dispos es itself. |
101 BeaconLoader* loader = new BeaconLoader(frame, request, initiatorInfo, A llowStoredCredentials); | 188 BeaconLoader* loader = new BeaconLoader(frame, request, initiatorInfo, A llowStoredCredentials); |
102 ASSERT_UNUSED(loader, loader); | 189 ASSERT_UNUSED(loader, loader); |
103 return true; | 190 return true; |
104 } | 191 } |
105 }; | 192 }; |
106 | 193 |
107 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, const String& data, int& payloadLength) | 194 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, const String& data, int& payloadLength) |
108 { | 195 { |
109 BeaconData<String> beacon(data); | 196 BeaconString beacon(data); |
110 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 197 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
111 } | 198 } |
112 | 199 |
113 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, DOMArrayBufferView* data, int& payloadLength) | 200 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, DOMArrayBufferView* data, int& payloadLength) |
114 { | 201 { |
115 BeaconData<decltype(data)> beacon(data); | 202 BeaconDOMArrayBufferView beacon(data); |
116 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 203 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
117 } | 204 } |
118 | 205 |
119 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, FormData* data, int& payloadLength) | 206 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, FormData* data, int& payloadLength) |
120 { | 207 { |
121 BeaconData<decltype(data)> beacon(data); | 208 BeaconFormData beacon(data); |
122 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 209 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
123 } | 210 } |
124 | 211 |
125 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, Blob* data, int& payloadLength) | 212 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, Blob* data, int& payloadLength) |
126 { | 213 { |
127 BeaconData<decltype(data)> beacon(data); | 214 BeaconBlob beacon(data); |
128 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); | 215 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); |
129 } | 216 } |
130 | 217 |
131 BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const Fe tchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed) | 218 BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const Fe tchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed) |
132 : PingLoader(frame, request, initiatorInfo, credentialsAllowed) | 219 : PingLoader(frame, request, initiatorInfo, credentialsAllowed) |
133 , m_beaconOrigin(frame->document()->getSecurityOrigin()) | 220 , m_beaconOrigin(frame->document()->getSecurityOrigin()) |
134 { | 221 { |
135 } | 222 } |
136 | 223 |
137 void BeaconLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewReq uest, const WebURLResponse& passedRedirectResponse) | 224 void BeaconLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewReq uest, const WebURLResponse& passedRedirectResponse) |
(...skipping 14 matching lines...) Expand all Loading... | |
152 localFrame->document()->addConsoleMessage(ConsoleMessage::create (JSMessageSource, ErrorMessageLevel, errorDescription)); | 239 localFrame->document()->addConsoleMessage(ConsoleMessage::create (JSMessageSource, ErrorMessageLevel, errorDescription)); |
153 } | 240 } |
154 // Cancel the load and self destruct. | 241 // Cancel the load and self destruct. |
155 dispose(); | 242 dispose(); |
156 return; | 243 return; |
157 } | 244 } |
158 // FIXME: http://crbug.com/427429 is needed to correctly propagate | 245 // FIXME: http://crbug.com/427429 is needed to correctly propagate |
159 // updates of Origin: following this successful redirect. | 246 // updates of Origin: following this successful redirect. |
160 } | 247 } |
161 | 248 |
162 namespace { | |
163 | |
164 unsigned long long Beacon::beaconSize(const String& data) | |
165 { | |
166 return data.sizeInBytes(); | |
167 } | |
168 | |
169 bool Beacon::serialize(const String& data, ResourceRequest& request, int, int&) | |
170 { | |
171 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(data.utf8()); | |
172 request.setHTTPBody(entityBody); | |
173 request.setHTTPContentType("text/plain;charset=UTF-8"); | |
174 return true; | |
175 } | |
176 | |
177 unsigned long long Beacon::beaconSize(Blob* data) | |
178 { | |
179 return data->size(); | |
180 } | |
181 | |
182 bool Beacon::serialize(Blob* data, ResourceRequest& request, int, int&) | |
183 { | |
184 ASSERT(data); | |
185 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(); | |
186 if (data->hasBackingFile()) | |
187 entityBody->appendFile(toFile(data)->path()); | |
188 else | |
189 entityBody->appendBlob(data->uuid(), data->blobDataHandle()); | |
190 | |
191 request.setHTTPBody(entityBody.release()); | |
192 | |
193 const String& blobType = data->type(); | |
194 if (!blobType.isEmpty() && isValidContentType(blobType)) | |
195 request.setHTTPContentType(AtomicString(blobType)); | |
196 | |
197 return true; | |
198 } | |
199 | |
200 unsigned long long Beacon::beaconSize(DOMArrayBufferView* data) | |
201 { | |
202 return data->byteLength(); | |
203 } | |
204 | |
205 bool Beacon::serialize(DOMArrayBufferView* data, ResourceRequest& request, int, int&) | |
206 { | |
207 ASSERT(data); | |
208 RefPtr<EncodedFormData> entityBody = EncodedFormData::create(data->baseAddre ss(), data->byteLength()); | |
209 request.setHTTPBody(entityBody.release()); | |
210 | |
211 // FIXME: a reasonable choice, but not in the spec; should it give a default ? | |
212 AtomicString contentType = AtomicString("application/octet-stream"); | |
213 request.setHTTPContentType(contentType); | |
214 | |
215 return true; | |
216 } | |
217 | |
218 unsigned long long Beacon::beaconSize(FormData*) | |
219 { | |
220 // FormData's size cannot be determined until serialized. | |
221 return 0; | |
222 } | |
223 | |
224 bool Beacon::serialize(FormData* data, ResourceRequest& request, int allowance, int& payloadLength) | |
225 { | |
226 ASSERT(data); | |
227 RefPtr<EncodedFormData> entityBody = data->encodeMultiPartFormData(); | |
228 unsigned long long entitySize = entityBody->sizeInBytes(); | |
229 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize ) | |
230 return false; | |
231 | |
232 AtomicString contentType = AtomicString("multipart/form-data; boundary=") + entityBody->boundary().data(); | |
233 request.setHTTPBody(entityBody.release()); | |
234 request.setHTTPContentType(contentType); | |
235 | |
236 payloadLength = entitySize; | |
237 return true; | |
238 } | |
239 | |
240 } // namespace | |
241 | |
242 } // namespace blink | 249 } // namespace blink |
OLD | NEW |