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

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

Issue 2292763002: [Fetch API] Implement Request.formData and Response.formData. (Closed)
Patch Set: 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "modules/fetch/FetchDataLoader.h" 5 #include "modules/fetch/FetchDataLoader.h"
6 6
7 #include "core/fetch/MultipartImageResourceParser.h"
horo 2016/08/30 05:12:55 I think we should rename MultipartImageResourcePar
yhirano 2016/08/30 05:51:14 MultipartImageResourceParser is not a generic mult
horo 2016/08/30 06:24:36 Then, are you saying that we shouldn't use it to p
8 #include "core/fileapi/Blob.h"
7 #include "core/html/parser/TextResourceDecoder.h" 9 #include "core/html/parser/TextResourceDecoder.h"
horo 2016/08/30 05:12:56 Include FormData.h here.
e_hakkinen 2016/08/30 07:59:08 Done.
8 #include "modules/fetch/BytesConsumer.h" 10 #include "modules/fetch/BytesConsumer.h"
11 #include "platform/HTTPNames.h"
12 #include "platform/network/ParsedContentType.h"
9 #include "wtf/PtrUtil.h" 13 #include "wtf/PtrUtil.h"
10 #include "wtf/text/StringBuilder.h" 14 #include "wtf/text/StringBuilder.h"
11 #include "wtf/text/WTFString.h" 15 #include "wtf/text/WTFString.h"
12 #include "wtf/typed_arrays/ArrayBufferBuilder.h" 16 #include "wtf/typed_arrays/ArrayBufferBuilder.h"
13 #include <memory> 17 #include <memory>
14 18
15 namespace blink { 19 namespace blink {
16 20
17 namespace { 21 namespace {
18 22
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 BytesConsumer::Client::trace(visitor); 158 BytesConsumer::Client::trace(visitor);
155 } 159 }
156 160
157 private: 161 private:
158 Member<BytesConsumer> m_consumer; 162 Member<BytesConsumer> m_consumer;
159 Member<FetchDataLoader::Client> m_client; 163 Member<FetchDataLoader::Client> m_client;
160 164
161 std::unique_ptr<ArrayBufferBuilder> m_rawData; 165 std::unique_ptr<ArrayBufferBuilder> m_rawData;
162 }; 166 };
163 167
168 class FetchDataLoaderAsFormData final : public FetchDataLoader, public BytesCons umer::Client, private MultipartImageResourceParser::Client {
169 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsFormData);
170 public:
171 explicit FetchDataLoaderAsFormData(const String& multipartBoundary)
172 : m_multipartBoundary(multipartBoundary)
173 {
174 }
175
176 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e
177 {
178 DCHECK(!m_client);
179 DCHECK(!m_multipartParser);
180 DCHECK(!m_consumer);
181
182 CString multipartBoundaryCString = m_multipartBoundary.utf8();
183 Vector<char> multipartBoundaryVector;
184 multipartBoundaryVector.append(multipartBoundaryCString.data(), multipar tBoundaryCString.length());
185
186 m_client = client;
187 m_formData = FormData::create();
188 m_multipartParser = new MultipartImageResourceParser(ResourceResponse(), multipartBoundaryVector, this);
189 m_consumer = consumer;
190 m_consumer->setClient(this);
191 onStateChange();
192 }
193
194 void onStateChange() override
195 {
196 while (true) {
197 const char* buffer;
198 size_t available;
199 switch (m_consumer->beginRead(&buffer, &available)) {
200 case BytesConsumer::Result::Ok:
201 if (available > 0)
202 m_multipartParser->appendData(buffer, available);
203 m_consumer->endRead(available);
204 break;
205 case BytesConsumer::Result::ShouldWait:
206 return;
207 case BytesConsumer::Result::Done:
208 m_multipartParser->finish();
209 m_currentEntry.finishIfInitialized(m_formData);
210 m_client->didFetchDataLoadedFormData(m_formData);
211 return;
212 case BytesConsumer::Result::Error:
213 m_client->didFetchDataLoadFailed();
214 return;
215 }
216 }
217 }
218
219 void cancel() override
220 {
221 m_consumer->cancel();
222 m_multipartParser->cancel();
223 }
224
225 DEFINE_INLINE_TRACE()
226 {
227 visitor->trace(m_consumer);
228 visitor->trace(m_client);
229 visitor->trace(m_formData);
230 visitor->trace(m_multipartParser);
231 FetchDataLoader::trace(visitor);
232 BytesConsumer::Client::trace(visitor);
233 MultipartImageResourceParser::Client::trace(visitor);
234 }
235
236 private:
237 void onePartInMultipartReceived(const ResourceResponse& response) override
238 {
239 m_currentEntry.finishIfInitialized(m_formData);
240 if (!m_currentEntry.initialize(response))
241 m_client->didFetchDataLoadFailed();
242 }
243
244 void multipartDataReceived(const char* bytes, size_t size) override
245 {
246 m_currentEntry.appendBytes(bytes, size);
247 }
248
249 class Entry {
250 public:
251 bool initialize(const ResourceResponse& response)
252 {
253 ParsedContentType disposition(response.httpHeaderField(HTTPNames::Co ntent_Disposition));
254 String dispositionType = disposition.mimeType();
255 m_filename = disposition.parameterValueForName("filename");
256 m_name = disposition.parameterValueForName("name");
257 if (dispositionType != "form-data" || m_name.isNull())
258 return false;
259 if (!m_filename.isNull()) {
260 m_blobData = BlobData::create();
261 m_blobData->setContentType(response.httpHeaderField(HTTPNames::C ontent_Type));
262 m_stringBuilder.reset();
263 } else {
264 m_blobData.reset();
265 if (!m_decoder)
266 m_decoder = TextResourceDecoder::createAlwaysUseUTF8ForText( );
267 m_stringBuilder.reset(new StringBuilder);
268 }
269 return true;
270 }
271
272 void appendBytes(const char* bytes, size_t size)
273 {
274 if (m_blobData)
275 m_blobData->appendBytes(bytes, size);
276 if (m_stringBuilder)
277 m_stringBuilder->append(m_decoder->decode(bytes, size));
278 }
279
280 void finishIfInitialized(FormData* formData)
281 {
282 if (m_blobData) {
283 auto size = m_blobData->length();
horo 2016/08/30 05:12:56 ASSERT(!m_stringBuilder);
e_hakkinen 2016/08/30 07:59:08 ASSERT is deprecated and does not thus pass presub
284 formData->append(m_name, Blob::create(BlobDataHandle::create(std ::move(m_blobData), size)), m_filename);
285 }
286 if (m_stringBuilder) {
287 m_stringBuilder->append(m_decoder->flush());
horo 2016/08/30 05:12:56 ASSERT(!m_blobData));
e_hakkinen 2016/08/30 07:59:08 Done.
288 formData->append(m_name, m_stringBuilder->toString());
289 }
290 }
291
292 private:
293 std::unique_ptr<BlobData> m_blobData;
294 std::unique_ptr<TextResourceDecoder> m_decoder;
295 String m_filename;
296 String m_name;
297 std::unique_ptr<StringBuilder> m_stringBuilder;
298 };
299
300 Member<BytesConsumer> m_consumer;
301 Member<FetchDataLoader::Client> m_client;
302 Member<FormData> m_formData;
303 Member<MultipartImageResourceParser> m_multipartParser;
304
305 Entry m_currentEntry;
306 String m_multipartBoundary;
307 };
308
164 class FetchDataLoaderAsString final : public FetchDataLoader, public BytesConsum er::Client { 309 class FetchDataLoaderAsString final : public FetchDataLoader, public BytesConsum er::Client {
165 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsString); 310 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsString);
166 public: 311 public:
167 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e 312 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e
168 { 313 {
169 DCHECK(!m_client); 314 DCHECK(!m_client);
170 DCHECK(!m_decoder); 315 DCHECK(!m_decoder);
171 DCHECK(!m_consumer); 316 DCHECK(!m_consumer);
172 m_client = client; 317 m_client = client;
173 m_decoder = TextResourceDecoder::createAlwaysUseUTF8ForText(); 318 m_decoder = TextResourceDecoder::createAlwaysUseUTF8ForText();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeTyp e) 443 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeTyp e)
299 { 444 {
300 return new FetchDataLoaderAsBlobHandle(mimeType); 445 return new FetchDataLoaderAsBlobHandle(mimeType);
301 } 446 }
302 447
303 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() 448 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer()
304 { 449 {
305 return new FetchDataLoaderAsArrayBuffer(); 450 return new FetchDataLoaderAsArrayBuffer();
306 } 451 }
307 452
453 FetchDataLoader* FetchDataLoader::createLoaderAsFormData(const String& multipart Boundary)
454 {
455 return new FetchDataLoaderAsFormData(multipartBoundary);
456 }
457
308 FetchDataLoader* FetchDataLoader::createLoaderAsString() 458 FetchDataLoader* FetchDataLoader::createLoaderAsString()
309 { 459 {
310 return new FetchDataLoaderAsString(); 460 return new FetchDataLoaderAsString();
311 } 461 }
312 462
313 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) 463 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream)
314 { 464 {
315 return new FetchDataLoaderAsStream(outStream); 465 return new FetchDataLoaderAsStream(outStream);
316 } 466 }
317 467
318 } // namespace blink 468 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698