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

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)
hiroshige 2016/09/15 09:47:33 Memo: this is dup of isSimple() in FetchFormDataCo
yhirano 2016/09/16 03:10:32 Acknowledged.
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 return Result::Ok;
59 }
60 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy) over ride
61 {
62 if (!m_formData)
63 return nullptr;
64
65 Vector<char> data;
66 m_formData->flatten(data);
67 m_formData = nullptr;
68 std::unique_ptr<BlobData> blobData = BlobData::create();
69 blobData->appendBytes(data.data(), data.size());
70 auto length = blobData->length();
71 return BlobDataHandle::create(std::move(blobData), length);
72 }
73 PassRefPtr<EncodedFormData> drainAsFormData() override
74 {
75 return m_formData.release();
76 }
77 void setClient(BytesConsumer::Client* client) override
78 {
79 DCHECK(client);
80 }
81 void clearClient() override
82 {
83 }
84 void cancel() override
85 {
86 m_state = PublicState::Closed;
87 m_formData = nullptr;
88 m_flattenFormData.clear();
89 m_flattenFormDataOffset = 0;
90 }
91 PublicState getPublicState() const override
92 {
93 return m_state;
94 }
95 Error getError() const override
96 {
97 NOTREACHED();
98 return Error();
99 }
100 String debugName() const override
101 {
102 return "SimpleFormDataBytesConsumer";
103 }
104
105 private:
106 // either one of |m_formData| and |m_flattenFormData| is usable at a time.
107 RefPtr<EncodedFormData> m_formData;
108 Vector<char> m_flattenFormData;
109 size_t m_flattenFormDataOffset = 0;
110 PublicState m_state = PublicState::ReadableOrWaiting;
111 };
112
113 class ComplexFormDataBytesConsumer final : public BytesConsumer {
114 public:
115 ComplexFormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr< EncodedFormData> formData, BytesConsumer* consumer)
116 : m_formData(formData)
117 {
118 if (consumer) {
119 // For testing.
120 m_blobBytesConsumer = consumer;
121 return;
122 }
123
124 std::unique_ptr<BlobData> blobData = BlobData::create();
125 for (const auto& element : m_formData->elements()) {
126 switch (element.m_type) {
127 case FormDataElement::data:
128 blobData->appendBytes(element.m_data.data(), element.m_data.size ());
129 break;
130 case FormDataElement::encodedFile:
131 blobData->appendFile(element.m_filename, element.m_fileStart, el ement.m_fileLength, element.m_expectedFileModificationTime);
132 break;
133 case FormDataElement::encodedBlob:
134 if (element.m_optionalBlobDataHandle)
135 blobData->appendBlob(element.m_optionalBlobDataHandle, 0, el ement.m_optionalBlobDataHandle->size());
136 break;
137 case FormDataElement::encodedFileSystemURL:
138 blobData->appendFileSystemURL(element.m_fileSystemURL, element.m _fileStart, element.m_fileLength, element.m_expectedFileModificationTime);
139 break;
140 }
141 }
142 // Here we handle m_formData->boundary() as a C-style string. See
143 // FormDataEncoder::generateUniqueBoundaryString.
144 blobData->setContentType(AtomicString("multipart/form-data; boundary=") + m_formData->boundary().data());
145 auto size = blobData->length();
146 m_blobBytesConsumer = new BlobBytesConsumer(executionContext, BlobDataHa ndle::create(std::move(blobData), size));
147 }
148
149 // BytesConsumer implementation
150 Result beginRead(const char** buffer, size_t* available) override
151 {
152 m_formData = nullptr;
153 return m_blobBytesConsumer->beginRead(buffer, available);
hiroshige 2016/09/15 09:47:33 IIUC this code returns Done after drainAsFormData(
yhirano 2016/09/16 03:10:32 Done.
154 }
155 Result endRead(size_t readSize) override
156 {
157 return m_blobBytesConsumer->endRead(readSize);
158 }
159 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy) over ride
160 {
161 RefPtr<BlobDataHandle> handle = m_blobBytesConsumer->drainAsBlobDataHand le(policy);
162 if (handle)
163 m_formData = nullptr;
164 return handle.release();
165 }
166 PassRefPtr<EncodedFormData> drainAsFormData() override
167 {
168 if (!m_formData)
169 return nullptr;
170 m_blobBytesConsumer->cancel();
171 return m_formData.release();
172 }
173 void setClient(BytesConsumer::Client* client) override
174 {
175 m_blobBytesConsumer->setClient(client);
176 }
177 void clearClient() override
178 {
179 m_blobBytesConsumer->clearClient();
180 }
181 void cancel() override
182 {
183 m_formData = nullptr;
184 m_blobBytesConsumer->cancel();
185 }
186 PublicState getPublicState() const override
187 {
188 return m_blobBytesConsumer->getPublicState();
189 }
190 Error getError() const override
191 {
192 return m_blobBytesConsumer->getError();
193 }
194 String debugName() const override
195 {
196 return "ComplexFormDataBytesConsumer";
197 }
198
199 DEFINE_INLINE_TRACE()
200 {
201 visitor->trace(m_blobBytesConsumer);
202 BytesConsumer::trace(visitor);
203 }
204
205 private:
206 RefPtr<EncodedFormData> m_formData;
207 Member<BytesConsumer> m_blobBytesConsumer;
208 };
209
210 } // namespace
211
212 FormDataBytesConsumer::FormDataBytesConsumer(const String& string)
213 : m_impl(new SimpleFormDataBytesConsumer(EncodedFormData::create(UTF8Encodin g().encode(string, WTF::EntitiesForUnencodables))))
214 {
215 }
216
217 FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBuffer* buffer)
218 : m_impl(new SimpleFormDataBytesConsumer(EncodedFormData::create(buffer->dat a(), buffer->byteLength())))
219 {
220 }
221
222 FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBufferView* view)
223 : m_impl(new SimpleFormDataBytesConsumer(EncodedFormData::create(view->baseA ddress(), view->byteLength())))
224 {
225 }
226
227 FormDataBytesConsumer::FormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr<EncodedFormData> formData)
228 : FormDataBytesConsumer(executionContext, formData, nullptr)
229 {
230 }
231
232 FormDataBytesConsumer::FormDataBytesConsumer(ExecutionContext* executionContext, PassRefPtr<EncodedFormData> formData, BytesConsumer* consumer)
233 : m_impl(isSimple(formData.get()) ?
234 static_cast<BytesConsumer*>(new SimpleFormDataBytesConsumer(formData)) :
235 static_cast<BytesConsumer*>(new ComplexFormDataBytesConsumer(executionCo ntext, formData, consumer)))
236 {
237 }
238
239 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698