Chromium Code Reviews| 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 |