Diff
Modified: trunk/LayoutTests/ChangeLog (272050 => 272051)
--- trunk/LayoutTests/ChangeLog 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/LayoutTests/ChangeLog 2021-01-29 08:49:50 UTC (rev 272051)
@@ -1,3 +1,14 @@
+2021-01-29 Carlos Garcia Campos <[email protected]>
+
+ [SOUP] Use a GInputStream to set the request body in preparation for libsoup3
+ https://bugs.webkit.org/show_bug.cgi?id=221034
+
+ Reviewed by Adrian Perez de Castro.
+
+ Remove expectations of http/tests/local/blob/send-hybrid-blob-using-open-panel.html that is now passing.
+
+ * platform/gtk/TestExpectations:
+
2021-01-29 Rob Buis <[email protected]>
Fix logic error in shouldComputeLogicalHeightFromAspectRatio
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (272050 => 272051)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2021-01-29 08:49:50 UTC (rev 272051)
@@ -2564,8 +2564,6 @@
webkit.org/b/194384 compositing/clipping/border-radius-async-overflow-clipping-layer.html [ Failure ]
webkit.org/b/206000 compositing/clipping/border-radius-async-overflow-non-stacking.html [ ImageOnlyFailure ]
-webkit.org/b/194609 http/tests/local/blob/send-hybrid-blob-using-open-panel.html [ Failure ]
-
webkit.org/b/195259 compositing/geometry/fixed-position-composited-page-scale-smaller-than-viewport.html [ ImageOnlyFailure ]
webkit.org/b/195712 inspector/canvas/recording-html-2d.html [ Failure ]
Modified: trunk/Source/WebCore/ChangeLog (272050 => 272051)
--- trunk/Source/WebCore/ChangeLog 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/Source/WebCore/ChangeLog 2021-01-29 08:49:50 UTC (rev 272051)
@@ -1,3 +1,26 @@
+2021-01-29 Carlos Garcia Campos <[email protected]>
+
+ [SOUP] Use a GInputStream to set the request body in preparation for libsoup3
+ https://bugs.webkit.org/show_bug.cgi?id=221034
+
+ Reviewed by Adrian Perez de Castro.
+
+ In libsoup3, the request body can be set using a stream. Add the stream now, that can still be used in libsoup2
+ to set the body data. This moves the FormData processing code to WebKitFormDataInputStream and also implements
+ the file seek and range length, which makes test http/tests/local/blob/send-hybrid-blob-using-open-panel.html pass.
+
+ * platform/SourcesSoup.txt:
+ * platform/network/soup/ResourceRequestSoup.cpp:
+ (WebCore::ResourceRequest::updateSoupMessageBody const):
+ * platform/network/soup/WebKitFormDataInputStream.cpp: Added.
+ (webkitFormDataInputStreamCreateNextStream):
+ (webkitFormDataInputStreamRead):
+ (webkitFormDataInputStreamClose):
+ (webkit_form_data_input_stream_class_init):
+ (webkitFormDataInputStreamNew):
+ (webkitFormDataInputStreamReadAll):
+ * platform/network/soup/WebKitFormDataInputStream.h: Added.
+
2021-01-29 Rob Buis <[email protected]>
Fix logic error in shouldComputeLogicalHeightFromAspectRatio
Modified: trunk/Source/WebCore/platform/SourcesSoup.txt (272050 => 272051)
--- trunk/Source/WebCore/platform/SourcesSoup.txt 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/Source/WebCore/platform/SourcesSoup.txt 2021-01-29 08:49:50 UTC (rev 272051)
@@ -36,6 +36,7 @@
platform/network/soup/SoupNetworkSession.cpp
platform/network/soup/SynchronousLoaderClientSoup.cpp
platform/network/soup/URLSoup.cpp
+platform/network/soup/WebKitFormDataInputStream.cpp @no-unify
platform/soup/PublicSuffixSoup.cpp
platform/soup/SharedBufferSoup.cpp
Modified: trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp (272050 => 272051)
--- trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp 2021-01-29 08:49:50 UTC (rev 272051)
@@ -30,77 +30,48 @@
#include "RegistrableDomain.h"
#include "SharedBuffer.h"
#include "URLSoup.h"
+#include "WebKitFormDataInputStream.h"
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-static uint64_t appendEncodedBlobItemToSoupMessageBody(SoupMessage* soupMessage, const BlobDataItem& blobItem)
+void ResourceRequest::updateSoupMessageBody(SoupMessage* soupMessage, BlobRegistryImpl& blobRegistry) const
{
- switch (blobItem.type()) {
- case BlobDataItem::Type::Data:
- soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, blobItem.data().data()->data() + blobItem.offset(), blobItem.length());
- return blobItem.length();
- case BlobDataItem::Type::File: {
- if (!blobItem.file()->expectedModificationTime())
- return 0;
+ auto* formData = httpBody();
+ if (!formData || formData->isEmpty())
+ return;
- auto fileModificationTime = FileSystem::getFileModificationTime(blobItem.file()->path());
- if (!fileModificationTime)
- return 0;
-
- if (fileModificationTime->secondsSinceEpoch().secondsAs<time_t>() != blobItem.file()->expectedModificationTime()->secondsSinceEpoch().secondsAs<time_t>())
- return 0;
-
- if (auto buffer = SharedBuffer::createWithContentsOfFile(blobItem.file()->path())) {
- if (buffer->isEmpty())
- return 0;
-
- GUniquePtr<SoupBuffer> soupBuffer(buffer->createSoupBuffer(blobItem.offset(), blobItem.length() == BlobDataItem::toEndOfFile ? 0 : blobItem.length()));
- if (soupBuffer->length)
- soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get());
- return soupBuffer->length;
+ // Handle the common special case of one piece of form data, with no files.
+ auto& elements = formData->elements();
+ if (elements.size() == 1 && !formData->alwaysStream()) {
+ if (auto* vector = WTF::get_if<Vector<char>>(elements[0].data)) {
+ soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, vector->data(), vector->size());
+ return;
}
- break;
}
+
+ // Precompute the content length.
+ auto resolvedFormData = formData->resolveBlobReferences();
+ uint64_t length = 0;
+ for (auto& element : resolvedFormData->elements()) {
+ length += element.lengthInBytes([&](auto& url) {
+ return blobRegistry.blobSize(url);
+ });
}
- return 0;
-}
-
-void ResourceRequest::updateSoupMessageBody(SoupMessage* soupMessage, BlobRegistryImpl& blobRegistry) const
-{
- auto* formData = httpBody();
- if (!formData || formData->isEmpty())
+ if (!length)
return;
- soup_message_body_set_accumulate(soupMessage->request_body, FALSE);
- uint64_t bodySize = 0;
- for (const auto& element : formData->elements()) {
- 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 (auto 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 = blobRegistry.getBlobDataFromURL(blob.url)) {
- for (const auto& item : blobData->items())
- bodySize += appendEncodedBlobItemToSoupMessageBody(soupMessage, item);
- }
- }
- );
+ GRefPtr<GInputStream> stream = webkitFormDataInputStreamNew(WTFMove(resolvedFormData));
+ if (GBytes* data = "" {
+ soup_message_body_set_accumulate(soupMessage->request_body, FALSE);
+ GUniquePtr<SoupBuffer> soupBuffer(soup_buffer_new_with_owner(g_bytes_get_data(data, nullptr),
+ g_bytes_get_size(data), data, reinterpret_cast<GDestroyNotify>(g_bytes_unref)));
+ soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get());
}
- ASSERT(bodySize == static_cast<uint64_t>(soupMessage->request_body->length));
+ ASSERT(length == static_cast<uint64_t>(soupMessage->request_body->length));
}
void ResourceRequest::updateSoupMessageMembers(SoupMessage* soupMessage) const
Added: trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.cpp (0 => 272051)
--- trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.cpp (rev 0)
+++ trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.cpp 2021-01-29 08:49:50 UTC (rev 272051)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitFormDataInputStream.h"
+
+#include "BlobData.h"
+#include <wtf/FileSystem.h>
+#include <wtf/glib/WTFGType.h>
+
+using namespace WebCore;
+
+struct _WebKitFormDataInputStreamPrivate {
+ RefPtr<FormData> formData;
+ GRefPtr<GInputStream> currentStream;
+ unsigned nextIndex;
+ long long currentStreamRangeLength;
+};
+
+WEBKIT_DEFINE_TYPE(WebKitFormDataInputStream, webkit_form_data_input_stream, G_TYPE_INPUT_STREAM)
+
+static bool webkitFormDataInputStreamCreateNextStream(WebKitFormDataInputStream* stream, GCancellable* cancellable)
+{
+ auto* priv = stream->priv;
+ if (priv->currentStream) {
+ g_input_stream_close(G_INPUT_STREAM(priv->currentStream.get()), cancellable, nullptr);
+ priv->currentStream = nullptr;
+ priv->currentStreamRangeLength = BlobDataItem::toEndOfFile;
+ }
+
+ const auto& elements = priv->formData->elements();
+ if (elements.size() == priv->nextIndex)
+ return true;
+
+ const auto& element = elements[priv->nextIndex++];
+ switchOn(element.data,
+ [priv] (const Vector<char>& data) {
+ GRefPtr<GBytes> bytes = adoptGRef(g_bytes_new_static(data.data(), data.size()));
+ priv->currentStream = adoptGRef(g_memory_input_stream_new_from_bytes(bytes.get()));
+ }, [priv, cancellable] (const FormDataElement::EncodedFileData& fileData) {
+ if (fileData.fileModificationTimeMatchesExpectation()) {
+ GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(FileSystem::fileSystemRepresentation(fileData.filename).data()));
+ priv->currentStream = adoptGRef(G_INPUT_STREAM(g_file_read(file.get(), cancellable, nullptr)));
+ if (G_IS_SEEKABLE(priv->currentStream.get()) && fileData.fileStart > 0)
+ g_seekable_seek(G_SEEKABLE(priv->currentStream.get()), fileData.fileStart, G_SEEK_SET, cancellable, nullptr);
+ if (priv->currentStream)
+ priv->currentStreamRangeLength = fileData.fileLength;
+ }
+ }, [] (const FormDataElement::EncodedBlobData&) {
+ ASSERT_NOT_REACHED();
+ }
+ );
+
+ return !!priv->currentStream;
+}
+
+static gssize webkitFormDataInputStreamRead(GInputStream* input, void* buffer, gsize count, GCancellable* cancellable, GError** error)
+{
+ auto* stream = WEBKIT_FORM_DATA_INPUT_STREAM(input);
+ auto* priv = stream->priv;
+ if (!priv->currentStream)
+ while (!webkitFormDataInputStreamCreateNextStream(stream, cancellable)) { }
+
+ while (priv->currentStream) {
+ auto bytesToRead = count;
+ if (priv->currentStreamRangeLength != BlobDataItem::toEndOfFile && static_cast<unsigned long long>(priv->currentStreamRangeLength) < count)
+ bytesToRead = priv->currentStreamRangeLength;
+
+ auto bytesRead = g_input_stream_read(priv->currentStream.get(), buffer, bytesToRead, cancellable, error);
+ if (error)
+ return bytesRead;
+
+ if (bytesRead) {
+ if (priv->currentStreamRangeLength != BlobDataItem::toEndOfFile)
+ priv->currentStreamRangeLength -= bytesRead;
+ return bytesRead;
+ }
+
+ while (!webkitFormDataInputStreamCreateNextStream(stream, cancellable)) { }
+ }
+
+ return 0;
+}
+
+static gboolean webkitFormDataInputStreamClose(GInputStream* input, GCancellable* cancellable, GError**)
+{
+ auto* priv = WEBKIT_FORM_DATA_INPUT_STREAM(input)->priv;
+ if (priv->currentStream) {
+ g_input_stream_close(G_INPUT_STREAM(priv->currentStream.get()), cancellable, nullptr);
+ priv->currentStream = nullptr;
+ priv->currentStreamRangeLength = BlobDataItem::toEndOfFile;
+ }
+ priv->nextIndex = priv->formData->elements().size();
+
+ return TRUE;
+}
+
+static void webkit_form_data_input_stream_class_init(WebKitFormDataInputStreamClass* klass)
+{
+ auto* inputStreamClass = G_INPUT_STREAM_CLASS(klass);
+ inputStreamClass->read_fn = webkitFormDataInputStreamRead;
+ inputStreamClass->close_fn = webkitFormDataInputStreamClose;
+}
+
+GRefPtr<GInputStream> webkitFormDataInputStreamNew(Ref<FormData>&& formData)
+{
+ auto* stream = WEBKIT_FORM_DATA_INPUT_STREAM(g_object_new(WEBKIT_TYPE_FORM_DATA_INPUT_STREAM, nullptr));
+ stream->priv->formData = WTFMove(formData);
+ stream->priv->currentStreamRangeLength = BlobDataItem::toEndOfFile;
+
+ return adoptGRef(G_INPUT_STREAM((stream)));
+}
+
+GBytes* webkitFormDataInputStreamReadAll(WebKitFormDataInputStream* stream)
+{
+ g_return_val_if_fail(WEBKIT_IS_FORM_DATA_INPUT_STREAM(stream), nullptr);
+
+ GRefPtr<GOutputStream> outputStream = adoptGRef(g_memory_output_stream_new(nullptr, 0, g_realloc, g_free));
+ auto bytesWritten = g_output_stream_splice(outputStream.get(), G_INPUT_STREAM(stream),
+ static_cast<GOutputStreamSpliceFlags>(G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET), nullptr, nullptr);
+ if (bytesWritten <= 0)
+ return nullptr;
+
+ return g_memory_output_stream_steal_as_bytes(G_MEMORY_OUTPUT_STREAM(outputStream.get()));
+}
Added: trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.h (0 => 272051)
--- trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.h (rev 0)
+++ trunk/Source/WebCore/platform/network/soup/WebKitFormDataInputStream.h 2021-01-29 08:49:50 UTC (rev 272051)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FormData.h"
+#include <gio/gio.h>
+#include <wtf/Forward.h>
+#include <wtf/glib/GRefPtr.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_FORM_DATA_INPUT_STREAM (webkit_form_data_input_stream_get_type ())
+#define WEBKIT_FORM_DATA_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_FORM_DATA_INPUT_STREAM, WebKitFormDataInputStream))
+#define WEBKIT_IS_FORM_DATA_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_FORM_DATA_INPUT_STREAM))
+#define WEBKIT_FORM_DATA_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_FORM_DATA_INPUT_STREAM, WebKitFormDataInputStreamClass))
+#define WEBKIT_IS_FORM_DATA_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), WEBKIT_TYPE_FORM_DATA_INPUT_STREAM))
+#define WEBKIT_FORM_DATA_INPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_FORM_DATA_INPUT_STREAM, WebKitFormDataInputStreamClass))
+
+typedef struct _WebKitFormDataInputStream WebKitFormDataInputStream;
+typedef struct _WebKitFormDataInputStreamClass WebKitFormDataInputStreamClass;
+typedef struct _WebKitFormDataInputStreamPrivate WebKitFormDataInputStreamPrivate;
+
+struct _WebKitFormDataInputStream {
+ GInputStream parent;
+
+ WebKitFormDataInputStreamPrivate* priv;
+};
+
+struct _WebKitFormDataInputStreamClass {
+ GInputStreamClass parentClass;
+};
+
+GType webkit_form_data_input_stream_get_type(void);
+
+GRefPtr<GInputStream> webkitFormDataInputStreamNew(Ref<WebCore::FormData>&&);
+GBytes* webkitFormDataInputStreamReadAll(WebKitFormDataInputStream*);
+
+G_END_DECLS
+
Modified: trunk/Tools/ChangeLog (272050 => 272051)
--- trunk/Tools/ChangeLog 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/Tools/ChangeLog 2021-01-29 08:49:50 UTC (rev 272051)
@@ -1,3 +1,14 @@
+2021-01-29 Carlos Garcia Campos <[email protected]>
+
+ [SOUP] Use a GInputStream to set the request body in preparation for libsoup3
+ https://bugs.webkit.org/show_bug.cgi?id=221034
+
+ Reviewed by Adrian Perez de Castro.
+
+ Add WebKitFormDataInputStream as an exception for some style checker rules.
+
+ * Scripts/webkitpy/style/checker.py:
+
2021-01-28 Lauro Moura <[email protected]>
[GLIB] Gardening API release passes and some debug crashes
Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (272050 => 272051)
--- trunk/Tools/Scripts/webkitpy/style/checker.py 2021-01-29 08:47:58 UTC (rev 272050)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py 2021-01-29 08:49:50 UTC (rev 272051)
@@ -234,6 +234,8 @@
os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'gstreamer', 'GStreamerMediaStreamSource.cpp'),
os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'ProxyResolverSoup.cpp'),
os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'ProxyResolverSoup.h'),
+ os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'WebKitFormDataInputStream.cpp'),
+ os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'WebKitFormDataInputStream.h'),
os.path.join('Source', 'WebKit', 'NetworkProcess', 'soup', 'WebKitDirectoryInputStream.h')],
["-readability/naming",
"-readability/enum_casing"]),