summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/network
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-08 12:18:00 +0100
committerKristian Monsen <kristianm@google.com>2010-09-11 12:08:58 +0100
commit5ddde30071f639962dd557c453f2ad01f8f0fd00 (patch)
tree775803c4ab35af50aa5f5472cd1fb95fe9d5152d /WebCore/platform/network
parent3e63d9b33b753ca86d0765d1b3d711114ba9e34f (diff)
downloadexternal_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.zip
external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.gz
external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.bz2
Merge WebKit at r66666 : Initial merge by git.
Change-Id: I57dedeb49859adc9c539e760f0e749768c66626f
Diffstat (limited to 'WebCore/platform/network')
-rw-r--r--WebCore/platform/network/BlobRegistryImpl.cpp16
-rw-r--r--WebCore/platform/network/BlobResourceHandle.cpp3
-rw-r--r--WebCore/platform/network/BlobResourceHandle.h2
-rw-r--r--WebCore/platform/network/FormData.cpp132
-rw-r--r--WebCore/platform/network/FormData.h18
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm56
6 files changed, 118 insertions, 109 deletions
diff --git a/WebCore/platform/network/BlobRegistryImpl.cpp b/WebCore/platform/network/BlobRegistryImpl.cpp
index ee872e6..c5beb64 100644
--- a/WebCore/platform/network/BlobRegistryImpl.cpp
+++ b/WebCore/platform/network/BlobRegistryImpl.cpp
@@ -30,8 +30,11 @@
#include "config.h"
+#if ENABLE(BLOB)
+
#include "BlobRegistryImpl.h"
+#include "BlobResourceHandle.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceLoader.h"
@@ -60,22 +63,21 @@ bool BlobRegistryImpl::shouldLoadResource(const ResourceRequest& request) const
return true;
}
-PassRefPtr<ResourceHandle> BlobRegistryImpl::createResourceHandle(const ResourceRequest& request, ResourceHandleClient*)
+PassRefPtr<ResourceHandle> BlobRegistryImpl::createResourceHandle(const ResourceRequest& request, ResourceHandleClient* client)
{
if (!shouldLoadResource(request))
return 0;
- // FIXME: To be implemented.
- return 0;
+ return BlobResourceHandle::create(m_blobs.get(request.url().string()), request, client);
}
-bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request, ResourceError&, ResourceResponse&, Vector<char>&)
+bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
if (!shouldLoadResource(request))
return false;
- // FIXME: To be implemented.
- return false;
+ BlobResourceHandle::loadResourceSynchronously(m_blobs.get(request.url().string()), request, error, response, data);
+ return true;
}
void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobDataItemList& items)
@@ -175,3 +177,5 @@ PassRefPtr<BlobStorageData> BlobRegistryImpl::getBlobDataFromURL(const KURL& url
}
} // namespace WebCore
+
+#endif // ENABLE(BLOB)
diff --git a/WebCore/platform/network/BlobResourceHandle.cpp b/WebCore/platform/network/BlobResourceHandle.cpp
index 63335f6..8767b55 100644
--- a/WebCore/platform/network/BlobResourceHandle.cpp
+++ b/WebCore/platform/network/BlobResourceHandle.cpp
@@ -159,7 +159,8 @@ BlobResourceHandle::BlobResourceHandle(PassRefPtr<BlobStorageData> blobData, con
, m_fileOpened(false)
{
if (m_async) {
- m_asyncStream = adoptRef(client->createAsyncFileStream(this));
+ // We need to take a ref.
+ m_asyncStream = client->createAsyncFileStream(this);
callOnMainThread(delayedStart, this);
} else
m_stream = FileStream::create();
diff --git a/WebCore/platform/network/BlobResourceHandle.h b/WebCore/platform/network/BlobResourceHandle.h
index b2a0854..63e8578 100644
--- a/WebCore/platform/network/BlobResourceHandle.h
+++ b/WebCore/platform/network/BlobResourceHandle.h
@@ -42,11 +42,11 @@
namespace WebCore {
class AsyncFileStream;
-class BlobDataItem;
class BlobStorageData;
class FileStream;
class ResourceHandleClient;
class ResourceRequest;
+struct BlobDataItem;
class BlobResourceHandle : public FileStreamClient, public ResourceHandle {
public:
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 4f2b365..786f1b6 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -22,23 +22,21 @@
#include "FormData.h"
-#include "BlobItem.h"
+#include "BlobData.h"
+#include "BlobURL.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
+#include "File.h"
#include "FileSystem.h"
#include "FormDataBuilder.h"
+#include "FormDataList.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "TextEncoding.h"
namespace WebCore {
-#if ENABLE(BLOB)
-const long long FormDataElement::toEndOfFile = -1;
-const double FormDataElement::doNotCheckFileChange = 0;
-#endif
-
inline FormData::FormData()
: m_identifier(0)
, m_hasGeneratedFiles(false)
@@ -99,17 +97,17 @@ PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
return result.release();
}
-PassRefPtr<FormData> FormData::create(const BlobItemList& items, const TextEncoding& encoding)
+PassRefPtr<FormData> FormData::create(const FormDataList& list, const TextEncoding& encoding)
{
RefPtr<FormData> result = create();
- result->appendKeyValuePairItems(items, encoding, false, 0);
+ result->appendKeyValuePairItems(list, encoding, false, 0);
return result.release();
}
-PassRefPtr<FormData> FormData::createMultiPart(const BlobItemList& items, const TextEncoding& encoding, Document* document)
+PassRefPtr<FormData> FormData::createMultiPart(const FormDataList& list, const TextEncoding& encoding, Document* document)
{
RefPtr<FormData> result = create();
- result->appendKeyValuePairItems(items, encoding, true, document);
+ result->appendKeyValuePairItems(list, encoding, true, document);
return result.release();
}
@@ -162,44 +160,12 @@ void FormData::appendData(const void* data, size_t size)
void FormData::appendFile(const String& filename, bool shouldGenerateFile)
{
#if ENABLE(BLOB)
- m_elements.append(FormDataElement(filename, 0, FormDataElement::toEndOfFile, FormDataElement::doNotCheckFileChange, shouldGenerateFile));
+ m_elements.append(FormDataElement(filename, 0, BlobDataItem::toEndOfFile, BlobDataItem::doNotCheckFileChange, shouldGenerateFile));
#else
m_elements.append(FormDataElement(filename, shouldGenerateFile));
#endif
}
-void FormData::appendItems(const BlobItemList& items)
-{
- for (BlobItemList::const_iterator iter(items.begin()); iter != items.end(); ++iter)
- appendItem(iter->get(), false);
-}
-
-void FormData::appendItem(const BlobItem* item, bool shouldGenerateFile)
-{
- const DataBlobItem* dataItem = item->toDataBlobItem();
- if (dataItem) {
- appendData(dataItem->data(), static_cast<size_t>(dataItem->size()));
- return;
- }
-
- const FileBlobItem* fileItem = item->toFileBlobItem();
- ASSERT(fileItem);
- if (fileItem->path().isEmpty()) {
- // If the path is empty do not add the item.
- return;
- }
-
-#if ENABLE(BLOB)
- const FileRangeBlobItem* fileRangeItem = item->toFileRangeBlobItem();
- if (fileRangeItem) {
- appendFileRange(fileItem->path(), fileRangeItem->start(), fileRangeItem->size(), fileRangeItem->snapshotModificationTime(), shouldGenerateFile);
- return;
- }
-#endif
-
- appendFile(fileItem->path(), shouldGenerateFile);
-}
-
#if ENABLE(BLOB)
void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile)
{
@@ -212,80 +178,82 @@ void FormData::appendBlob(const KURL& blobURL)
}
#endif
-void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
+void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
{
if (isMultiPartForm)
m_boundary = FormDataBuilder::generateUniqueBoundaryString();
Vector<char> encodedData;
+ const Vector<FormDataList::Item>& items = list.items();
size_t formDataListSize = items.size();
ASSERT(!(formDataListSize % 2));
for (size_t i = 0; i < formDataListSize; i += 2) {
- const StringBlobItem* key = items[i]->toStringBlobItem();
- const BlobItem* value = items[i + 1].get();
- ASSERT(key);
+ const FormDataList::Item& key = items[i];
+ const FormDataList::Item& value = items[i + 1];
if (isMultiPartForm) {
Vector<char> header;
- FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key->cstr());
+ FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());
bool shouldGenerateFile = false;
- // If the current type is FILE, then we also need to include the filename
- const FileBlobItem* fileItem = value->toFileBlobItem();
- if (fileItem) {
- const String& path = fileItem->path();
-#if ENABLE(DIRECTORY_UPLOAD)
- String fileName = !fileItem->relativePath().isEmpty() ? fileItem->relativePath() : fileItem->name();
+ // If the current type is blob, then we also need to include the filename
+ if (value.blob()) {
+ String name;
+ if (value.blob()->isFile()) {
+ // For file blob, use the filename (or relative path if it is present) as the name.
+ File* file = static_cast<File*>(value.blob());
+#if ENABLE(DIRECTORY_UPLOAD)
+ name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();
#else
- String fileName = fileItem->name();
-#endif
+ name = file->name();
+#endif
- // Let the application specify a filename if it's going to generate a replacement file for the upload.
- if (!path.isEmpty()) {
+ // Let the application specify a filename if it's going to generate a replacement file for the upload.
if (Page* page = document->page()) {
String generatedFileName;
- shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
+ shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(file->path(), generatedFileName);
if (shouldGenerateFile)
- fileName = generatedFileName;
+ name = generatedFileName;
}
+ } else {
+ // For non-file blob, use the identifier part of the URL as the name.
+ name = "Blob" + BlobURL::getIdentifier(value.blob()->url());
+ name = name.replace("-", ""); // For safety, remove '-' from the filename since some servers may not like it.
}
// We have to include the filename=".." part in the header, even if the filename is empty
- FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, fileName);
+ FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
- // If the item is sliced from a file, do not add the content type.
-#if ENABLE(BLOB)
- if (!fileName.isEmpty() && !value->toFileRangeBlobItem()) {
-#else
- if (!fileName.isEmpty()) {
-#endif
- // FIXME: The MIMETypeRegistry function's name makes it sound like it takes a path,
- // not just a basename. But filename is not the path. But note that it's not safe to
- // just use path instead since in the generated-file case it will not reflect the
- // MIME type of the generated file.
- String mimeType = MIMETypeRegistry::getMIMETypeForPath(fileName);
- if (!mimeType.isEmpty())
- FormDataBuilder::addContentTypeToMultiPartHeader(header, mimeType.latin1());
- }
+ // Add the content type if it is available.
+ if (value.blob()->type().isEmpty())
+ FormDataBuilder::addContentTypeToMultiPartHeader(header, value.blob()->type().latin1());
}
FormDataBuilder::finishMultiPartHeader(header);
// Append body
appendData(header.data(), header.size());
- appendItem(value, shouldGenerateFile);
+ if (value.blob()) {
+ if (value.blob()->isFile()) {
+ // Do not add the file if the path is empty.
+ if (!static_cast<File*>(value.blob())->path().isEmpty())
+ appendFile(static_cast<File*>(value.blob())->path(), shouldGenerateFile);
+ }
+#if ENABLE(BLOB)
+ else
+ appendBlob(value.blob()->url());
+#endif
+ } else
+ appendData(value.data().data(), value.data().length());
appendData("\r\n", 2);
} else {
// Omit the name "isindex" if it's the first form data element.
// FIXME: Why is this a good rule? Is this obsolete now?
- const StringBlobItem* stringValue = value->toStringBlobItem();
- if (!stringValue)
- continue;
- if (encodedData.isEmpty() && key->cstr() == "isindex")
- FormDataBuilder::encodeStringAsFormData(encodedData, stringValue->cstr());
+ if (encodedData.isEmpty() && key.data() == "isindex")
+ FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
else
- FormDataBuilder::addKeyValuePairAsFormData(encodedData, key->cstr(), stringValue->cstr());
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data());
}
}
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index d7faa89..22ceb25 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -28,10 +28,9 @@
namespace WebCore {
-class BlobItem;
class Document;
+class FormDataList;
class TextEncoding;
-typedef Vector<RefPtr<BlobItem> > BlobItemList;
class FormDataElement {
public:
@@ -62,11 +61,6 @@ public:
#endif
String m_generatedFilename;
bool m_shouldGenerateFile;
-
-#if ENABLE(BLOB)
- static const long long toEndOfFile;
- static const double doNotCheckFileChange;
-#endif
};
inline bool operator==(const FormDataElement& a, const FormDataElement& b)
@@ -101,15 +95,14 @@ public:
static PassRefPtr<FormData> create(const void*, size_t);
static PassRefPtr<FormData> create(const CString&);
static PassRefPtr<FormData> create(const Vector<char>&);
- static PassRefPtr<FormData> create(const BlobItemList&, const TextEncoding&);
- static PassRefPtr<FormData> createMultiPart(const BlobItemList&, const TextEncoding&, Document*);
+ static PassRefPtr<FormData> create(const FormDataList&, const TextEncoding&);
+ static PassRefPtr<FormData> createMultiPart(const FormDataList&, const TextEncoding&, Document*);
PassRefPtr<FormData> copy() const;
PassRefPtr<FormData> deepCopy() const;
~FormData();
void appendData(const void* data, size_t);
- void appendItems(const BlobItemList&);
- void appendFile(const String& filename, bool shouldGenerateFile = false);
+ void appendFile(const String& filePath, bool shouldGenerateFile = false);
#if ENABLE(BLOB)
void appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile = false);
void appendBlob(const KURL& blobURL);
@@ -137,8 +130,7 @@ private:
FormData();
FormData(const FormData&);
- void appendItem(const BlobItem*, bool shouldGenerateFile);
- void appendKeyValuePairItems(const BlobItemList&, const TextEncoding&, bool isMultiPartForm, Document*);
+ void appendKeyValuePairItems(const FormDataList&, const TextEncoding&, bool isMultiPartForm, Document*);
Vector<FormDataElement> m_elements;
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index c7bd2e7..ed98356 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -31,6 +31,7 @@
#import "config.h"
#import "FormDataStreamMac.h"
+#import "BlobRegistryImpl.h"
#import "FileSystem.h"
#import "FormData.h"
#import "ResourceHandle.h"
@@ -141,7 +142,7 @@ static void closeCurrentStream(FormStreamFields *form)
CFRelease(form->currentStream);
form->currentStream = NULL;
#if ENABLE(BLOB)
- form->currentStreamRangeLength = FormDataElement::toEndOfFile;
+ form->currentStreamRangeLength = BlobDataItem::toEndOfFile;
#endif
}
if (form->currentData) {
@@ -169,7 +170,7 @@ static bool advanceCurrentStream(FormStreamFields* form)
} else {
#if ENABLE(BLOB)
// Check if the file has been changed or not if required.
- if (nextInput.m_expectedFileModificationTime != FormDataElement::doNotCheckFileChange) {
+ if (nextInput.m_expectedFileModificationTime != BlobDataItem::doNotCheckFileChange) {
time_t fileModificationTime;
if (!getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime))
return false;
@@ -225,7 +226,7 @@ static void* formCreate(CFReadStreamRef stream, void* context)
FormStreamFields* newInfo = new FormStreamFields;
newInfo->currentStream = NULL;
#if ENABLE(BLOB)
- newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile;
+ newInfo->currentStreamRangeLength = BlobDataItem::toEndOfFile;
#endif
newInfo->currentData = 0;
newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
@@ -273,7 +274,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
while (form->currentStream) {
CFIndex bytesToRead = bufferLength;
#if ENABLE(BLOB)
- if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
+ if (form->currentStreamRangeLength != BlobDataItem::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength);
#endif
CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bytesToRead);
@@ -286,7 +287,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
*atEOF = FALSE;
form->bytesSent += bytesRead;
#if ENABLE(BLOB)
- if (form->currentStreamRangeLength != FormDataElement::toEndOfFile)
+ if (form->currentStreamRangeLength != BlobDataItem::toEndOfFile)
form->currentStreamRangeLength -= bytesRead;
#endif
@@ -394,6 +395,49 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
}
}
+#if ENABLE(BLOB)
+ // Check if there is a blob in the form data.
+ bool hasBlob = false;
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::encodedBlob) {
+ hasBlob = true;
+ break;
+ }
+ }
+
+ // If yes, we have to resolve all the blob references and regenerate the form data with only data and file types.
+ if (hasBlob) {
+ RefPtr<FormData> newFormData = FormData::create();
+ newFormData->setAlwaysStream(formData->alwaysStream());
+ newFormData->setIdentifier(formData->identifier());
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::data)
+ newFormData->appendData(element.m_data.data(), element.m_data.size());
+ else if (element.m_type == FormDataElement::encodedFile)
+ newFormData->appendFile(element.m_filename, element.m_shouldGenerateFile);
+ else {
+ ASSERT(element.m_type == FormDataElement::encodedBlob);
+ RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(KURL(ParsedURLString, element.m_blobURL));
+ if (blobData) {
+ for (size_t j = 0; j < blobData->items().size(); ++j) {
+ const BlobDataItem& blobItem = blobData->items()[j];
+ if (blobItem.type == BlobDataItem::Data) {
+ newFormData->appendData(blobItem.data.data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
+ } else {
+ ASSERT(blobItem.type == BlobDataItem::File);
+ newFormData->appendFileRange(blobItem.path, blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
+ }
+ }
+ }
+ }
+ }
+ formData = newFormData;
+ count = formData->elements().size();
+ }
+#endif
+
// Precompute the content length so NSURLConnection doesn't use chunked mode.
long long length = 0;
for (size_t i = 0; i < count; ++i) {
@@ -403,7 +447,7 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
else {
#if ENABLE(BLOB)
// If we're sending the file range, use the existing range length for now. We will detect if the file has been changed right before we read the file and abort the operation if necessary.
- if (element.m_fileLength != FormDataElement::toEndOfFile) {
+ if (element.m_fileLength != BlobDataItem::toEndOfFile) {
length += element.m_fileLength;
continue;
}