Diff
Modified: trunk/Source/WebCore/ChangeLog (236364 => 236365)
--- trunk/Source/WebCore/ChangeLog 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/ChangeLog 2018-09-21 22:50:36 UTC (rev 236365)
@@ -1,3 +1,48 @@
+2018-09-21 Alex Christensen <[email protected]>
+
+ Use a Variant for FormDataElement
+ https://bugs.webkit.org/show_bug.cgi?id=189777
+
+ Reviewed by Chris Dumez.
+
+ * platform/network/FormData.cpp:
+ (WebCore::FormData::FormData):
+ (WebCore::FormDataElement::lengthInBytes const):
+ (WebCore::FormDataElement::isolatedCopy const):
+ (WebCore::FormData::appendData):
+ (WebCore::FormData::flatten const):
+ (WebCore::FormData::resolveBlobReferences):
+ (WebCore::FormData::generateFiles):
+ (WebCore::FormData::hasGeneratedFiles const):
+ (WebCore::FormData::hasOwnedGeneratedFiles const):
+ (WebCore::FormData::removeGeneratedFilesIfNeeded):
+ (WebCore::FormData::asSharedBuffer const):
+ (WebCore::FormData::asBlobURL const):
+ (WebCore::FormData::expandDataStore): Deleted.
+ * platform/network/FormData.h:
+ (WebCore::FormDataElement::FormDataElement):
+ (WebCore::FormDataElement::encode const):
+ (WebCore::FormDataElement::decode):
+ (WebCore::FormDataElement::EncodedFileData::isolatedCopy const):
+ (WebCore::FormDataElement::EncodedFileData::operator== const):
+ (WebCore::FormDataElement::EncodedFileData::encode const):
+ (WebCore::FormDataElement::EncodedFileData::decode):
+ (WebCore::FormDataElement::EncodedBlobData::operator== const):
+ (WebCore::FormDataElement::EncodedBlobData::encode const):
+ (WebCore::FormDataElement::EncodedBlobData::decode):
+ (WebCore::FormDataElement::operator== const):
+ (WebCore::FormDataElement::operator!= const):
+ * platform/network/cf/FormDataStreamCFNet.cpp:
+ (WebCore::advanceCurrentStream):
+ (WebCore::createHTTPBodyCFReadStream):
+ (WebCore::setHTTPBody):
+ * platform/network/curl/CurlFormDataStream.cpp:
+ (WebCore::CurlFormDataStream::computeContentLength):
+ (WebCore::CurlFormDataStream::read):
+ (WebCore::CurlFormDataStream::readFromFile):
+ (WebCore::CurlFormDataStream::readFromData):
+ * platform/network/curl/CurlFormDataStream.h:
+
2018-09-20 Simon Fraser <[email protected]>
Simplify the logic around has*ScrollbarWithAutoBehavior
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (236364 => 236365)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -1484,7 +1484,7 @@
// 2. End the synchronous section, continuing the remaining steps in parallel.
// 3. Run the resource fetch algorithm with the assigned media provider object.
- WTF::visit(WTF::makeVisitor(
+ switchOn(m_mediaProvider.value(),
#if ENABLE(MEDIA_STREAM)
[this](RefPtr<MediaStream> stream) { m_mediaStreamSrcObject = stream; },
#endif
@@ -1492,7 +1492,7 @@
[this](RefPtr<MediaSource> source) { m_mediaSource = source; },
#endif
[this](RefPtr<Blob> blob) { m_blob = blob; }
- ), m_mediaProvider.value());
+ );
ContentType contentType;
loadResource(URL(), contentType, String());
Modified: trunk/Source/WebCore/platform/network/FormData.cpp (236364 => 236365)
--- trunk/Source/WebCore/platform/network/FormData.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/FormData.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -53,9 +53,9 @@
// We shouldn't be copying FormData that hasn't already removed its generated files
// but just in case, make sure the new FormData is ready to generate its own files.
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedFile) {
- element.m_generatedFilename = String();
- element.m_ownsGeneratedFile = false;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ fileData->generatedFilename = { };
+ fileData->ownsGeneratedFile = false;
}
}
}
@@ -90,6 +90,13 @@
return create(vector.data(), vector.size());
}
+Ref<FormData> FormData::create(Vector<char>&& vector)
+{
+ auto data = ""
+ data->m_elements.append(WTFMove(vector));
+ return data;
+}
+
Ref<FormData> FormData::create(const Vector<uint8_t>& vector)
{
return create(vector.data(), vector.size());
@@ -132,41 +139,49 @@
uint64_t FormDataElement::lengthInBytes() const
{
- switch (m_type) {
- case Type::Data:
- return m_data.size();
- case Type::EncodedFile: {
- if (m_fileLength != BlobDataItem::toEndOfFile)
- return m_fileLength;
- long long fileSize;
- if (FileSystem::getFileSize(m_shouldGenerateFile ? m_generatedFilename : m_filename, fileSize))
- return fileSize;
- return 0;
- }
- case Type::EncodedBlob:
- return ThreadableBlobRegistry::blobSize(m_url);
- }
- ASSERT_NOT_REACHED();
- return 0;
+ return switchOn(data,
+ [] (const Vector<char>& bytes) {
+ return static_cast<uint64_t>(bytes.size());
+ }, [] (const FormDataElement::EncodedFileData& fileData) {
+ if (fileData.fileLength != BlobDataItem::toEndOfFile)
+ return static_cast<uint64_t>(fileData.fileLength);
+ long long fileSize;
+ if (FileSystem::getFileSize(fileData.shouldGenerateFile ? fileData.generatedFilename : fileData.filename, fileSize))
+ return static_cast<uint64_t>(fileSize);
+ return static_cast<uint64_t>(0);
+ }, [] (const FormDataElement::EncodedBlobData& blobData) {
+ return ThreadableBlobRegistry::blobSize(blobData.url);
+ }
+ );
}
FormDataElement FormDataElement::isolatedCopy() const
{
- switch (m_type) {
- case Type::Data:
- return FormDataElement(m_data);
- case Type::EncodedFile:
- return FormDataElement(m_filename.isolatedCopy(), m_fileStart, m_fileLength, m_expectedFileModificationTime, m_shouldGenerateFile);
- case Type::EncodedBlob:
- return FormDataElement(m_url.isolatedCopy());
- }
-
- RELEASE_ASSERT_NOT_REACHED();
+ return switchOn(data,
+ [] (const Vector<char>& bytes) {
+ Vector<char> copy;
+ copy.append(bytes.data(), bytes.size());
+ return FormDataElement(WTFMove(copy));
+ }, [] (const FormDataElement::EncodedFileData& fileData) {
+ return FormDataElement(fileData.isolatedCopy());
+ }, [] (const FormDataElement::EncodedBlobData& blobData) {
+ return FormDataElement(blobData.url.isolatedCopy());
+ }
+ );
}
void FormData::appendData(const void* data, size_t size)
{
- memcpy(expandDataStore(size), data, size);
+ m_lengthInBytes = std::nullopt;
+ if (!m_elements.isEmpty()) {
+ if (auto* vector = WTF::get_if<Vector<char>>(m_elements.last().data)) {
+ vector->append(reinterpret_cast<const char*>(data), size);
+ return;
+ }
+ }
+ Vector<char> vector;
+ vector.append(reinterpret_cast<const char*>(data), size);
+ m_elements.append(WTFMove(vector));
}
void FormData::appendFile(const String& filename, bool shouldGenerateFile)
@@ -279,28 +294,13 @@
appendData(encodedData.data(), encodedData.size());
}
-char* FormData::expandDataStore(size_t size)
-{
- m_lengthInBytes = std::nullopt;
- if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::Type::Data)
- m_elements.append({ });
-
- auto& lastElement = m_elements.last();
- size_t oldSize = lastElement.m_data.size();
-
- auto newSize = Checked<size_t>(oldSize) + size;
-
- lastElement.m_data.grow(newSize.unsafeGet());
- return lastElement.m_data.data() + oldSize;
-}
-
Vector<char> FormData::flatten() const
{
// Concatenate all the byte arrays, but omit any files.
Vector<char> data;
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::Data)
- data.append(element.m_data.data(), static_cast<size_t>(element.m_data.size()));
+ if (auto* vector = WTF::get_if<Vector<char>>(element.data))
+ data.append(vector->data(), vector->size());
}
return data;
}
@@ -340,7 +340,7 @@
// First check if any blobs needs to be resolved, or we can take the fast path.
bool hasBlob = false;
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedBlob) {
+ if (WTF::holds_alternative<FormDataElement::EncodedBlobData>(element.data)) {
hasBlob = true;
break;
}
@@ -355,14 +355,15 @@
newFormData->setIdentifier(identifier());
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::Data)
- newFormData->appendData(element.m_data.data(), element.m_data.size());
- else if (element.m_type == FormDataElement::Type::EncodedFile)
- newFormData->appendFileRange(element.m_filename, element.m_fileStart, element.m_fileLength, element.m_expectedFileModificationTime, element.m_shouldGenerateFile);
- else if (element.m_type == FormDataElement::Type::EncodedBlob)
- appendBlobResolved(newFormData.ptr(), element.m_url);
- else
- ASSERT_NOT_REACHED();
+ switchOn(element.data,
+ [&] (const Vector<char>& bytes) {
+ newFormData->appendData(bytes.data(), bytes.size());
+ }, [&] (const FormDataElement::EncodedFileData& fileData) {
+ newFormData->appendFileRange(fileData.filename, fileData.fileStart, fileData.fileLength, fileData.expectedFileModificationTime, fileData.shouldGenerateFile);
+ }, [&] (const FormDataElement::EncodedBlobData& blobData) {
+ appendBlobResolved(newFormData.ptr(), blobData.url);
+ }
+ );
}
return newFormData;
}
@@ -374,14 +375,16 @@
return;
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedFile && element.m_shouldGenerateFile) {
- ASSERT(!element.m_ownsGeneratedFile);
- ASSERT(element.m_generatedFilename.isEmpty());
- if (!element.m_generatedFilename.isEmpty())
- continue;
- element.m_generatedFilename = page->chrome().client().generateReplacementFile(element.m_filename);
- if (!element.m_generatedFilename.isEmpty())
- element.m_ownsGeneratedFile = true;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ if (fileData->shouldGenerateFile) {
+ ASSERT(!fileData->ownsGeneratedFile);
+ ASSERT(fileData->generatedFilename.isEmpty());
+ if (!fileData->generatedFilename.isEmpty())
+ continue;
+ fileData->generatedFilename = page->chrome().client().generateReplacementFile(fileData->filename);
+ if (!fileData->generatedFilename.isEmpty())
+ fileData->ownsGeneratedFile = true;
+ }
}
}
}
@@ -389,8 +392,10 @@
bool FormData::hasGeneratedFiles() const
{
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedFile && !element.m_generatedFilename.isEmpty())
- return true;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ if (!fileData->generatedFilename.isEmpty())
+ return true;
+ }
}
return false;
}
@@ -398,9 +403,11 @@
bool FormData::hasOwnedGeneratedFiles() const
{
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedFile && element.m_ownsGeneratedFile) {
- ASSERT(!element.m_generatedFilename.isEmpty());
- return true;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ if (fileData->ownsGeneratedFile) {
+ ASSERT(!fileData->generatedFilename.isEmpty());
+ return true;
+ }
}
}
return false;
@@ -409,14 +416,16 @@
void FormData::removeGeneratedFilesIfNeeded()
{
for (auto& element : m_elements) {
- if (element.m_type == FormDataElement::Type::EncodedFile && element.m_ownsGeneratedFile) {
- ASSERT(!element.m_generatedFilename.isEmpty());
- ASSERT(element.m_shouldGenerateFile);
- String directory = FileSystem::directoryName(element.m_generatedFilename);
- FileSystem::deleteFile(element.m_generatedFilename);
- FileSystem::deleteEmptyDirectory(directory);
- element.m_generatedFilename = String();
- element.m_ownsGeneratedFile = false;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ if (fileData->ownsGeneratedFile) {
+ ASSERT(!fileData->generatedFilename.isEmpty());
+ ASSERT(fileData->shouldGenerateFile);
+ String directory = FileSystem::directoryName(fileData->generatedFilename);
+ FileSystem::deleteFile(fileData->generatedFilename);
+ FileSystem::deleteEmptyDirectory(directory);
+ fileData->generatedFilename = String();
+ fileData->ownsGeneratedFile = false;
+ }
}
}
}
@@ -435,7 +444,7 @@
RefPtr<SharedBuffer> FormData::asSharedBuffer() const
{
for (auto& element : m_elements) {
- if (element.m_type != FormDataElement::Type::Data)
+ if (!WTF::holds_alternative<Vector<char>>(element.data))
return nullptr;
}
return SharedBuffer::create(flatten());
@@ -446,8 +455,9 @@
if (m_elements.size() != 1)
return { };
- ASSERT(m_elements.first().m_type == FormDataElement::Type::EncodedBlob || m_elements.first().m_url.isNull());
- return m_elements.first().m_url;
+ if (auto* blobData = WTF::get_if<FormDataElement::EncodedBlobData>(m_elements.first().data))
+ return blobData->url;
+ return { };
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/FormData.h (236364 => 236365)
--- trunk/Source/WebCore/platform/network/FormData.h 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/FormData.h 2018-09-21 22:50:36 UTC (rev 236365)
@@ -23,6 +23,7 @@
#include "URL.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include <wtf/Variant.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -34,158 +35,159 @@
class SharedBuffer;
class TextEncoding;
-// FIXME: Convert this to a Variant of structs and remove "Type" and also the "m_" prefixes from the data members.
-// The member functions can become non-member fucntions.
-class FormDataElement {
-public:
- enum class Type { Data, EncodedFile, EncodedBlob };
+struct FormDataElement {
+ struct EncodedFileData;
+ struct EncodedBlobData;
+ using Data = "" EncodedFileData, EncodedBlobData>;
- FormDataElement()
- : m_type(Type::Data)
- {
- }
-
- explicit FormDataElement(const Vector<char>& array)
- : m_type(Type::Data)
- , m_data(array)
- {
- }
-
- FormDataElement(const String& filename, long long fileStart, long long fileLength, double expectedFileModificationTime, bool shouldGenerateFile)
- : m_type(Type::EncodedFile)
- , m_filename(filename)
- , m_fileStart(fileStart)
- , m_fileLength(fileLength)
- , m_expectedFileModificationTime(expectedFileModificationTime)
- , m_shouldGenerateFile(shouldGenerateFile)
- , m_ownsGeneratedFile(false)
- {
- }
-
+ FormDataElement() = default;
+ explicit FormDataElement(Data&& data)
+ : data(WTFMove(data)) { }
+ explicit FormDataElement(Vector<char>&& array)
+ : data(WTFMove(array)) { }
+ FormDataElement(const String& filename, int64_t fileStart, int64_t fileLength, double expectedFileModificationTime, bool shouldGenerateFile)
+ : data(EncodedFileData { filename, fileStart, fileLength, expectedFileModificationTime, { }, shouldGenerateFile, false }) { }
explicit FormDataElement(const URL& blobURL)
- : m_type(Type::EncodedBlob)
- , m_url(blobURL)
- {
- }
+ : data(EncodedBlobData { blobURL }) { }
uint64_t lengthInBytes() const;
FormDataElement isolatedCopy() const;
- template<typename Encoder> void encode(Encoder&) const;
- template<typename Decoder> static std::optional<FormDataElement> decode(Decoder&);
-
- Type m_type;
- Vector<char> m_data;
- String m_filename;
- URL m_url; // For Blob or URL.
- int64_t m_fileStart;
- int64_t m_fileLength;
- double m_expectedFileModificationTime;
- // FIXME: Generated file support in FormData is almost identical to Blob, they should be merged.
- // We can't just switch to using Blobs for all files because EncodedFile form data elements do not
- // have a valid m_expectedFileModificationTime, meaning we always upload the latest content from disk.
- String m_generatedFilename;
- bool m_shouldGenerateFile;
- bool m_ownsGeneratedFile;
-};
-
-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_type == FormDataElement::Type::Data)
- return a.m_data == b.m_data;
- if (a.m_type == FormDataElement::Type::EncodedFile)
- return a.m_filename == b.m_filename && a.m_fileStart == b.m_fileStart && a.m_fileLength == b.m_fileLength && a.m_expectedFileModificationTime == b.m_expectedFileModificationTime;
- if (a.m_type == FormDataElement::Type::EncodedBlob)
- return a.m_url == b.m_url;
-
- return true;
-}
-
-inline bool operator!=(const FormDataElement& a, const FormDataElement& b)
-{
- return !(a == b);
-}
-
-template<typename Encoder>
-void FormDataElement::encode(Encoder& encoder) const
-{
- encoder.encodeEnum(m_type);
-
- switch (m_type) {
- case Type::Data:
- encoder << m_data;
- break;
-
- case Type::EncodedFile:
- encoder << m_filename;
- encoder << m_generatedFilename;
- encoder << m_shouldGenerateFile;
- encoder << m_fileStart;
- encoder << m_fileLength;
- encoder << m_expectedFileModificationTime;
- break;
-
- case Type::EncodedBlob:
- encoder << m_url.string();
- break;
+ template<typename Encoder> void encode(Encoder& encoder) const
+ {
+ encoder << data;
}
-}
-
-template<typename Decoder>
-std::optional<FormDataElement> FormDataElement::decode(Decoder& decoder)
-{
- FormDataElement result;
- if (!decoder.decodeEnum(result.m_type))
- return std::nullopt;
-
- switch (result.m_type) {
- case Type::Data:
- if (!decoder.decode(result.m_data))
+ template<typename Decoder> static std::optional<FormDataElement> decode(Decoder& decoder)
+ {
+ std::optional<Data> data;
+ decoder >> data;
+ if (!data)
return std::nullopt;
+ return FormDataElement(WTFMove(*data));
+ }
- return WTFMove(result);
+ struct EncodedFileData {
+ String filename;
+ int64_t fileStart { 0 };
+ int64_t fileLength { 0 };
+ double expectedFileModificationTime { 0 };
+ String generatedFilename;
+ bool shouldGenerateFile { false };
+ bool ownsGeneratedFile { false };
- case Type::EncodedFile:
- if (!decoder.decode(result.m_filename))
- return std::nullopt;
- if (!decoder.decode(result.m_generatedFilename))
- return std::nullopt;
- if (!decoder.decode(result.m_shouldGenerateFile))
- return std::nullopt;
- result.m_ownsGeneratedFile = false;
- if (!decoder.decode(result.m_fileStart))
- return std::nullopt;
- if (!decoder.decode(result.m_fileLength))
- return std::nullopt;
+ // FIXME: Generated file support in FormData is almost identical to Blob, they should be merged.
+ // We can't just switch to using Blobs for all files because EncodedFile form data elements do not
+ // have a valid expectedFileModificationTime, meaning we always upload the latest content from disk.
- if (result.m_fileLength != BlobDataItem::toEndOfFile && result.m_fileLength < result.m_fileStart)
- return std::nullopt;
+ EncodedFileData isolatedCopy() const
+ {
+ return { filename.isolatedCopy(), fileStart, fileLength, expectedFileModificationTime, generatedFilename.isolatedCopy(), shouldGenerateFile, ownsGeneratedFile };
+ }
+
+ bool operator==(const EncodedFileData other) const
+ {
+ return filename == other.filename
+ && fileStart == other.fileStart
+ && fileLength == other.fileLength
+ && expectedFileModificationTime == other.expectedFileModificationTime
+ && generatedFilename == other.generatedFilename
+ && shouldGenerateFile == other.shouldGenerateFile
+ && ownsGeneratedFile == other.ownsGeneratedFile;
+ }
+ template<typename Encoder> void encode(Encoder& encoder) const
+ {
+ encoder << filename << fileStart << fileLength << expectedFileModificationTime << generatedFilename << shouldGenerateFile;
+ }
+ template<typename Decoder> static std::optional<EncodedFileData> decode(Decoder& decoder)
+ {
+ std::optional<String> filename;
+ decoder >> filename;
+ if (!filename)
+ return std::nullopt;
+
+ std::optional<int64_t> fileStart;
+ decoder >> fileStart;
+ if (!fileStart)
+ return std::nullopt;
+
+ std::optional<int64_t> fileLength;
+ decoder >> fileLength;
+ if (!fileLength)
+ return std::nullopt;
+
+ std::optional<double> expectedFileModificationTime;
+ decoder >> expectedFileModificationTime;
+ if (!expectedFileModificationTime)
+ return std::nullopt;
+
+ std::optional<String> generatedFilename;
+ decoder >> generatedFilename;
+ if (!generatedFilename)
+ return std::nullopt;
- if (!decoder.decode(result.m_expectedFileModificationTime))
- return std::nullopt;
+ std::optional<bool> shouldGenerateFile;
+ decoder >> shouldGenerateFile;
+ if (!shouldGenerateFile)
+ return std::nullopt;
- return WTFMove(result);
+ bool ownsGeneratedFile = false;
+
+ return {{
+ WTFMove(*filename),
+ WTFMove(*fileStart),
+ WTFMove(*fileLength),
+ WTFMove(*expectedFileModificationTime),
+ WTFMove(*generatedFilename),
+ WTFMove(*shouldGenerateFile),
+ WTFMove(ownsGeneratedFile)
+ }};
+ }
- case Type::EncodedBlob: {
- String blobURLString;
- if (!decoder.decode(blobURLString))
- return std::nullopt;
+ };
+
+ struct EncodedBlobData {
+ URL url;
- result.m_url = URL(URL(), blobURLString);
+ bool operator==(const EncodedBlobData other) const
+ {
+ return url == other.url;
+ }
+ template<typename Encoder> void encode(Encoder& encoder) const
+ {
+ encoder << url;
+ }
+ template<typename Decoder> static std::optional<EncodedBlobData> decode(Decoder& decoder)
+ {
+ std::optional<URL> url;
+ decoder >> url;
+ if (!url)
+ return std::nullopt;
- return WTFMove(result);
+ return {{ WTFMove(*url) }};
+ }
+ };
+
+ bool operator==(const FormDataElement& other) const
+ {
+ if (&other == this)
+ return true;
+ if (data.index() != other.data.index())
+ return false;
+ if (!data.index())
+ return WTF::get<0>(data) == WTF::get<0>(other.data);
+ if (data.index() == 1)
+ return WTF::get<1>(data) == WTF::get<1>(other.data);
+ return WTF::get<2>(data) == WTF::get<2>(other.data);
}
+ bool operator!=(const FormDataElement& other) const
+ {
+ return !(*this == other);
}
+
+ Data data;
+};
- return std::nullopt;
-}
-
class FormData : public RefCounted<FormData> {
public:
enum EncodingType {
@@ -197,6 +199,7 @@
WEBCORE_EXPORT static Ref<FormData> create();
WEBCORE_EXPORT static Ref<FormData> create(const void*, size_t);
static Ref<FormData> create(const CString&);
+ static Ref<FormData> create(Vector<char>&&);
static Ref<FormData> create(const Vector<char>&);
static Ref<FormData> create(const Vector<uint8_t>&);
static Ref<FormData> create(const DOMFormData&, EncodingType = FormURLEncoded);
@@ -217,7 +220,6 @@
void appendFile(const String& filePath, bool shouldGenerateFile = false);
WEBCORE_EXPORT void appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile = false);
WEBCORE_EXPORT void appendBlob(const URL& blobURL);
- char* expandDataStore(size_t);
Vector<char> flatten() const; // omits files
String flattenToString() const; // omits files
Modified: trunk/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp (236364 => 236365)
--- trunk/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -136,30 +136,41 @@
// Create the new stream.
FormDataElement& nextInput = form->remainingElements.last();
- if (nextInput.m_type == FormDataElement::Type::Data) {
- size_t size = nextInput.m_data.size();
- MallocPtr<char> data = ""
- form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data.get()), size, kCFAllocatorNull);
- form->currentData = WTFMove(data);
- } else {
- // Check if the file has been changed or not if required.
- if (FileSystem::isValidFileTime(nextInput.m_expectedFileModificationTime)) {
- time_t fileModificationTime;
- if (!FileSystem::getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime))
+ bool success = switchOn(nextInput.data,
+ [form] (Vector<char>& bytes) {
+ size_t size = bytes.size();
+ MallocPtr<char> data = ""
+ form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data.get()), size, kCFAllocatorNull);
+ form->currentData = WTFMove(data);
+ return true;
+ }, [form] (const FormDataElement::EncodedFileData& fileData) {
+ // Check if the file has been changed or not if required.
+ if (FileSystem::isValidFileTime(fileData.expectedFileModificationTime)) {
+ time_t fileModificationTime;
+ if (!FileSystem::getFileModificationTime(fileData.filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(fileData.expectedFileModificationTime))
+ return false;
+ }
+ const String& path = fileData.shouldGenerateFile ? fileData.generatedFilename : fileData.filename;
+ form->currentStream = CFReadStreamCreateWithFile(0, FileSystem::pathAsURL(path).get());
+ if (!form->currentStream) {
+ // The file must have been removed or become unreadable.
return false;
- }
- const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
- form->currentStream = CFReadStreamCreateWithFile(0, FileSystem::pathAsURL(path).get());
- if (!form->currentStream) {
- // The file must have been removed or become unreadable.
+ }
+ if (fileData.fileStart > 0) {
+ RetainPtr<CFNumberRef> position = adoptCF(CFNumberCreate(0, kCFNumberLongLongType, &fileData.fileStart));
+ CFReadStreamSetProperty(form->currentStream, kCFStreamPropertyFileCurrentOffset, position.get());
+ }
+ form->currentStreamRangeLength = fileData.fileLength;
+ return true;
+ }, [] (const FormDataElement::EncodedBlobData&) {
+ ASSERT_NOT_REACHED();
return false;
}
- if (nextInput.m_fileStart > 0) {
- RetainPtr<CFNumberRef> position = adoptCF(CFNumberCreate(0, kCFNumberLongLongType, &nextInput.m_fileStart));
- CFReadStreamSetProperty(form->currentStream, kCFStreamPropertyFileCurrentOffset, position.get());
- }
- form->currentStreamRangeLength = nextInput.m_fileLength;
- }
+ );
+
+ if (!success)
+ return false;
+
form->remainingElements.removeLast();
// Set up the callback.
@@ -363,23 +374,9 @@
// Precompute the content length so CFNetwork doesn't use chunked mode.
unsigned long long length = 0;
+ for (auto& element : resolvedFormData->elements())
+ length += element.lengthInBytes();
- for (auto& element : resolvedFormData->elements()) {
- if (element.m_type == FormDataElement::Type::Data)
- length += element.m_data.size();
- else {
- // 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 != BlobDataItem::toEndOfFile) {
- length += element.m_fileLength;
- continue;
- }
- long long fileSize;
- if (FileSystem::getFileSize(element.m_shouldGenerateFile ? element.m_generatedFilename : element.m_filename, fileSize))
- length += fileSize;
- }
- }
-
FormCreationContext formContext = { WTFMove(resolvedFormData), length };
CFReadStreamCallBacksV1 callBacks = { 1, formCreate, formFinalize, nullptr, formOpen, nullptr, formRead, nullptr, formCanRead, formClose, formCopyProperty, nullptr, nullptr, formSchedule, formUnschedule };
return adoptCF(CFReadStreamCreate(nullptr, static_cast<const void*>(&callBacks), &formContext));
@@ -393,10 +390,8 @@
// Handle the common special case of one piece of form data, with no files.
auto& elements = formData->elements();
if (elements.size() == 1 && !formData->alwaysStream()) {
- auto& element = elements[0];
- if (element.m_type == FormDataElement::Type::Data) {
- auto& vector = element.m_data;
- auto data = "" reinterpret_cast<const UInt8*>(vector.data()), vector.size()));
+ if (auto* vector = WTF::get_if<Vector<char>>(elements[0].data)) {
+ auto data = "" reinterpret_cast<const UInt8*>(vector->data()), vector->size()));
CFURLRequestSetHTTPRequestBody(request, data.get());
return;
}
@@ -408,7 +403,7 @@
FormData* httpBodyFromStream(CFReadStreamRef stream)
{
if (!stream)
- return 0;
+ return nullptr;
// Passing the pointer as property appears to be the only way to associate a stream with FormData.
// A new stream is always created in CFURLRequestCopyHTTPRequestBodyStream (or -[NSURLRequest HTTPBodyStream]),
@@ -417,11 +412,11 @@
RetainPtr<CFNumberRef> formDataPointerAsCFNumber = adoptCF(static_cast<CFNumberRef>(CFReadStreamCopyProperty(stream, formDataPointerPropertyName)));
if (!formDataPointerAsCFNumber)
- return 0;
+ return nullptr;
long formDataPointerAsNumber;
if (!CFNumberGetValue(formDataPointerAsCFNumber.get(), kCFNumberLongType, &formDataPointerAsNumber))
- return 0;
+ return nullptr;
return reinterpret_cast<FormData*>(static_cast<intptr_t>(formDataPointerAsNumber));
}
Modified: trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.cpp (236364 => 236365)
--- trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -103,21 +103,8 @@
m_isContentLengthUpdated = true;
- for (const auto& element : m_formData->elements()) {
- if (element.m_type == FormDataElement::Type::EncodedFile) {
- long long fileSize;
- if (FileSystem::getFileSize(element.m_filename, fileSize)) {
- if (fileSize > maxCurlOffT) {
- // File size is too big for specifying it to curl
- m_shouldUseChunkTransfer = true;
- }
-
- m_totalSize += fileSize;
- } else
- m_shouldUseChunkTransfer = true;
- } else
- m_totalSize += element.m_data.size();
- }
+ for (const auto& element : m_formData->elements())
+ m_totalSize += element.lengthInBytes();
}
std::optional<size_t> CurlFormDataStream::read(char* buffer, size_t size)
@@ -134,14 +121,19 @@
while ((m_elementPosition < totalElementSize) && (totalReadBytes < size)) {
const auto& element = m_formData->elements().at(m_elementPosition);
- std::optional<size_t> readBytes;
size_t bufferSize = size - totalReadBytes;
char* bufferPosition = buffer + totalReadBytes;
- if (element.m_type == FormDataElement::Type::EncodedFile)
- readBytes = readFromFile(element, bufferPosition, bufferSize);
- else
- readBytes = readFromData(element, bufferPosition, bufferSize);
+ std::optional<size_t> readBytes = switchOn(element.data,
+ [&] (const Vector<char>& bytes) {
+ return readFromData(bytes, bufferPosition, bufferSize);
+ }, [&] (const FormDataElement::EncodedFileData& fileData) {
+ return readFromFile(fileData, bufferPosition, bufferSize);
+ }, [] (const FormDataElement::EncodedBlobData& blobData) {
+ ASSERT_NOT_REACHED();
+ return std::nullopt;
+ }
+ );
if (!readBytes)
return std::nullopt;
@@ -154,13 +146,13 @@
return totalReadBytes;
}
-std::optional<size_t> CurlFormDataStream::readFromFile(const FormDataElement& element, char* buffer, size_t size)
+std::optional<size_t> CurlFormDataStream::readFromFile(const FormDataElement::EncodedFileData& fileData, char* buffer, size_t size)
{
if (m_fileHandle == FileSystem::invalidPlatformFileHandle)
- m_fileHandle = FileSystem::openFile(element.m_filename, FileSystem::FileOpenMode::Read);
+ m_fileHandle = FileSystem::openFile(fileData.filename, FileSystem::FileOpenMode::Read);
if (!FileSystem::isHandleValid(m_fileHandle)) {
- LOG(Network, "Curl - Failed while trying to open %s for upload\n", element.m_filename.utf8().data());
+ LOG(Network, "Curl - Failed while trying to open %s for upload\n", fileData.filename.utf8().data());
m_fileHandle = FileSystem::invalidPlatformFileHandle;
return std::nullopt;
}
@@ -167,7 +159,7 @@
auto readBytes = FileSystem::readFromFile(m_fileHandle, buffer, size);
if (readBytes < 0) {
- LOG(Network, "Curl - Failed while trying to read %s for upload\n", element.m_filename.utf8().data());
+ LOG(Network, "Curl - Failed while trying to read %s for upload\n", fileData.filename.utf8().data());
FileSystem::closeFile(m_fileHandle);
m_fileHandle = FileSystem::invalidPlatformFileHandle;
return std::nullopt;
@@ -182,10 +174,10 @@
return readBytes;
}
-std::optional<size_t> CurlFormDataStream::readFromData(const FormDataElement& element, char* buffer, size_t size)
+std::optional<size_t> CurlFormDataStream::readFromData(const Vector<char>& data, char* buffer, size_t size)
{
- size_t elementSize = element.m_data.size() - m_dataOffset;
- const char* elementBuffer = element.m_data.data() + m_dataOffset;
+ size_t elementSize = data.size() - m_dataOffset;
+ const char* elementBuffer = data.data() + m_dataOffset;
size_t readBytes = elementSize > size ? size : elementSize;
memcpy(buffer, elementBuffer, readBytes);
Modified: trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.h (236364 => 236365)
--- trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.h 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/curl/CurlFormDataStream.h 2018-09-21 22:50:36 UTC (rev 236365)
@@ -51,8 +51,8 @@
private:
void computeContentLength();
- std::optional<size_t> readFromFile(const FormDataElement&, char*, size_t);
- std::optional<size_t> readFromData(const FormDataElement&, char*, size_t);
+ std::optional<size_t> readFromFile(const FormDataElement::EncodedFileData&, char*, size_t);
+ std::optional<size_t> readFromData(const Vector<char>&, char*, size_t);
RefPtr<FormData> m_formData;
Modified: trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp (236364 => 236365)
--- trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -74,29 +74,27 @@
soup_message_body_set_accumulate(soupMessage->request_body, FALSE);
uint64_t bodySize = 0;
for (const auto& element : formData->elements()) {
- switch (element.m_type) {
- case FormDataElement::Type::Data:
- bodySize += element.m_data.size();
- soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
- break;
- case FormDataElement::Type::EncodedFile:
- if (RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(element.m_filename)) {
- if (buffer->isEmpty())
- break;
-
- GUniquePtr<SoupBuffer> soupBuffer(buffer->createSoupBuffer());
- bodySize += buffer->size();
- if (soupBuffer->length)
- soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get());
+ return switchOn(element.data,
+ [&] (const Vector<char>& bytes) {
+ bodySize += bytes.size();
+ soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, bytes.data(), bytes.size());
+ }, [&] (const FormDataElement::EncodedFileData& fileData) {
+ if (RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(fileData.filename)) {
+ if (buffer->isEmpty())
+ return;
+
+ GUniquePtr<SoupBuffer> soupBuffer(buffer->createSoupBuffer());
+ bodySize += buffer->size();
+ if (soupBuffer->length)
+ soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get());
+ }
+ }, [&] (const FormDataElement::EncodedBlobData& blob) {
+ if (auto* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(blob.url)) {
+ for (const auto& item : blobData->items())
+ bodySize += appendEncodedBlobItemToSoupMessageBody(soupMessage, item);
+ }
}
- break;
- case FormDataElement::Type::EncodedBlob:
- if (auto* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(element.m_url)) {
- for (const auto& item : blobData->items())
- bodySize += appendEncodedBlobItemToSoupMessageBody(soupMessage, item);
- }
- break;
- }
+ );
}
ASSERT(bodySize == static_cast<uint64_t>(soupMessage->request_body->length));
Modified: trunk/Source/WebKit/ChangeLog (236364 => 236365)
--- trunk/Source/WebKit/ChangeLog 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/ChangeLog 2018-09-21 22:50:36 UTC (rev 236365)
@@ -1,5 +1,19 @@
2018-09-21 Alex Christensen <[email protected]>
+ Use a Variant for FormDataElement
+ https://bugs.webkit.org/show_bug.cgi?id=189777
+
+ Reviewed by Chris Dumez.
+
+ * NetworkProcess/NetworkResourceLoadParameters.cpp:
+ (WebKit::NetworkResourceLoadParameters::encode const):
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ * Shared/SessionState.h:
+ * WebProcess/WebCoreSupport/SessionStateConversion.cpp:
+ (WebKit::toHTTPBody):
+
+2018-09-21 Alex Christensen <[email protected]>
+
Simply authentication code even more!
https://bugs.webkit.org/show_bug.cgi?id=189719
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp (236364 => 236365)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -49,7 +49,7 @@
const Vector<FormDataElement>& elements = request.httpBody()->elements();
size_t fileCount = 0;
for (size_t i = 0, count = elements.size(); i < count; ++i) {
- if (elements[i].m_type == FormDataElement::Type::EncodedFile)
+ if (WTF::holds_alternative<FormDataElement::EncodedFileData>(elements[i].data))
++fileCount;
}
@@ -58,8 +58,8 @@
size_t extensionIndex = 0;
for (size_t i = 0, count = elements.size(); i < count; ++i) {
const FormDataElement& element = elements[i];
- if (element.m_type == FormDataElement::Type::EncodedFile) {
- const String& path = element.m_shouldGenerateFile ? element.m_generatedFilename : element.m_filename;
+ if (auto* fileData = WTF::get_if<FormDataElement::EncodedFileData>(element.data)) {
+ const String& path = fileData->shouldGenerateFile ? fileData->generatedFilename : fileData->filename;
SandboxExtension::createHandle(path, SandboxExtension::Type::ReadOnly, requestBodySandboxExtensions[extensionIndex++]);
}
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (236364 => 236365)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -112,8 +112,8 @@
if (originalRequest().httpBody()) {
for (const auto& element : originalRequest().httpBody()->elements()) {
- if (element.m_type == FormDataElement::Type::EncodedBlob)
- m_fileReferences.appendVector(NetworkBlobRegistry::singleton().filesInBlob(connection, element.m_url));
+ if (auto* blobData = WTF::get_if<FormDataElement::EncodedBlobData>(element.data))
+ m_fileReferences.appendVector(NetworkBlobRegistry::singleton().filesInBlob(connection, blobData->url));
}
}
Modified: trunk/Source/WebKit/Platform/IPC/SharedBufferDataReference.h (236364 => 236365)
--- trunk/Source/WebKit/Platform/IPC/SharedBufferDataReference.h 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/Platform/IPC/SharedBufferDataReference.h 2018-09-21 22:50:36 UTC (rev 236365)
@@ -41,7 +41,7 @@
void encode(Encoder& encoder) const
{
- WTF::visit(WTF::makeVisitor(
+ switchOn(m_data,
[encoder = &encoder] (const Ref<const WebCore::SharedBuffer>& buffer) mutable {
uint64_t bufferSize = buffer->size();
encoder->reserve(bufferSize + sizeof(uint64_t));
@@ -53,7 +53,8 @@
encoder->reserve(bufferSize + sizeof(uint64_t));
*encoder << bufferSize;
encoder->encodeFixedLengthData(pair.first, pair.second, 1);
- }), m_data);
+ }
+ );
}
private:
Modified: trunk/Source/WebKit/Shared/SessionState.h (236364 => 236365)
--- trunk/Source/WebKit/Shared/SessionState.h 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/Shared/SessionState.h 2018-09-21 22:50:36 UTC (rev 236365)
@@ -59,6 +59,7 @@
Blob,
};
+ // FIXME: This should be a Variant. It's also unclear why we don't just use FormDataElement here.
Type type = Type::Data;
// Data.
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/SessionStateConversion.cpp (236364 => 236365)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/SessionStateConversion.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/SessionStateConversion.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -42,26 +42,22 @@
for (const auto& formDataElement : formData.elements()) {
HTTPBody::Element element;
- switch (formDataElement.m_type) {
- case FormDataElement::Type::Data:
- element.type = HTTPBody::Element::Type::Data;
- element.data = ""
- break;
+ switchOn(formDataElement.data,
+ [&] (const Vector<char>& bytes) {
+ element.type = HTTPBody::Element::Type::Data;
+ element.data = ""
+ }, [&] (const FormDataElement::EncodedFileData& fileData) {
+ element.filePath = fileData.filename;
+ element.fileStart = fileData.fileStart;
+ if (fileData.fileLength != BlobDataItem::toEndOfFile)
+ element.fileLength = fileData.fileLength;
+ if (fileData.expectedFileModificationTime != FileSystem::invalidFileTime())
+ element.expectedFileModificationTime = fileData.expectedFileModificationTime;
+ }, [&] (const FormDataElement::EncodedBlobData& blobData) {
+ element.blobURLString = blobData.url.string();
+ }
+ );
- case FormDataElement::Type::EncodedFile:
- element.filePath = formDataElement.m_filename;
- element.fileStart = formDataElement.m_fileStart;
- if (formDataElement.m_fileLength != BlobDataItem::toEndOfFile)
- element.fileLength = formDataElement.m_fileLength;
- if (formDataElement.m_expectedFileModificationTime != FileSystem::invalidFileTime())
- element.expectedFileModificationTime = formDataElement.m_expectedFileModificationTime;
- break;
-
- case FormDataElement::Type::EncodedBlob:
- element.blobURLString = formDataElement.m_url.string();
- break;
- }
-
httpBody.elements.append(WTFMove(element));
}
Modified: trunk/Source/WebKitLegacy/win/ChangeLog (236364 => 236365)
--- trunk/Source/WebKitLegacy/win/ChangeLog 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKitLegacy/win/ChangeLog 2018-09-21 22:50:36 UTC (rev 236365)
@@ -1,3 +1,13 @@
+2018-09-21 Alex Christensen <[email protected]>
+
+ Use a Variant for FormDataElement
+ https://bugs.webkit.org/show_bug.cgi?id=189777
+
+ Reviewed by Chris Dumez.
+
+ * WebMutableURLRequest.cpp:
+ (WebMutableURLRequest::setHTTPBody):
+
2018-09-17 Fujii Hironori <[email protected]>
[Win][Clang][WebKitLegacy] error: cannot pass object of non-trivial type through variadic function
Modified: trunk/Source/WebKitLegacy/win/WebMutableURLRequest.cpp (236364 => 236365)
--- trunk/Source/WebKitLegacy/win/WebMutableURLRequest.cpp 2018-09-21 21:50:38 UTC (rev 236364)
+++ trunk/Source/WebKitLegacy/win/WebMutableURLRequest.cpp 2018-09-21 22:50:36 UTC (rev 236365)
@@ -300,14 +300,12 @@
if (stat.cbSize.HighPart || !stat.cbSize.LowPart)
return E_FAIL;
- RefPtr<FormData> httpBody = FormData::create();
- char* formData = httpBody->expandDataStore(stat.cbSize.LowPart);
-
+ size_t length = stat.cbSize.LowPart;
+ Vector<char> vector(length);
ULONG bytesRead = 0;
- if (FAILED(data->Read(formData, stat.cbSize.LowPart, &bytesRead)))
+ if (FAILED(data->Read(vector.data(), stat.cbSize.LowPart, &bytesRead)))
return E_FAIL;
-
- m_request.setHTTPBody(WTFMove(httpBody));
+ m_request.setHTTPBody(FormData::create(WTFMove(vector)));
return S_OK;
}