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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/FormDataBytesConsumer.cpp

Issue 2342023002: Introduce FormDataBytesConsumer (Closed)
Patch Set: fix Created 4 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/fetch/FormDataBytesConsumer.h"
6
7 #include "core/dom/DOMArrayBuffer.h"
8 #include "core/dom/DOMArrayBufferView.h"
9 #include "modules/fetch/BlobBytesConsumer.h"
10 #include "platform/blob/BlobData.h"
11 #include "platform/network/EncodedFormData.h"
12 #include "wtf/Vector.h"
13 #include "wtf/text/TextCodec.h"
14 #include "wtf/text/TextEncoding.h"
15 #include "wtf/text/WTFString.h"
16
17 namespace blink {
18
19 namespace {
20
21 bool isSimple(const EncodedFormData* formData)
22 {
23 for (const auto& element : formData->elements()) {
24 if (element.m_type != FormDataElement::data)
25 return false;
26 }
27 return true;
28 }
29
30 class SimpleFormDataBytesConsumer : public BytesConsumer {
31 public:
32 explicit SimpleFormDataBytesConsumer(PassRefPtr<EncodedFormData> formData)
33 : m_formData(formData)
34 {
35 }
36
37 // BytesConsumer implementation
38 Result beginRead(const char** buffer, size_t* available) override
39 {
40 *buffer = nullptr;
41 *available = 0;
42 if (m_formData) {
43 m_formData->flatten(m_flattenFormData);
44 m_formData = nullptr;
45 DCHECK_EQ(m_flattenFormDataOffset, 0u);
46 }
47 if (m_flattenFormDataOffset == m_flattenFormData.size())
48 return Result::Done;
49 *buffer = m_flattenFormData.data() + m_flattenFormDataOffset;
50 *available = m_flattenFormData.size() - m_flattenFormDataOffset;
51 return Result::Ok;
52 }
53 Result endRead(size_t readSize) override
54 {
55 DCHECK(!m_formData);
56 DCHECK_LE(m_flattenFormDataOffset + readSize, m_flattenFormData.size());
57 m_flattenFormDataOffset += readSize;
58 if (m_flattenFormDataOffset == m_flattenFormData.size()) {
59 m_state = PublicState::Closed;
60 return Result::Done;
61 }
62 return Result::Ok;
63 }
64 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy) over ride
65 {
66 if (!m_formData)
67 return nullptr;
68
69 Vector<char> data;
70 m_formData->flatten(data);
71 m_formData = nullptr;
72 std::unique_ptr<BlobData> blobData = BlobData::create();
73 blobData->appendBytes(data.data(), data.size());
74 auto length = blobData->length();
75 m_state = PublicState::Closed;
76 return BlobDataHandle::create(std::move(blobData), length);
77 }
78 PassRefPtr<EncodedFormData> drainAsFormData() override
79 {
80 if (!m_formData)
81 return nullptr;
82
83 m_state = PublicState::Closed;
84 return m_formData.release();
85 }
86 void setClient(BytesConsumer::Client* client) override
87 {
88 DCHECK(client);
89 }
90 void clearClient() override
91 {
92 }
93 void cancel() override
94 {
95 m_state = PublicState::Closed;
96 m_formData = nullptr;
97 m_flattenFormData.clear();
98 m_flattenFormDataOffset = 0;
99 }
100 PublicState getPublicState() const override
101 {
102 return m_state;
103 }
104 Error getError() const override
105 {
106 NOTREACHED();
107 return Error();
108 }
109 String debugName() const override
110 {
111 return "SimpleFormDataBytesConsumer";
112 }
113
114 private:
115 // either one of |m_formData| and |m_flattenFormData| is usable at a time.
116 RefPtr<EncodedFormData> m_formData;
117 Vector<char> m_flattenFormData;
118 size_t m_flattenFormDataOffset = 0;
119 PublicState m_state = PublicState::ReadableOrWaiting;
120 };
121
122 class ComplexFormDataBytesConsumer final : public BytesConsumer {
123 public:
124 ComplexFormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr< EncodedFormData> formData, BytesConsumer* consumer)
125 : m_formData(formData)
126 {
127 if (consumer) {
128 // For testing.
129 m_blobBytesConsumer = consumer;
130 return;
131 }
132
133 std::unique_ptr<BlobData> blobData = BlobData::create();
134 for (const auto& element : m_formData->elements()) {
135 switch (element.m_type) {
136 case FormDataElement::data:
137 blobData->appendBytes(element.m_data.data(), element.m_data.size ());
138 break;
139 case FormDataElement::encodedFile:
140 blobData->appendFile(element.m_filename, element.m_fileStart, el ement.m_fileLength, element.m_expectedFileModificationTime);
141 break;
142 case FormDataElement::encodedBlob:
143 if (element.m_optionalBlobDataHandle)
144 blobData->appendBlob(element.m_optionalBlobDataHandle, 0, el ement.m_optionalBlobDataHandle->size());
145 break;
146 case FormDataElement::encodedFileSystemURL:
147 blobData->appendFileSystemURL(element.m_fileSystemURL, element.m _fileStart, element.m_fileLength, element.m_expectedFileModificationTime);
148 break;
149 }
150 }
151 // Here we handle m_formData->boundary() as a C-style string. See
152 // FormDataEncoder::generateUniqueBoundaryString.
153 blobData->setContentType(AtomicString("multipart/form-data; boundary=") + m_formData->boundary().data());
154 auto size = blobData->length();
155 m_blobBytesConsumer = new BlobBytesConsumer(executionContext, BlobDataHa ndle::create(std::move(blobData), size));
156 }
157
158 // BytesConsumer implementation
159 Result beginRead(const char** buffer, size_t* available) override
160 {
161 m_formData = nullptr;
162 // Delegate the operation to the underlying consumer. This relies on
163 // the fact that we appropriately notify the draining information to
164 // the underlying consumer.
165 return m_blobBytesConsumer->beginRead(buffer, available);
166 }
167 Result endRead(size_t readSize) override
168 {
169 return m_blobBytesConsumer->endRead(readSize);
170 }
171 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy) over ride
172 {
173 RefPtr<BlobDataHandle> handle = m_blobBytesConsumer->drainAsBlobDataHand le(policy);
174 if (handle)
175 m_formData = nullptr;
176 return handle.release();
177 }
178 PassRefPtr<EncodedFormData> drainAsFormData() override
179 {
180 if (!m_formData)
181 return nullptr;
182 m_blobBytesConsumer->cancel();
183 return m_formData.release();
184 }
185 void setClient(BytesConsumer::Client* client) override
186 {
187 m_blobBytesConsumer->setClient(client);
188 }
189 void clearClient() override
190 {
191 m_blobBytesConsumer->clearClient();
192 }
193 void cancel() override
194 {
195 m_formData = nullptr;
196 m_blobBytesConsumer->cancel();
197 }
198 PublicState getPublicState() const override
199 {
200 return m_blobBytesConsumer->getPublicState();
201 }
202 Error getError() const override
203 {
204 return m_blobBytesConsumer->getError();
205 }
206 String debugName() const override
207 {
208 return "ComplexFormDataBytesConsumer";
209 }
210
211 DEFINE_INLINE_TRACE()
212 {
213 visitor->trace(m_blobBytesConsumer);
214 BytesConsumer::trace(visitor);
215 }
216
217 private:
218 RefPtr<EncodedFormData> m_formData;
219 Member<BytesConsumer> m_blobBytesConsumer;
220 };
221
222 } // namespace
223
224 FormDataBytesConsumer::FormDataBytesConsumer(const String& string)
225 : m_impl(new SimpleFormDataBytesConsumer(EncodedFormData::create(UTF8Encodin g().encode(string, WTF::EntitiesForUnencodables))))
226 {
227 }
228
229 FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBuffer* buffer)
230 : FormDataBytesConsumer(buffer->data(), buffer->byteLength())
231 {
232 }
233
234 FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBufferView* view)
235 : FormDataBytesConsumer(view->baseAddress(), view->byteLength())
236 {
237 }
238
239 FormDataBytesConsumer::FormDataBytesConsumer(const void* data, size_t size)
240 : m_impl(new SimpleFormDataBytesConsumer(EncodedFormData::create(data, size) ))
241 {
242 }
243
244 FormDataBytesConsumer::FormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr<EncodedFormData> formData)
245 : FormDataBytesConsumer(executionContext, formData, nullptr)
246 {
247 }
248
249 FormDataBytesConsumer::FormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr<EncodedFormData> formData, BytesConsumer* consumer)
250 : m_impl(isSimple(formData.get()) ?
251 static_cast<BytesConsumer*>(new SimpleFormDataBytesConsumer(formData)) :
252 static_cast<BytesConsumer*>(new ComplexFormDataBytesConsumer(executionCo ntext, formData, consumer)))
253 {
254 }
255
256 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698