OLD | NEW |
---|---|
(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 | |
OLD | NEW |