summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/network
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/network')
-rw-r--r--WebCore/platform/network/FormData.cpp124
-rw-r--r--WebCore/platform/network/FormData.h29
-rw-r--r--WebCore/platform/network/chromium/ResourceResponse.h8
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm21
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp6
5 files changed, 111 insertions, 77 deletions
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 918002a..431dbe4 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -19,23 +19,26 @@
*/
#include "config.h"
+
#include "FormData.h"
-#include "Blob.h"
+#include "BlobItem.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "DOMFormData.h"
#include "Document.h"
-#include "File.h"
#include "FileSystem.h"
#include "FormDataBuilder.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "TextEncoding.h"
-#include "UUID.h"
namespace WebCore {
+#if ENABLE(BLOB_SLICE)
+const long long FormDataElement::toEndOfFile = -1;
+const double FormDataElement::doNotCheckFileChange = 0;
+#endif
+
inline FormData::FormData()
: m_identifier(0)
, m_hasGeneratedFiles(false)
@@ -96,17 +99,17 @@ PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
return result.release();
}
-PassRefPtr<FormData> FormData::create(const DOMFormData& domFormData)
+PassRefPtr<FormData> FormData::create(const BlobItemList& items, const TextEncoding& encoding)
{
RefPtr<FormData> result = create();
- result->appendDOMFormData(domFormData, false, 0);
+ result->appendKeyValuePairItems(items, encoding, false, 0);
return result.release();
}
-PassRefPtr<FormData> FormData::createMultiPart(const DOMFormData& domFormData, Document* document)
+PassRefPtr<FormData> FormData::createMultiPart(const BlobItemList& items, const TextEncoding& encoding, Document* document)
{
RefPtr<FormData> result = create();
- result->appendDOMFormData(domFormData, true, document);
+ result->appendKeyValuePairItems(items, encoding, true, document);
return result.release();
}
@@ -154,12 +157,44 @@ void FormData::appendData(const void* data, size_t size)
void FormData::appendFile(const String& filename, bool shouldGenerateFile)
{
#if ENABLE(BLOB_SLICE)
- m_elements.append(FormDataElement(filename, 0, Blob::toEndOfFile, Blob::doNotCheckFileChange, shouldGenerateFile));
+ m_elements.append(FormDataElement(filename, 0, FormDataElement::toEndOfFile, FormDataElement::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_SLICE)
+ 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_SLICE)
void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile)
{
@@ -167,42 +202,30 @@ void FormData::appendFileRange(const String& filename, long long start, long lon
}
#endif
-void FormData::appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document)
+void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
{
FormDataBuilder formDataBuilder;
if (isMultiPartForm)
m_boundary = formDataBuilder.generateUniqueBoundaryString();
Vector<char> encodedData;
- TextEncoding encoding = domFormData.encoding();
- const Vector<FormDataList::Item>& list = domFormData.list();
- size_t formDataListSize = list.size();
+ size_t formDataListSize = items.size();
ASSERT(!(formDataListSize % 2));
for (size_t i = 0; i < formDataListSize; i += 2) {
- const FormDataList::Item& key = list[i];
- const FormDataList::Item& value = list[i + 1];
+ const StringBlobItem* key = items[i]->toStringBlobItem();
+ const BlobItem* value = items[i + 1].get();
+ ASSERT(key);
if (isMultiPartForm) {
Vector<char> header;
- formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key.data());
+ formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key->cstr());
bool shouldGenerateFile = false;
// If the current type is FILE, then we also need to include the filename
- if (value.blob()) {
- const String& path = value.blob()->path();
-#if ENABLE(BLOB_SLICE)
- String fileName;
- if (value.blob()->isFile())
- fileName = static_cast<File*>(value.blob())->fileName();
- else {
- // If a blob is sliced from a file, it does not have the filename. In this case, let's produce a unique filename.
- fileName = "Blob" + createCanonicalUUIDString();
- fileName.replace("-", ""); // For safty, remove '-' from the filename snce some servers may not like it.
- }
-#else
- ASSERT(value.blob()->isFile());
- String fileName = static_cast<File*>(value.blob())->fileName();
-#endif
+ const FileBlobItem* fileItem = value->toFileBlobItem();
+ if (fileItem) {
+ const String& path = fileItem->path();
+ String fileName = fileItem->name();
// Let the application specify a filename if it's going to generate a replacement file for the upload.
if (!path.isEmpty()) {
@@ -217,9 +240,9 @@ void FormData::appendDOMFormData(const DOMFormData& domFormData, bool isMultiPar
// We have to include the filename=".." part in the header, even if the filename is empty
formDataBuilder.addFilenameToMultiPartHeader(header, encoding, fileName);
- // If a blob is sliced from a file, do not add the content type.
+ // If the item is sliced from a file, do not add the content type.
#if ENABLE(BLOB_SLICE)
- if (!fileName.isEmpty() && value.blob()->isFile()) {
+ if (!fileName.isEmpty() && !value->toFileRangeBlobItem()) {
#else
if (!fileName.isEmpty()) {
#endif
@@ -237,25 +260,20 @@ void FormData::appendDOMFormData(const DOMFormData& domFormData, bool isMultiPar
// Append body
appendData(header.data(), header.size());
- if (size_t dataSize = value.data().length())
- appendData(value.data().data(), dataSize);
- else if (value.blob() && !value.blob()->path().isEmpty())
-#if ENABLE(BLOB_SLICE)
- appendFileRange(value.blob()->path(), value.blob()->start(), value.blob()->length(), value.blob()->modificationTime(), shouldGenerateFile);
-#else
- appendFile(value.blob()->path(), shouldGenerateFile);
-#endif
-
+ appendItem(value, shouldGenerateFile);
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?
- if (encodedData.isEmpty() && key.data() == "isindex")
- FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
+ const StringBlobItem* stringValue = value->toStringBlobItem();
+ if (!stringValue)
+ continue;
+ if (encodedData.isEmpty() && key->cstr() == "isindex")
+ FormDataBuilder::encodeStringAsFormData(encodedData, stringValue->cstr());
else
- formDataBuilder.addKeyValuePairAsFormData(encodedData, key.data(), value.data());
+ formDataBuilder.addKeyValuePairAsFormData(encodedData, key->cstr(), stringValue->cstr());
}
- }
+ }
if (isMultiPartForm)
formDataBuilder.addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);
@@ -270,12 +288,8 @@ void FormData::flatten(Vector<char>& data) const
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
const FormDataElement& e = m_elements[i];
- if (e.m_type == FormDataElement::data) {
- size_t oldSize = data.size();
- size_t delta = e.m_data.size();
- data.grow(oldSize + delta);
- memcpy(data.data() + oldSize, e.m_data.data(), delta);
- }
+ if (e.m_type == FormDataElement::data)
+ data.append(e.m_data.data(), static_cast<size_t>(e.m_data.size()));
}
}
@@ -289,10 +303,10 @@ String FormData::flattenToString() const
void FormData::generateFiles(Document* document)
{
ASSERT(!m_hasGeneratedFiles);
-
+
if (m_hasGeneratedFiles)
return;
-
+
Page* page = document->page();
if (!page)
return;
@@ -312,7 +326,7 @@ void FormData::removeGeneratedFilesIfNeeded()
{
if (!m_hasGeneratedFiles)
return;
-
+
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
FormDataElement& e = m_elements[i];
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index a439023..95eb258 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -26,13 +26,16 @@
namespace WebCore {
-class DOMFormData;
+class BlobItem;
class Document;
+class TextEncoding;
+typedef Vector<RefPtr<BlobItem> > BlobItemList;
class FormDataElement {
public:
FormDataElement() : m_type(data) { }
FormDataElement(const Vector<char>& array) : m_type(data), m_data(array) { }
+
#if ENABLE(BLOB_SLICE)
FormDataElement(const String& filename, long long fileStart, long long fileLength, double expectedFileModificationTime, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_fileStart(fileStart), m_fileLength(fileLength), m_expectedFileModificationTime(expectedFileModificationTime), m_shouldGenerateFile(shouldGenerateFile) { }
#else
@@ -49,13 +52,18 @@ public:
#endif
String m_generatedFilename;
bool m_shouldGenerateFile;
+
+#if ENABLE(BLOB_SLICE)
+ static const long long toEndOfFile;
+ static const double doNotCheckFileChange;
+#endif
};
inline bool operator==(const FormDataElement& a, const FormDataElement& b)
{
if (&a == &b)
return true;
-
+
if (a.m_type != b.m_type)
return false;
if (a.m_data != b.m_data)
@@ -69,25 +77,26 @@ inline bool operator==(const FormDataElement& a, const FormDataElement& b)
return true;
}
-
+
inline bool operator!=(const FormDataElement& a, const FormDataElement& b)
{
return !(a == b);
}
-
+
class FormData : public RefCounted<FormData> {
public:
static PassRefPtr<FormData> create();
static PassRefPtr<FormData> create(const void*, size_t);
static PassRefPtr<FormData> create(const WTF::CString&);
static PassRefPtr<FormData> create(const Vector<char>&);
- static PassRefPtr<FormData> create(const DOMFormData&);
- static PassRefPtr<FormData> createMultiPart(const DOMFormData&, Document*);
+ static PassRefPtr<FormData> create(const BlobItemList&, const TextEncoding&);
+ static PassRefPtr<FormData> createMultiPart(const BlobItemList&, 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);
#if ENABLE(BLOB_SLICE)
void appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile = false);
@@ -115,9 +124,11 @@ private:
FormData();
FormData(const FormData&);
- void appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document);
+ void appendItem(const BlobItem*, bool shouldGenerateFile);
+ void appendKeyValuePairItems(const BlobItemList&, const TextEncoding&, bool isMultiPartForm, Document*);
Vector<FormDataElement> m_elements;
+
int64_t m_identifier;
bool m_hasGeneratedFiles;
bool m_alwaysStream;
@@ -131,7 +142,7 @@ inline bool operator==(const FormData& a, const FormData& b)
inline bool operator!=(const FormData& a, const FormData& b)
{
- return a.elements() != b.elements();
+ return !(a == b);
}
} // namespace WebCore
diff --git a/WebCore/platform/network/chromium/ResourceResponse.h b/WebCore/platform/network/chromium/ResourceResponse.h
index 8400ce5..f80bf42 100644
--- a/WebCore/platform/network/chromium/ResourceResponse.h
+++ b/WebCore/platform/network/chromium/ResourceResponse.h
@@ -41,6 +41,7 @@ namespace WebCore {
, m_isMultipartPayload(false)
, m_wasFetchedViaSPDY(false)
, m_wasNpnNegotiated(false)
+ , m_wasFetchedViaProxy(false)
, m_responseTime(0)
{
}
@@ -52,6 +53,7 @@ namespace WebCore {
, m_isMultipartPayload(false)
, m_wasFetchedViaSPDY(false)
, m_wasNpnNegotiated(false)
+ , m_wasFetchedViaProxy(false)
, m_responseTime(0)
{
}
@@ -74,6 +76,9 @@ namespace WebCore {
bool wasNpnNegotiated() const { return m_wasNpnNegotiated; }
void setWasNpnNegotiated(bool value) { m_wasNpnNegotiated = value; }
+ bool wasFetchedViaProxy() const { return m_wasFetchedViaProxy; }
+ void setWasFetchedViaProxy(bool value) { m_wasFetchedViaProxy = value; }
+
bool isMultipartPayload() const { return m_isMultipartPayload; }
void setIsMultipartPayload(bool value) { m_isMultipartPayload = value; }
@@ -114,6 +119,9 @@ namespace WebCore {
// Was the resource fetched over a channel which used TLS/Next-Protocol-Negotiation (also SPDY related).
bool m_wasNpnNegotiated;
+ // Was the resource fetched over an explicit proxy (HTTP, SOCKS, etc).
+ bool m_wasFetchedViaProxy;
+
// The time at which the response headers were received. For cached
// responses, this time could be "far" in the past.
double m_responseTime;
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index 27ecfd0..db2e13b 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -31,7 +31,6 @@
#import "config.h"
#import "FormDataStreamMac.h"
-#import "Blob.h"
#import "FileSystem.h"
#import "FormData.h"
#import "ResourceHandle.h"
@@ -142,7 +141,7 @@ static void closeCurrentStream(FormStreamFields *form)
CFRelease(form->currentStream);
form->currentStream = NULL;
#if ENABLE(BLOB_SLICE)
- form->currentStreamRangeLength = Blob::toEndOfFile;
+ form->currentStreamRangeLength = FormDataElement::toEndOfFile;
#endif
}
if (form->currentData) {
@@ -151,7 +150,7 @@ static void closeCurrentStream(FormStreamFields *form)
}
}
-// Return false if we cannot advance the stream. Currently the only possible failure is that the underlying file has been changed since File.slice.
+// Return false if we cannot advance the stream. Currently the only possible failure is that the underlying file has been removed or changed since File.slice.
static bool advanceCurrentStream(FormStreamFields* form)
{
closeCurrentStream(form);
@@ -161,6 +160,7 @@ static bool advanceCurrentStream(FormStreamFields* form)
// Create the new stream.
FormDataElement& nextInput = form->remainingElements.last();
+
if (nextInput.m_type == FormDataElement::data) {
size_t size = nextInput.m_data.size();
char* data = nextInput.m_data.releaseBuffer();
@@ -169,17 +169,20 @@ static bool advanceCurrentStream(FormStreamFields* form)
} else {
#if ENABLE(BLOB_SLICE)
// Check if the file has been changed or not if required.
- if (nextInput.m_expectedFileModificationTime != Blob::doNotCheckFileChange) {
+ if (nextInput.m_expectedFileModificationTime != FormDataElement::doNotCheckFileChange) {
time_t fileModificationTime;
if (!getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime))
return false;
}
#endif
-
const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString());
RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, filename.get(), kCFURLPOSIXPathStyle, FALSE));
form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get());
+ if (!form->currentStream) {
+ // The file must have been removed or become unreadable.
+ return false;
+ }
#if ENABLE(BLOB_SLICE)
if (nextInput.m_fileStart > 0) {
CFNumberRef position = CFNumberCreate(0, kCFNumberLongLongType, &nextInput.m_fileStart);
@@ -222,7 +225,7 @@ static void* formCreate(CFReadStreamRef stream, void* context)
FormStreamFields* newInfo = new FormStreamFields;
newInfo->currentStream = NULL;
#if ENABLE(BLOB_SLICE)
- newInfo->currentStreamRangeLength = Blob::toEndOfFile;
+ newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile;
#endif
newInfo->currentData = 0;
newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
@@ -270,7 +273,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
while (form->currentStream) {
CFIndex bytesToRead = bufferLength;
#if ENABLE(BLOB_SLICE)
- if (form->currentStreamRangeLength != Blob::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
+ if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength);
#endif
CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bytesToRead);
@@ -283,7 +286,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
*atEOF = FALSE;
form->bytesSent += bytesRead;
#if ENABLE(BLOB_SLICE)
- if (form->currentStreamRangeLength != Blob::toEndOfFile)
+ if (form->currentStreamRangeLength != FormDataElement::toEndOfFile)
form->currentStreamRangeLength -= bytesRead;
#endif
@@ -400,7 +403,7 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
else {
#if ENABLE(BLOB_SLICE)
// 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 != Blob::toEndOfFile) {
+ if (element.m_fileLength != FormDataElement::toEndOfFile) {
length += element.m_fileLength;
continue;
}
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 90a842e..e2c67bc 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -533,10 +533,8 @@ static bool startHttp(ResourceHandle* handle)
* libsoup's simple-httpd test
*/
GError* error = 0;
- gchar* fileName = filenameFromString(element.m_filename);
- GMappedFile* fileMapping = g_mapped_file_new(fileName, false, &error);
-
- g_free(fileName);
+ CString fileName = fileSystemRepresentation(element.m_filename);
+ GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error);
if (error) {
g_error_free(error);