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

Side by Side Diff: Source/core/loader/BeaconLoader.cpp

Issue 864163004: Reduce code duplication across sendBeacon() overloads. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/loader/BeaconLoader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/FetchInitiatorTypeNames.h" 8 #include "core/FetchInitiatorTypeNames.h"
9 #include "core/dom/DOMArrayBufferView.h" 9 #include "core/dom/DOMArrayBufferView.h"
10 #include "core/fetch/FetchContext.h" 10 #include "core/fetch/FetchContext.h"
11 #include "core/fileapi/File.h" 11 #include "core/fileapi/File.h"
12 #include "core/frame/LocalFrame.h" 12 #include "core/frame/LocalFrame.h"
13 #include "core/html/DOMFormData.h" 13 #include "core/html/DOMFormData.h"
14 #include "platform/network/FormData.h" 14 #include "platform/network/FormData.h"
15 #include "platform/network/ParsedContentType.h" 15 #include "platform/network/ParsedContentType.h"
16 #include "platform/network/ResourceRequest.h" 16 #include "platform/network/ResourceRequest.h"
17 #include "public/platform/WebURLRequest.h" 17 #include "public/platform/WebURLRequest.h"
18 #include "wtf/Functional.h"
18 19
19 namespace blink { 20 namespace blink {
20 21
21 void BeaconLoader::prepareRequest(LocalFrame* frame, ResourceRequest& request) 22 namespace {
22 {
23 request.setRequestContext(WebURLRequest::RequestContextBeacon);
24 request.setHTTPMethod("POST");
25 request.setHTTPHeaderField("Cache-Control", "max-age=0");
26 request.setAllowStoredCredentials(true);
27 frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document() , request, FetchSubresource);
28 frame->loader().fetchContext().setFirstPartyForCookies(request);
29 }
30 23
31 void BeaconLoader::issueRequest(LocalFrame* frame, ResourceRequest& request) 24 class Beacon {
32 { 25 public:
33 FetchInitiatorInfo initiatorInfo; 26 virtual bool serialize(ResourceRequest&, int, int&) const = 0;
34 initiatorInfo.name = FetchInitiatorTypeNames::beacon; 27 virtual unsigned long long size() const = 0;
35 28
36 PingLoader::start(frame, request, initiatorInfo); 29 protected:
37 } 30 static unsigned long long beaconSize(const String&);
31 static unsigned long long beaconSize(Blob*);
32 static unsigned long long beaconSize(PassRefPtr<DOMArrayBufferView>);
33 static unsigned long long beaconSize(PassRefPtrWillBeRawPtr<DOMFormData>);
34
35 static bool serialize(const String&, ResourceRequest&, int, int&);
36 static bool serialize(Blob*, ResourceRequest&, int, int&);
37 static bool serialize(PassRefPtr<DOMArrayBufferView>, ResourceRequest&, int, int&);
38 static bool serialize(PassRefPtrWillBeRawPtr<DOMFormData>, ResourceRequest&, int, int&);
39 };
40
41 template<typename Payload>
42 class BeaconData final : public Beacon {
43 public:
44 BeaconData(const Payload& data)
45 : m_data(data)
46 {
47 }
48
49 bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override
50 {
51 return Beacon::serialize(m_data, request, allowance, payloadLength);
52 }
53
54 unsigned long long size() const override
55 {
56 return beaconSize(m_data);
57 }
58
59 private:
60 const typename WTF::ParamStorageTraits<Payload>::StorageType m_data;
61 };
62
63 } // namespace
64
65 class BeaconLoader::Sender {
66 public:
67 static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, co nst Beacon& beacon, int& payloadLength)
68 {
69 unsigned long long entitySize = beacon.size();
70 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entity Size)
71 return false;
72
73 ResourceRequest request(beaconURL);
74 request.setRequestContext(WebURLRequest::RequestContextBeacon);
75 request.setHTTPMethod("POST");
76 request.setHTTPHeaderField("Cache-Control", "max-age=0");
77 request.setAllowStoredCredentials(true);
78 frame->loader().fetchContext().addAdditionalRequestHeaders(frame->docume nt(), request, FetchSubresource);
79 frame->loader().fetchContext().setFirstPartyForCookies(request);
80
81 payloadLength = entitySize;
82 if (!beacon.serialize(request, allowance, payloadLength))
83 return false;
84
85 FetchInitiatorInfo initiatorInfo;
86 initiatorInfo.name = FetchInitiatorTypeNames::beacon;
87
88 PingLoader::start(frame, request, initiatorInfo);
89 return true;
90 }
91 };
38 92
39 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, const String& data, int& payloadLength) 93 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, const String& data, int& payloadLength)
40 { 94 {
41 ResourceRequest request(beaconURL); 95 BeaconData<decltype(data)> beacon(data);
42 prepareRequest(frame, request); 96 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength);
43
44 RefPtr<FormData> entityBody = FormData::create(data.utf8());
45 unsigned long long entitySize = entityBody->sizeInBytes();
46 if (allowance > 0 && static_cast<unsigned>(allowance) < entitySize)
47 return false;
48
49 request.setHTTPBody(entityBody);
50 request.setHTTPContentType("text/plain;charset=UTF-8");
51
52 issueRequest(frame, request);
53 payloadLength = entitySize;
54 return true;
55 } 97 }
56 98
57 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, PassRefPtr<DOMArrayBufferView> data, int& payloadLength) 99 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, PassRefPtr<DOMArrayBufferView> data, int& payloadLength)
58 { 100 {
59 ASSERT(data); 101 BeaconData<decltype(data)> beacon(data);
60 unsigned long long entitySize = data->byteLength(); 102 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength);
61 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize ) 103 }
62 return false;
63 104
64 ResourceRequest request(beaconURL); 105 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, PassRefPtrWillBeRawPtr<DOMFormData> data, int& payloadLength)
65 prepareRequest(frame, request); 106 {
66 107 BeaconData<decltype(data)> beacon(data);
67 RefPtr<FormData> entityBody = FormData::create(data->baseAddress(), data->by teLength()); 108 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength);
68 request.setHTTPBody(entityBody.release());
69
70 // FIXME: a reasonable choice, but not in the spec; should it give a default ?
71 AtomicString contentType = AtomicString("application/octet-stream");
72 request.setHTTPContentType(contentType);
73
74 issueRequest(frame, request);
75 payloadLength = entitySize;
76 return true;
77 } 109 }
78 110
79 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, Blob* data, int& payloadLength) 111 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, Blob* data, int& payloadLength)
80 { 112 {
113 BeaconData<decltype(data)> beacon(data);
114 return Sender::send(frame, allowance, beaconURL, beacon, payloadLength);
115 }
116
117 namespace {
118
119 unsigned long long Beacon::beaconSize(const String& data)
120 {
121 return data.sizeInBytes();
122 }
123
124 bool Beacon::serialize(const String& data, ResourceRequest& request, int, int&)
125 {
126 RefPtr<FormData> entityBody = FormData::create(data.utf8());
127 request.setHTTPBody(entityBody);
128 request.setHTTPContentType("text/plain;charset=UTF-8");
129 return true;
130 }
131
132 unsigned long long Beacon::beaconSize(Blob* data)
133 {
134 return data->size();
135 }
136
137 bool Beacon::serialize(Blob* data, ResourceRequest& request, int, int&)
138 {
81 ASSERT(data); 139 ASSERT(data);
82 unsigned long long entitySize = data->size();
83 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize )
84 return false;
85
86 ResourceRequest request(beaconURL);
87 prepareRequest(frame, request);
88
89 RefPtr<FormData> entityBody = FormData::create(); 140 RefPtr<FormData> entityBody = FormData::create();
90 if (data->hasBackingFile()) 141 if (data->hasBackingFile())
91 entityBody->appendFile(toFile(data)->path()); 142 entityBody->appendFile(toFile(data)->path());
92 else 143 else
93 entityBody->appendBlob(data->uuid(), data->blobDataHandle()); 144 entityBody->appendBlob(data->uuid(), data->blobDataHandle());
94 145
95 request.setHTTPBody(entityBody.release()); 146 request.setHTTPBody(entityBody.release());
96 147
97 AtomicString contentType; 148 AtomicString contentType;
98 const String& blobType = data->type(); 149 const String& blobType = data->type();
99 if (!blobType.isEmpty() && isValidContentType(blobType)) 150 if (!blobType.isEmpty() && isValidContentType(blobType))
100 request.setHTTPContentType(AtomicString(contentType)); 151 request.setHTTPContentType(AtomicString(contentType));
101 152
102 issueRequest(frame, request);
103 payloadLength = entitySize;
104 return true; 153 return true;
105 } 154 }
106 155
107 bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beac onURL, PassRefPtrWillBeRawPtr<DOMFormData> data, int& payloadLength) 156 unsigned long long Beacon::beaconSize(PassRefPtr<DOMArrayBufferView> data)
157 {
158 return data->byteLength();
159 }
160
161 bool Beacon::serialize(PassRefPtr<DOMArrayBufferView> data, ResourceRequest& req uest, int, int&)
108 { 162 {
109 ASSERT(data); 163 ASSERT(data);
110 ResourceRequest request(beaconURL); 164 RefPtr<FormData> entityBody = FormData::create(data->baseAddress(), data->by teLength());
111 prepareRequest(frame, request); 165 request.setHTTPBody(entityBody.release());
112 166
167 // FIXME: a reasonable choice, but not in the spec; should it give a default ?
168 AtomicString contentType = AtomicString("application/octet-stream");
169 request.setHTTPContentType(contentType);
170
171 return true;
172 }
173
174 unsigned long long Beacon::beaconSize(PassRefPtrWillBeRawPtr<DOMFormData> data)
175 {
176 // DOMFormData's size cannot be determined until serialized.
177 return 0;
178 }
179
180 bool Beacon::serialize(PassRefPtrWillBeRawPtr<DOMFormData> data, ResourceRequest & request, int allowance, int& payloadLength)
181 {
182 ASSERT(data);
113 RefPtr<FormData> entityBody = data->createMultiPartFormData(); 183 RefPtr<FormData> entityBody = data->createMultiPartFormData();
114
115 unsigned long long entitySize = entityBody->sizeInBytes(); 184 unsigned long long entitySize = entityBody->sizeInBytes();
116 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize ) 185 if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize )
117 return false; 186 return false;
118 187
119 AtomicString contentType = AtomicString("multipart/form-data; boundary=", At omicString::ConstructFromLiteral) + entityBody->boundary().data(); 188 AtomicString contentType = AtomicString("multipart/form-data; boundary=", At omicString::ConstructFromLiteral) + entityBody->boundary().data();
120 request.setHTTPBody(entityBody.release()); 189 request.setHTTPBody(entityBody.release());
121 request.setHTTPContentType(contentType); 190 request.setHTTPContentType(contentType);
122 191
123 issueRequest(frame, request);
124 payloadLength = entitySize; 192 payloadLength = entitySize;
125 return true; 193 return true;
126 } 194 }
127 195
196 } // namespace
197
128 } // namespace blink 198 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/loader/BeaconLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698