OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 * Library General Public License for more details. | 14 * Library General Public License for more details. |
15 * | 15 * |
16 * You should have received a copy of the GNU Library General Public License | 16 * You should have received a copy of the GNU Library General Public License |
17 * along with this library; see the file COPYING.LIB. If not, write to | 17 * along with this library; see the file COPYING.LIB. If not, write to |
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 * Boston, MA 02110-1301, USA. | 19 * Boston, MA 02110-1301, USA. |
20 */ | 20 */ |
21 | 21 |
22 #include "config.h" | 22 #include "config.h" |
23 | 23 |
24 #include "FormData.h" | 24 #include "FormData.h" |
25 | 25 |
26 #include "BlobData.h" | |
27 #include "BlobRegistryImpl.h" | |
28 #include "BlobURL.h" | |
29 #include "Chrome.h" | 26 #include "Chrome.h" |
30 #include "ChromeClient.h" | 27 #include "ChromeClient.h" |
31 #include "Document.h" | 28 #include "Document.h" |
32 #include "File.h" | 29 #include "File.h" |
33 #include "FileSystem.h" | 30 #include "FileSystem.h" |
34 #include "FormDataBuilder.h" | 31 #include "FormDataBuilder.h" |
35 #include "FormDataList.h" | 32 #include "FormDataList.h" |
36 #include "MIMETypeRegistry.h" | 33 #include "MIMETypeRegistry.h" |
37 #include "Page.h" | 34 #include "Page.h" |
38 #include "PlatformMemoryInstrumentation.h" | 35 #include "PlatformMemoryInstrumentation.h" |
39 #include "TextEncoding.h" | 36 #include "TextEncoding.h" |
40 #include <wtf/Decoder.h> | 37 #include <wtf/Decoder.h> |
41 #include <wtf/Encoder.h> | 38 #include <wtf/Encoder.h> |
42 #include <wtf/MemoryInstrumentationVector.h> | 39 #include <wtf/MemoryInstrumentationVector.h> |
43 | 40 |
| 41 #if PLATFORM(CHROMIUM) |
| 42 // Chromium doesn't store blob data in renderer processes. |
| 43 #else |
| 44 #include "BlobRegistryImpl.h" |
| 45 #endif |
| 46 |
44 namespace WebCore { | 47 namespace WebCore { |
45 | 48 |
46 inline FormData::FormData() | 49 inline FormData::FormData() |
47 : m_identifier(0) | 50 : m_identifier(0) |
48 , m_hasGeneratedFiles(false) | 51 , m_hasGeneratedFiles(false) |
49 , m_alwaysStream(false) | 52 , m_alwaysStream(false) |
50 , m_containsPasswordData(false) | 53 , m_containsPasswordData(false) |
51 { | 54 { |
52 } | 55 } |
53 | 56 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 break; | 143 break; |
141 case FormDataElement::encodedFile: | 144 case FormDataElement::encodedFile: |
142 #if ENABLE(BLOB) | 145 #if ENABLE(BLOB) |
143 formData->m_elements.append(FormDataElement(e.m_filename, e.m_fileSt
art, e.m_fileLength, e.m_expectedFileModificationTime, e.m_shouldGenerateFile)); | 146 formData->m_elements.append(FormDataElement(e.m_filename, e.m_fileSt
art, e.m_fileLength, e.m_expectedFileModificationTime, e.m_shouldGenerateFile)); |
144 #else | 147 #else |
145 formData->m_elements.append(FormDataElement(e.m_filename, e.m_should
GenerateFile)); | 148 formData->m_elements.append(FormDataElement(e.m_filename, e.m_should
GenerateFile)); |
146 #endif | 149 #endif |
147 break; | 150 break; |
148 #if ENABLE(BLOB) | 151 #if ENABLE(BLOB) |
149 case FormDataElement::encodedBlob: | 152 case FormDataElement::encodedBlob: |
150 formData->m_elements.append(FormDataElement(e.m_url)); | 153 formData->m_elements.append(FormDataElement(e.m_blobUUID, e.m_option
alBlobDataHandle)); |
151 break; | 154 break; |
152 #endif | 155 #endif |
153 #if ENABLE(FILE_SYSTEM) | 156 #if ENABLE(FILE_SYSTEM) |
154 case FormDataElement::encodedURL: | 157 case FormDataElement::encodedFileSystemURL: |
155 formData->m_elements.append(FormDataElement(e.m_url, e.m_fileStart,
e.m_fileLength, e.m_expectedFileModificationTime)); | 158 formData->m_elements.append(FormDataElement(e.m_fileSystemURL, e.m_f
ileStart, e.m_fileLength, e.m_expectedFileModificationTime)); |
156 break; | 159 break; |
157 #endif | 160 #endif |
158 } | 161 } |
159 } | 162 } |
160 return formData.release(); | 163 return formData.release(); |
161 } | 164 } |
162 | 165 |
163 void FormData::appendData(const void* data, size_t size) | 166 void FormData::appendData(const void* data, size_t size) |
164 { | 167 { |
165 if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::dat
a) | 168 if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::dat
a) |
(...skipping 12 matching lines...) Expand all Loading... |
178 m_elements.append(FormDataElement(filename, shouldGenerateFile)); | 181 m_elements.append(FormDataElement(filename, shouldGenerateFile)); |
179 #endif | 182 #endif |
180 } | 183 } |
181 | 184 |
182 #if ENABLE(BLOB) | 185 #if ENABLE(BLOB) |
183 void FormData::appendFileRange(const String& filename, long long start, long lon
g length, double expectedModificationTime, bool shouldGenerateFile) | 186 void FormData::appendFileRange(const String& filename, long long start, long lon
g length, double expectedModificationTime, bool shouldGenerateFile) |
184 { | 187 { |
185 m_elements.append(FormDataElement(filename, start, length, expectedModificat
ionTime, shouldGenerateFile)); | 188 m_elements.append(FormDataElement(filename, start, length, expectedModificat
ionTime, shouldGenerateFile)); |
186 } | 189 } |
187 | 190 |
188 void FormData::appendBlob(const KURL& blobURL) | 191 void FormData::appendBlob(const String& blobUUID, PassRefPtr<BlobDataHandle> opt
ionalBlobDataHandle) |
189 { | 192 { |
190 m_elements.append(FormDataElement(blobURL)); | 193 m_elements.append(FormDataElement(blobUUID, optionalBlobDataHandle)); |
191 } | 194 } |
192 #endif | 195 #endif |
193 #if ENABLE(FILE_SYSTEM) | 196 #if ENABLE(FILE_SYSTEM) |
194 void FormData::appendURL(const KURL& url) | 197 void FormData::appendURL(const KURL& url) |
195 { | 198 { |
196 m_elements.append(FormDataElement(url, 0, BlobDataItem::toEndOfFile, invalid
FileTime())); | 199 m_elements.append(FormDataElement(url, 0, BlobDataItem::toEndOfFile, invalid
FileTime())); |
197 } | 200 } |
198 | 201 |
199 void FormData::appendURLRange(const KURL& url, long long start, long long length
, double expectedModificationTime) | 202 void FormData::appendURLRange(const KURL& url, long long start, long long length
, double expectedModificationTime) |
200 { | 203 { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // Do not add the file if the path is empty. | 275 // Do not add the file if the path is empty. |
273 if (!file->path().isEmpty()) | 276 if (!file->path().isEmpty()) |
274 appendFile(file->path(), shouldGenerateFile); | 277 appendFile(file->path(), shouldGenerateFile); |
275 #if ENABLE(FILE_SYSTEM) | 278 #if ENABLE(FILE_SYSTEM) |
276 if (!file->fileSystemURL().isEmpty()) | 279 if (!file->fileSystemURL().isEmpty()) |
277 appendURL(file->fileSystemURL()); | 280 appendURL(file->fileSystemURL()); |
278 #endif | 281 #endif |
279 } | 282 } |
280 #if ENABLE(BLOB) | 283 #if ENABLE(BLOB) |
281 else | 284 else |
282 appendBlob(value.blob()->url()); | 285 appendBlob(value.blob()->uuid(), value.blob()->blobDataHandl
e()); |
283 #endif | 286 #endif |
284 } else | 287 } else |
285 appendData(value.data().data(), value.data().length()); | 288 appendData(value.data().data(), value.data().length()); |
286 appendData("\r\n", 2); | 289 appendData("\r\n", 2); |
287 } else { | 290 } else { |
288 // Omit the name "isindex" if it's the first form data element. | 291 // Omit the name "isindex" if it's the first form data element. |
289 // FIXME: Why is this a good rule? Is this obsolete now? | 292 // FIXME: Why is this a good rule? Is this obsolete now? |
290 if (encodedData.isEmpty() && key.data() == "isindex") | 293 if (encodedData.isEmpty() && key.data() == "isindex") |
291 FormDataBuilder::encodeStringAsFormData(encodedData, value.data(
)); | 294 FormDataBuilder::encodeStringAsFormData(encodedData, value.data(
)); |
292 else | 295 else |
(...skipping 20 matching lines...) Expand all Loading... |
313 } | 316 } |
314 | 317 |
315 String FormData::flattenToString() const | 318 String FormData::flattenToString() const |
316 { | 319 { |
317 Vector<char> bytes; | 320 Vector<char> bytes; |
318 flatten(bytes); | 321 flatten(bytes); |
319 return Latin1Encoding().decode(reinterpret_cast<const char*>(bytes.data()),
bytes.size()); | 322 return Latin1Encoding().decode(reinterpret_cast<const char*>(bytes.data()),
bytes.size()); |
320 } | 323 } |
321 | 324 |
322 #if ENABLE(BLOB) | 325 #if ENABLE(BLOB) |
323 static void appendBlobResolved(FormData* formData, const KURL& url) | 326 #if PLATFORM(CHROMIUM) |
| 327 // Chromium doesn't store blob data in renderer processes. |
| 328 #else |
| 329 static void appendBlobResolved(FormData* formData, const String& blobUUID) |
324 { | 330 { |
325 RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegist
ry()).getBlobDataFromURL(KURL(ParsedURLString, url)); | 331 RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegist
ry()).getBlobDataFromUUID(blobUUID); |
326 if (!blobData) | 332 if (!blobData) |
327 return; | 333 return; |
328 | 334 |
329 BlobDataItemList::const_iterator it = blobData->items().begin(); | 335 BlobDataItemList::const_iterator it = blobData->items().begin(); |
330 const BlobDataItemList::const_iterator itend = blobData->items().end(); | 336 const BlobDataItemList::const_iterator itend = blobData->items().end(); |
331 for (; it != itend; ++it) { | 337 for (; it != itend; ++it) { |
332 const BlobDataItem& blobItem = *it; | 338 const BlobDataItem& blobItem = *it; |
333 if (blobItem.type == BlobDataItem::Data) | 339 if (blobItem.type == BlobDataItem::Data) |
334 formData->appendData(blobItem.data->data() + static_cast<int>(blobIt
em.offset), static_cast<int>(blobItem.length)); | 340 formData->appendData(blobItem.data->data() + static_cast<int>(blobIt
em.offset), static_cast<int>(blobItem.length)); |
335 else if (blobItem.type == BlobDataItem::File) | 341 else if (blobItem.type == BlobDataItem::File) |
336 formData->appendFileRange(blobItem.path, blobItem.offset, blobItem.l
ength, blobItem.expectedModificationTime); | 342 formData->appendFileRange(blobItem.path, blobItem.offset, blobItem.l
ength, blobItem.expectedModificationTime); |
337 else if (blobItem.type == BlobDataItem::Blob) | 343 else if (blobItem.type == BlobDataItem::Blob) |
338 appendBlobResolved(formData, blobItem.url); | 344 appendBlobResolved(formData, blobItem.blobDataHandle->uuid()); |
339 else | 345 else |
340 ASSERT_NOT_REACHED(); | 346 ASSERT_NOT_REACHED(); |
341 } | 347 } |
342 } | 348 } |
343 | 349 |
344 PassRefPtr<FormData> FormData::resolveBlobReferences() | 350 PassRefPtr<FormData> FormData::resolveBlobReferences() |
345 { | 351 { |
346 // First check if any blobs needs to be resolved, or we can take the fast pa
th. | 352 // First check if any blobs needs to be resolved, or we can take the fast pa
th. |
347 bool hasBlob = false; | 353 bool hasBlob = false; |
348 Vector<FormDataElement>::const_iterator it = elements().begin(); | 354 Vector<FormDataElement>::const_iterator it = elements().begin(); |
(...skipping 13 matching lines...) Expand all Loading... |
362 newFormData->setAlwaysStream(alwaysStream()); | 368 newFormData->setAlwaysStream(alwaysStream()); |
363 newFormData->setIdentifier(identifier()); | 369 newFormData->setIdentifier(identifier()); |
364 it = elements().begin(); | 370 it = elements().begin(); |
365 for (; it != itend; ++it) { | 371 for (; it != itend; ++it) { |
366 const FormDataElement& element = *it; | 372 const FormDataElement& element = *it; |
367 if (element.m_type == FormDataElement::data) | 373 if (element.m_type == FormDataElement::data) |
368 newFormData->appendData(element.m_data.data(), element.m_data.size()
); | 374 newFormData->appendData(element.m_data.data(), element.m_data.size()
); |
369 else if (element.m_type == FormDataElement::encodedFile) | 375 else if (element.m_type == FormDataElement::encodedFile) |
370 newFormData->appendFileRange(element.m_filename, element.m_fileStart
, element.m_fileLength, element.m_expectedFileModificationTime, element.m_should
GenerateFile); | 376 newFormData->appendFileRange(element.m_filename, element.m_fileStart
, element.m_fileLength, element.m_expectedFileModificationTime, element.m_should
GenerateFile); |
371 else if (element.m_type == FormDataElement::encodedBlob) | 377 else if (element.m_type == FormDataElement::encodedBlob) |
372 appendBlobResolved(newFormData.get(), element.m_url); | 378 appendBlobResolved(newFormData.get(), element.m_blobUUID); |
373 else | 379 else |
374 ASSERT_NOT_REACHED(); | 380 ASSERT_NOT_REACHED(); |
375 } | 381 } |
376 return newFormData.release(); | 382 return newFormData.release(); |
377 } | 383 } |
378 #endif | 384 #endif // CHROMIUM |
| 385 #endif // BLOB |
379 | 386 |
380 void FormData::generateFiles(Document* document) | 387 void FormData::generateFiles(Document* document) |
381 { | 388 { |
382 ASSERT(!m_hasGeneratedFiles); | 389 ASSERT(!m_hasGeneratedFiles); |
383 | 390 |
384 if (m_hasGeneratedFiles) | 391 if (m_hasGeneratedFiles) |
385 return; | 392 return; |
386 | 393 |
387 Page* page = document->page(); | 394 Page* page = document->page(); |
388 if (!page) | 395 if (!page) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 encoder.encodeDouble(element.m_expectedFileModificationTime); | 449 encoder.encodeDouble(element.m_expectedFileModificationTime); |
443 #else | 450 #else |
444 encoder.encodeInt64(0); | 451 encoder.encodeInt64(0); |
445 encoder.encodeInt64(0); | 452 encoder.encodeInt64(0); |
446 encoder.encodeDouble(invalidFileTime()); | 453 encoder.encodeDouble(invalidFileTime()); |
447 #endif | 454 #endif |
448 return; | 455 return; |
449 | 456 |
450 #if ENABLE(BLOB) | 457 #if ENABLE(BLOB) |
451 case FormDataElement::encodedBlob: | 458 case FormDataElement::encodedBlob: |
452 encoder.encodeString(element.m_url.string()); | 459 encoder.encodeString(element.m_blobUUID); |
453 return; | 460 return; |
454 #endif | 461 #endif |
455 | 462 |
456 #if ENABLE(FILE_SYSTEM) | 463 #if ENABLE(FILE_SYSTEM) |
457 case FormDataElement::encodedURL: | 464 case FormDataElement::encodedFileSystemURL: |
458 encoder.encodeString(element.m_url.string()); | 465 encoder.encodeString(element.m_fileSystemURL.string()); |
459 encoder.encodeInt64(element.m_fileStart); | 466 encoder.encodeInt64(element.m_fileStart); |
460 encoder.encodeInt64(element.m_fileLength); | 467 encoder.encodeInt64(element.m_fileLength); |
461 encoder.encodeDouble(element.m_expectedFileModificationTime); | 468 encoder.encodeDouble(element.m_expectedFileModificationTime); |
462 return; | 469 return; |
463 #endif | 470 #endif |
464 } | 471 } |
465 | 472 |
466 ASSERT_NOT_REACHED(); | 473 ASSERT_NOT_REACHED(); |
467 } | 474 } |
468 | 475 |
(...skipping 10 matching lines...) Expand all Loading... |
479 if (!decoder.decodeBytes(data)) | 486 if (!decoder.decodeBytes(data)) |
480 return false; | 487 return false; |
481 size_t size = data.size(); | 488 size_t size = data.size(); |
482 element.m_data.resize(size); | 489 element.m_data.resize(size); |
483 memcpy(element.m_data.data(), data.data(), size); | 490 memcpy(element.m_data.data(), data.data(), size); |
484 return true; | 491 return true; |
485 } | 492 } |
486 | 493 |
487 case FormDataElement::encodedFile: | 494 case FormDataElement::encodedFile: |
488 #if ENABLE(FILE_SYSTEM) | 495 #if ENABLE(FILE_SYSTEM) |
489 case FormDataElement::encodedURL: | 496 case FormDataElement::encodedFileSystemURL: |
490 #endif | 497 #endif |
491 { | 498 { |
492 element.m_type = static_cast<FormDataElement::Type>(type); | 499 element.m_type = static_cast<FormDataElement::Type>(type); |
493 String filenameOrURL; | 500 String filenameOrURL; |
494 if (!decoder.decodeString(filenameOrURL)) | 501 if (!decoder.decodeString(filenameOrURL)) |
495 return false; | 502 return false; |
496 if (type == FormDataElement::encodedFile && !decoder.decodeBool(element.
m_shouldGenerateFile)) | 503 if (type == FormDataElement::encodedFile && !decoder.decodeBool(element.
m_shouldGenerateFile)) |
497 return false; | 504 return false; |
498 int64_t fileStart; | 505 int64_t fileStart; |
499 if (!decoder.decodeInt64(fileStart)) | 506 if (!decoder.decodeInt64(fileStart)) |
500 return false; | 507 return false; |
501 if (fileStart < 0) | 508 if (fileStart < 0) |
502 return false; | 509 return false; |
503 int64_t fileLength; | 510 int64_t fileLength; |
504 if (!decoder.decodeInt64(fileLength)) | 511 if (!decoder.decodeInt64(fileLength)) |
505 return false; | 512 return false; |
506 if (fileLength < fileStart) | 513 if (fileLength < fileStart) |
507 return false; | 514 return false; |
508 double expectedFileModificationTime; | 515 double expectedFileModificationTime; |
509 if (!decoder.decodeDouble(expectedFileModificationTime)) | 516 if (!decoder.decodeDouble(expectedFileModificationTime)) |
510 return false; | 517 return false; |
511 | 518 |
512 #if ENABLE(FILE_SYSTEM) | 519 #if ENABLE(FILE_SYSTEM) |
513 if (type == FormDataElement::encodedURL) | 520 if (type == FormDataElement::encodedFileSystemURL) |
514 element.m_url = KURL(KURL(), filenameOrURL); | 521 element.m_fileSystemURL = KURL(KURL(), filenameOrURL); |
515 else | 522 else |
516 #endif | 523 #endif |
517 element.m_filename = filenameOrURL; | 524 element.m_filename = filenameOrURL; |
518 | 525 |
519 #if ENABLE(BLOB) | 526 #if ENABLE(BLOB) |
520 element.m_fileStart = fileStart; | 527 element.m_fileStart = fileStart; |
521 element.m_fileLength = fileLength; | 528 element.m_fileLength = fileLength; |
522 element.m_expectedFileModificationTime = expectedFileModificationTime; | 529 element.m_expectedFileModificationTime = expectedFileModificationTime; |
523 #endif | 530 #endif |
524 return true; | 531 return true; |
525 } | 532 } |
526 | 533 |
527 #if ENABLE(BLOB) | 534 #if ENABLE(BLOB) |
528 case FormDataElement::encodedBlob: | 535 case FormDataElement::encodedBlob: |
529 element.m_type = FormDataElement::encodedBlob; | 536 element.m_type = FormDataElement::encodedBlob; |
530 String blobURLString; | 537 String blobUUID; |
531 if (!decoder.decodeString(blobURLString)) | 538 if (!decoder.decodeString(blobUUID)) |
532 return false; | 539 return false; |
533 element.m_url = KURL(KURL(), blobURLString); | 540 element.m_blobUUID = blobUUID; |
| 541 // Note we're not setting the optionalBlobDataHandle here. |
534 return true; | 542 return true; |
535 #endif | 543 #endif |
536 | 544 |
537 } | 545 } |
538 | 546 |
539 return false; | 547 return false; |
540 } | 548 } |
541 | 549 |
542 void FormData::encodeForBackForward(Encoder& encoder) const | 550 void FormData::encodeForBackForward(Encoder& encoder) const |
543 { | 551 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 if (!decoder.decodeBool(data->m_hasGeneratedFiles)) | 590 if (!decoder.decodeBool(data->m_hasGeneratedFiles)) |
583 return 0; | 591 return 0; |
584 | 592 |
585 if (!decoder.decodeInt64(data->m_identifier)) | 593 if (!decoder.decodeInt64(data->m_identifier)) |
586 return 0; | 594 return 0; |
587 | 595 |
588 return data.release(); | 596 return data.release(); |
589 } | 597 } |
590 | 598 |
591 } // namespace WebCore | 599 } // namespace WebCore |
OLD | NEW |