OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |