WebKit Bugzilla
Attachment 372915 Details for
Bug 199189
: WebSockets: add support for sending blob messages when using web sockets platform APIs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
wk2-sockets-blob.diff (text/plain), 11.33 KB, created by
Carlos Garcia Campos
on 2019-06-26 04:50:28 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Carlos Garcia Campos
Created:
2019-06-26 04:50:28 PDT
Size:
11.33 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index e3c86f6388f..6fd82a05a1b 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,12 @@ >+2019-06-26 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ WebSockets: add support for sending blob messages when using web sockets platform APIs >+ https://bugs.webkit.org/show_bug.cgi?id=199189 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Headers.cmake: Add missing headers. >+ > 2019-06-25 Fujii Hironori <Hironori.Fujii@sony.com> > > [WinCairo] incorrect font height for 'Google Sans Display' font >diff --git a/Source/WebCore/Headers.cmake b/Source/WebCore/Headers.cmake >index a81d82ab8df..017c9129ef0 100644 >--- a/Source/WebCore/Headers.cmake >+++ b/Source/WebCore/Headers.cmake >@@ -515,7 +515,9 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > fileapi/BlobLineEndings.h > fileapi/BlobPropertyBag.h > fileapi/File.h >+ fileapi/FileError.h > fileapi/FileList.h >+ fileapi/FileReaderLoader.h > fileapi/FileReaderLoaderClient.h > > history/BackForwardClient.h >@@ -1168,6 +1170,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/network/BlobPart.h > platform/network/BlobRegistry.h > platform/network/BlobRegistryImpl.h >+ platform/network/BlobResourceHandle.h > platform/network/CacheValidation.h > platform/network/CertificateInfoBase.h > platform/network/CookieRequestHeaderFieldProxy.h >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 4cc8c2158b5..49c8b3d82a8 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,26 @@ >+2019-06-26 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ WebSockets: add support for sending blob messages when using web sockets platform APIs >+ https://bugs.webkit.org/show_bug.cgi?id=199189 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add helper private class BlobLoader that uses FileReaderLoader to load the blobs. Since blob loads are >+ asynchronous, the messages are queued using another helper internal class PendingMessage. >+ >+ * WebProcess/Network/WebSocketChannel.cpp: >+ (WebKit::WebSocketChannel::send): Queue the message in pending queue if there are pending messages in the queue >+ for text and binary messages. For blobs, always queue the message unless it's an empty blob that we can handle >+ as empty binary data directly. >+ (WebKit::PendingMessage::PendingMessage): Helper class to queue message requests. >+ (WebKit::PendingMessage::type const): Type of message: Text, Binary, Blob. >+ (WebKit::PendingMessage::textMessage const): The text message. >+ (WebKit::PendingMessage::binaryData const): The binary data. >+ (WebKit::PendingMessage::blobLoader const): The blob loader. >+ (WebKit::PendingMessage::releaseCompletionHandler): Transfer the completion handler to the caller. >+ (WebKit::WebSocketChannel::disconnect): Clear the pending messages queue. >+ * WebProcess/Network/WebSocketChannel.h: >+ > 2019-06-25 Jiewen Tan <jiewen_tan@apple.com> > > Implement a new SPI to inform clients about AppSSO >diff --git a/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp b/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp >index e3a23a44aa4..17d9c7a69b3 100644 >--- a/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp >+++ b/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp >@@ -32,11 +32,15 @@ > #include "NetworkSocketChannelMessages.h" > #include "WebCoreArgumentCoders.h" > #include "WebProcess.h" >+#include <WebCore/Blob.h> > #include <WebCore/Document.h> >+#include <WebCore/FileReaderLoader.h> >+#include <WebCore/FileReaderLoaderClient.h> > #include <WebCore/NotImplemented.h> > #include <WebCore/WebSocketChannel.h> > #include <WebCore/WebSocketChannelClient.h> > #include <pal/SessionID.h> >+#include <wtf/SetForScope.h> > > namespace WebKit { > >@@ -105,7 +109,12 @@ WebSocketChannel::SendResult WebSocketChannel::send(const String& message) > if (m_client) > m_client->didUpdateBufferedAmount(m_bufferedAmount); > }; >- sendWithAsyncReply(Messages::NetworkSocketChannel::SendString { message }, WTFMove(completionHandler)); >+ >+ if (m_pendingMessages.isEmpty()) >+ sendWithAsyncReply(Messages::NetworkSocketChannel::SendString { message }, WTFMove(completionHandler)); >+ else >+ m_pendingMessages.append(std::make_unique<PendingMessage>(message, WTFMove(completionHandler))); >+ > return SendSuccess; > } > >@@ -121,14 +130,144 @@ WebSocketChannel::SendResult WebSocketChannel::send(const JSC::ArrayBuffer& bina > if (m_client) > m_client->didUpdateBufferedAmount(m_bufferedAmount); > }; >- sendWithAsyncReply(Messages::NetworkSocketChannel::SendData { IPC::DataReference { static_cast<const uint8_t*>(binaryData.data()) + byteOffset, byteLength } }, WTFMove(completionHandler)); >+ >+ if (m_sendingPendingBlobMessage || m_pendingMessages.isEmpty()) >+ sendWithAsyncReply(Messages::NetworkSocketChannel::SendData { IPC::DataReference { static_cast<const uint8_t*>(binaryData.data()) + byteOffset, byteLength } }, WTFMove(completionHandler)); >+ else >+ m_pendingMessages.append(std::make_unique<PendingMessage>(binaryData, byteOffset, byteLength, WTFMove(completionHandler))); >+ > return SendSuccess; > } > >-WebSocketChannel::SendResult WebSocketChannel::send(WebCore::Blob&) >+class BlobLoader final : public WebCore::FileReaderLoaderClient { >+ WTF_MAKE_FAST_ALLOCATED; >+public: >+ BlobLoader(WebCore::Document* document, Blob& blob, CompletionHandler<void()>&& completionHandler) >+ : m_loader(std::make_unique<FileReaderLoader>(FileReaderLoader::ReadAsArrayBuffer, this)) >+ , m_completionHandler(WTFMove(completionHandler)) >+ { >+ m_loader->start(document, blob); >+ } >+ >+ ~BlobLoader() >+ { >+ if (m_loader) >+ m_loader->cancel(); >+ } >+ >+ bool isLoading() const { return !!m_loader; } >+ const RefPtr<JSC::ArrayBuffer>& result() const { return m_buffer; } >+ Optional<int> errorCode() const { return m_errorCode; } >+ >+private: >+ void didStartLoading() final { } >+ void didReceiveData() final { } >+ >+ void didFinishLoading() final >+ { >+ m_buffer = m_loader->arrayBufferResult(); >+ complete(); >+ } >+ >+ void didFail(int errorCode) final >+ { >+ m_errorCode = errorCode; >+ complete(); >+ } >+ >+ void complete() >+ { >+ m_loader = nullptr; >+ m_completionHandler(); >+ } >+ >+ std::unique_ptr<WebCore::FileReaderLoader> m_loader; >+ RefPtr<JSC::ArrayBuffer> m_buffer; >+ Optional<int> m_errorCode; >+ CompletionHandler<void()> m_completionHandler; >+}; >+ >+class PendingMessage { >+ WTF_MAKE_FAST_ALLOCATED; >+public: >+ enum class Type { Text, Binary, Blob }; >+ >+ PendingMessage(const String& message, CompletionHandler<void()>&& completionHandler) >+ : m_type(Type::Text) >+ , m_textMessage(message) >+ , m_completionHandler(WTFMove(completionHandler)) >+ { >+ } >+ >+ PendingMessage(const JSC::ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength, CompletionHandler<void()>&& completionHandler) >+ : m_type(Type::Binary) >+ , m_binaryData(WebCore::SharedBuffer::create(static_cast<const uint8_t*>(binaryData.data()) + byteOffset, byteLength)) >+ , m_completionHandler(WTFMove(completionHandler)) >+ { >+ } >+ >+ PendingMessage(WebCore::Document* document, Blob& blob, CompletionHandler<void()>&& completionHandler) >+ : m_type(Type::Blob) >+ , m_blobLoader(std::make_unique<BlobLoader>(document, blob, WTFMove(completionHandler))) >+ { >+ } >+ >+ ~PendingMessage() = default; >+ >+ Type type() const { return m_type; } >+ const String& textMessage() const { ASSERT(m_type == Type::Text); return m_textMessage; } >+ const WebCore::SharedBuffer& binaryData() const { ASSERT(m_type == Type::Binary); return *m_binaryData; } >+ const BlobLoader& blobLoader() const { ASSERT(m_type == Type::Blob); return *m_blobLoader; } >+ >+ CompletionHandler<void()> releaseCompletionHandler() { ASSERT(m_type != Type::Blob); return std::exchange(m_completionHandler, nullptr); } >+ >+private: >+ Type m_type; >+ String m_textMessage; >+ RefPtr<WebCore::SharedBuffer> m_binaryData; >+ std::unique_ptr<BlobLoader> m_blobLoader; >+ CompletionHandler<void()> m_completionHandler; >+}; >+ >+WebSocketChannel::SendResult WebSocketChannel::send(WebCore::Blob& blob) > { >- notImplemented(); >- return SendFail; >+ // Avoid the Blob queue and loading for empty blobs. >+ if (!blob.size()) >+ return send(JSC::ArrayBuffer::create(blob.size(), 1), 0, 0); >+ >+ m_pendingMessages.append(std::make_unique<PendingMessage>(m_document.get(), blob, [this, protectedThis = makeRef(*this)] { >+ while (!m_pendingMessages.isEmpty()) { >+ auto& message = m_pendingMessages.first(); >+ >+ switch (message->type()) { >+ case PendingMessage::Type::Text: >+ sendWithAsyncReply(Messages::NetworkSocketChannel::SendString { message->textMessage() }, message->releaseCompletionHandler()); >+ break; >+ case PendingMessage::Type::Binary: { >+ const auto& binaryData = message->binaryData(); >+ sendWithAsyncReply(Messages::NetworkSocketChannel::SendData { IPC::DataReference { reinterpret_cast<const uint8_t*>(binaryData.data()), binaryData.size() } }, message->releaseCompletionHandler()); >+ break; >+ } >+ case PendingMessage::Type::Blob: { >+ auto& loader = message->blobLoader(); >+ if (loader.isLoading()) >+ return; >+ >+ if (const auto& result = loader.result()) { >+ SetForScope change(m_sendingPendingBlobMessage, true); >+ send(*result, 0, result->byteLength()); >+ } else if (auto errorCode = loader.errorCode()) >+ fail(makeString("Failed to load Blob: error code = ", errorCode.value())); >+ else >+ ASSERT_NOT_REACHED(); >+ break; >+ } >+ } >+ >+ m_pendingMessages.removeFirst(); >+ } >+ })); >+ return SendSuccess; > } > > unsigned WebSocketChannel::bufferedAmount() const >@@ -157,6 +296,7 @@ void WebSocketChannel::disconnect() > m_client = nullptr; > m_document = nullptr; > m_pendingTasks.clear(); >+ m_pendingMessages.clear(); > > MessageSender::send(Messages::NetworkSocketChannel::Close { 0, { } }); > } >diff --git a/Source/WebKit/WebProcess/Network/WebSocketChannel.h b/Source/WebKit/WebProcess/Network/WebSocketChannel.h >index d8a6aac2112..a1cbbcc0d20 100644 >--- a/Source/WebKit/WebProcess/Network/WebSocketChannel.h >+++ b/Source/WebKit/WebProcess/Network/WebSocketChannel.h >@@ -41,6 +41,8 @@ class DataReference; > > namespace WebKit { > >+class PendingMessage; >+ > class WebSocketChannel : public IPC::MessageSender, public IPC::MessageReceiver, public WebCore::ThreadableWebSocketChannel, public RefCounted<WebSocketChannel>, public Identified<WebSocketChannel> { > public: > static Ref<WebSocketChannel> create(WebCore::Document&, WebCore::WebSocketChannelClient&); >@@ -91,7 +93,9 @@ private: > size_t m_bufferedAmount { 0 }; > bool m_isClosing { false }; > bool m_isSuspended { false }; >+ bool m_sendingPendingBlobMessage { false }; > Deque<Function<void()>> m_pendingTasks; >+ Deque<std::unique_ptr<PendingMessage>> m_pendingMessages; > }; > > } // namespace WebKit
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199189
:
372834
|
372915
|
373016
|
373019
|
373029
|
373031
|
373095