Title: [116738] trunk/Source/WebKit2
Revision
116738
Author
carlo...@webkit.org
Date
2012-05-11 01:14:39 -0700 (Fri, 11 May 2012)

Log Message

[SOUP] Allow sending URI request data in chunks
https://bugs.webkit.org/show_bug.cgi?id=85880

Reviewed by Martin Robinson.

The API to handle custom URI schemes will receive an input stream
to read from. Current code requires to buffer the whole stream
before sending it to the WebProcess. This patch allows to send the
data in chunks while it's read from the stream.

* GNUmakefile.list.am: Add new files to compilation
* UIProcess/API/C/soup/WKSoupRequestManager.cpp:
(WKSoupRequestManagerRegisterURIScheme): Use toWTFString() to
convert from WKString to WTFString.
(WKSoupRequestManagerDidHandleURIRequest): Use didHandleURIRequest
as it has been renamed.
(WKSoupRequestManagerDidReceiveURIRequestData): New method to send
more data for the uri request to the web process.
* UIProcess/API/C/soup/WKSoupRequestManager.h:
* UIProcess/soup/WebSoupRequestManagerProxy.cpp:
(WebKit::WebSoupRequestManagerProxy::didHandleURIRequest):
HandleURIRequest has been renamed to DidHandleURIRequest.
(WebKit::WebSoupRequestManagerProxy::didReceiveURIRequestData):
Send DidReceiveURIRequestData message to the web process.
(WebKit::WebSoupRequestManagerProxy::didReceiveURIRequest): Use
didHandleURIRequest as it has been renamed.
* UIProcess/soup/WebSoupRequestManagerProxy.h:
(WebSoupRequestManagerProxy):
* WebProcess/soup/WebKitSoupRequestInputStream.cpp: Added.
(AsyncReadData::AsyncReadData): Helper struct to store information
about pending async read operations.
(_WebKitSoupRequestInputStreamPrivate):
(webkitSoupRequestInputStreamReadAsyncResultComplete): Read the
data from the memory input stream and complete the async read
operation.
(webkitSoupRequestInputStreamReadAsync): Read the data from the
memory input stream and complete the async read operation if
there's data to read, or save the async result to be completed
when more data is added to the stream.
(webkitSoupRequestInputStreamReadFinish): Finish an async read
started with webkitSoupRequestInputStreamReadAsync.
(webkitSoupRequestInputStreamFinalize):
(webkit_soup_request_input_stream_init):
(webkit_soup_request_input_stream_class_init):
(webkitSoupRequestInputStreamNew): Create a new input stream with
a fixed size or 0 if content length is not known.
(webkitSoupRequestInputStreamAddData): Add more data to the
stream and complete any pending async read.
(webkitSoupRequestInputStreamFinished): Whether all data expected
by the stream has been received.
* WebProcess/soup/WebKitSoupRequestInputStream.h: Added.
* WebProcess/soup/WebSoupRequestManager.cpp:
(WebKit::WebSoupRequestManager::didHandleURIRequest): Create a
WebKitSoupRequestInputStream if we haven't received all the
request data in the HandleURIRequest message. Otherwise just
create a memory input stream with all the data.
(WebKit::WebSoupRequestManager::didReceiveURIRequestData): Add the data
received to the WebKitSoupRequestInputStream associated to the
given request identifier.
* WebProcess/soup/WebSoupRequestManager.h:
* WebProcess/soup/WebSoupRequestManager.messages.in: Add
contentLength parameter to DidHandleURIRequest message and add
DidReceiveURIRequestData message.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (116737 => 116738)


--- trunk/Source/WebKit2/ChangeLog	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/ChangeLog	2012-05-11 08:14:39 UTC (rev 116738)
@@ -1,3 +1,69 @@
+2012-05-11  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [SOUP] Allow sending URI request data in chunks
+        https://bugs.webkit.org/show_bug.cgi?id=85880
+
+        Reviewed by Martin Robinson.
+
+        The API to handle custom URI schemes will receive an input stream
+        to read from. Current code requires to buffer the whole stream
+        before sending it to the WebProcess. This patch allows to send the
+        data in chunks while it's read from the stream.
+
+        * GNUmakefile.list.am: Add new files to compilation
+        * UIProcess/API/C/soup/WKSoupRequestManager.cpp:
+        (WKSoupRequestManagerRegisterURIScheme): Use toWTFString() to
+        convert from WKString to WTFString.
+        (WKSoupRequestManagerDidHandleURIRequest): Use didHandleURIRequest
+        as it has been renamed.
+        (WKSoupRequestManagerDidReceiveURIRequestData): New method to send
+        more data for the uri request to the web process.
+        * UIProcess/API/C/soup/WKSoupRequestManager.h:
+        * UIProcess/soup/WebSoupRequestManagerProxy.cpp:
+        (WebKit::WebSoupRequestManagerProxy::didHandleURIRequest):
+        HandleURIRequest has been renamed to DidHandleURIRequest.
+        (WebKit::WebSoupRequestManagerProxy::didReceiveURIRequestData):
+        Send DidReceiveURIRequestData message to the web process.
+        (WebKit::WebSoupRequestManagerProxy::didReceiveURIRequest): Use
+        didHandleURIRequest as it has been renamed.
+        * UIProcess/soup/WebSoupRequestManagerProxy.h:
+        (WebSoupRequestManagerProxy):
+        * WebProcess/soup/WebKitSoupRequestInputStream.cpp: Added.
+        (AsyncReadData::AsyncReadData): Helper struct to store information
+        about pending async read operations.
+        (_WebKitSoupRequestInputStreamPrivate):
+        (webkitSoupRequestInputStreamReadAsyncResultComplete): Read the
+        data from the memory input stream and complete the async read
+        operation.
+        (webkitSoupRequestInputStreamReadAsync): Read the data from the
+        memory input stream and complete the async read operation if
+        there's data to read, or save the async result to be completed
+        when more data is added to the stream.
+        (webkitSoupRequestInputStreamReadFinish): Finish an async read
+        started with webkitSoupRequestInputStreamReadAsync.
+        (webkitSoupRequestInputStreamFinalize):
+        (webkit_soup_request_input_stream_init):
+        (webkit_soup_request_input_stream_class_init):
+        (webkitSoupRequestInputStreamNew): Create a new input stream with
+        a fixed size or 0 if content length is not known.
+        (webkitSoupRequestInputStreamAddData): Add more data to the
+        stream and complete any pending async read.
+        (webkitSoupRequestInputStreamFinished): Whether all data expected
+        by the stream has been received.
+        * WebProcess/soup/WebKitSoupRequestInputStream.h: Added.
+        * WebProcess/soup/WebSoupRequestManager.cpp:
+        (WebKit::WebSoupRequestManager::didHandleURIRequest): Create a
+        WebKitSoupRequestInputStream if we haven't received all the
+        request data in the HandleURIRequest message. Otherwise just
+        create a memory input stream with all the data.
+        (WebKit::WebSoupRequestManager::didReceiveURIRequestData): Add the data
+        received to the WebKitSoupRequestInputStream associated to the
+        given request identifier.
+        * WebProcess/soup/WebSoupRequestManager.h:
+        * WebProcess/soup/WebSoupRequestManager.messages.in: Add
+        contentLength parameter to DidHandleURIRequest message and add
+        DidReceiveURIRequestData message.
+
 2012-05-10  MORITA Hajime  <morr...@google.com>
 
         ElementShadow should minimize the usage of "ShadowRoot" name

Modified: trunk/Source/WebKit2/GNUmakefile.list.am (116737 => 116738)


--- trunk/Source/WebKit2/GNUmakefile.list.am	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/GNUmakefile.list.am	2012-05-11 08:14:39 UTC (rev 116738)
@@ -939,6 +939,8 @@
 	Source/WebKit2/WebProcess/soup/WebSoupRequestManager.h \
 	Source/WebKit2/WebProcess/soup/WebKitSoupRequestGeneric.cpp \
 	Source/WebKit2/WebProcess/soup/WebKitSoupRequestGeneric.h \
+	Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp \
+	Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.h \
 	Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp \
 	Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp \
 	Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp \

Modified: trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp (116737 => 116738)


--- trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.cpp	2012-05-11 08:14:39 UTC (rev 116738)
@@ -43,10 +43,15 @@
 
 void WKSoupRequestManagerRegisterURIScheme(WKSoupRequestManagerRef soupRequestManagerRef, WKStringRef schemeRef)
 {
-    toImpl(soupRequestManagerRef)->registerURIScheme(toImpl(schemeRef)->string());
+    toImpl(soupRequestManagerRef)->registerURIScheme(toWTFString(schemeRef));
 }
 
-void WKSoupRequestManagerHandleURIRequest(WKSoupRequestManagerRef soupRequestManagerRef, WKDataRef data, WKStringRef mimeTypeRef, uint64_t requestID)
+void WKSoupRequestManagerDidHandleURIRequest(WKSoupRequestManagerRef soupRequestManagerRef, WKDataRef data, uint64_t contentLength, WKStringRef mimeTypeRef, uint64_t requestID)
 {
-    toImpl(soupRequestManagerRef)->handleURIRequest(toImpl(data), toImpl(mimeTypeRef)->string(), requestID);
+    toImpl(soupRequestManagerRef)->didHandleURIRequest(toImpl(data), contentLength, toWTFString(mimeTypeRef), requestID);
 }
+
+void WKSoupRequestManagerDidReceiveURIRequestData(WKSoupRequestManagerRef soupRequestManagerRef, WKDataRef data, uint64_t requestID)
+{
+    toImpl(soupRequestManagerRef)->didReceiveURIRequestData(toImpl(data), requestID);
+}

Modified: trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h (116737 => 116738)


--- trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h	2012-05-11 08:14:39 UTC (rev 116738)
@@ -48,7 +48,8 @@
 
 WK_EXPORT void WKSoupRequestManagerSetClient(WKSoupRequestManagerRef, const WKSoupRequestManagerClient* client);
 WK_EXPORT void WKSoupRequestManagerRegisterURIScheme(WKSoupRequestManagerRef, WKStringRef schemeRef);
-WK_EXPORT void WKSoupRequestManagerHandleURIRequest(WKSoupRequestManagerRef, WKDataRef, WKStringRef mimeTypeRef, uint64_t requestID);
+WK_EXPORT void WKSoupRequestManagerDidHandleURIRequest(WKSoupRequestManagerRef, WKDataRef, uint64_t contentLength, WKStringRef mimeTypeRef, uint64_t requestID);
+WK_EXPORT void WKSoupRequestManagerDidReceiveURIRequestData(WKSoupRequestManagerRef, WKDataRef, uint64_t requestID);
 
 #ifdef __cplusplus
 }

Modified: trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp (116737 => 116738)


--- trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp	2012-05-11 08:14:39 UTC (rev 116738)
@@ -60,16 +60,22 @@
     m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebSoupRequestManager::RegisterURIScheme(scheme));
 }
 
-void WebSoupRequestManagerProxy::handleURIRequest(const WebData* requestData, const String& mimeType, uint64_t requestID)
+void WebSoupRequestManagerProxy::didHandleURIRequest(const WebData* requestData, uint64_t contentLength, const String& mimeType, uint64_t requestID)
 {
     ASSERT(m_webContext);
-    m_webContext->sendToAllProcesses(Messages::WebSoupRequestManager::HandleURIRequest(requestData->dataReference(), mimeType, requestID));
+    m_webContext->sendToAllProcesses(Messages::WebSoupRequestManager::DidHandleURIRequest(requestData->dataReference(), contentLength, mimeType, requestID));
 }
 
+void WebSoupRequestManagerProxy::didReceiveURIRequestData(const WebData* requestData, uint64_t requestID)
+{
+    ASSERT(m_webContext);
+    m_webContext->sendToAllProcesses(Messages::WebSoupRequestManager::DidReceiveURIRequestData(requestData->dataReference(), requestID));
+}
+
 void WebSoupRequestManagerProxy::didReceiveURIRequest(const String& uriString, uint64_t requestID)
 {
     if (!m_client.didReceiveURIRequest(this, WebURL::create(uriString).get(), requestID))
-        handleURIRequest(WebData::create(0, 0).get(), String(), requestID);
+        didHandleURIRequest(WebData::create(0, 0).get(), 0, String(), requestID);
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h (116737 => 116738)


--- trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h	2012-05-11 08:14:39 UTC (rev 116738)
@@ -50,7 +50,8 @@
     void initializeClient(const WKSoupRequestManagerClient*);
 
     void registerURIScheme(const String& scheme);
-    void handleURIRequest(const WebData*, const String& mimeType, uint64_t requestID);
+    void didHandleURIRequest(const WebData*, uint64_t contentLength, const String& mimeType, uint64_t requestID);
+    void didReceiveURIRequestData(const WebData*, uint64_t requestID);
 
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 

Added: trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp (0 => 116738)


--- trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp	2012-05-11 08:14:39 UTC (rev 116738)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitSoupRequestInputStream.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/gobject/GRefPtr.h>
+
+struct AsyncReadData {
+    AsyncReadData(GSimpleAsyncResult* result, void* buffer, gsize count, GCancellable* cancellable)
+        : result(result)
+        , buffer(buffer)
+        , count(count)
+        , cancellable(cancellable)
+    {
+    }
+
+    GRefPtr<GSimpleAsyncResult> result;
+    void* buffer;
+    size_t count;
+    GRefPtr<GCancellable> cancellable;
+};
+
+struct _WebKitSoupRequestInputStreamPrivate {
+    uint64_t contentLength;
+    uint64_t bytesReceived;
+    uint64_t bytesRead;
+
+    Mutex readLock;
+    OwnPtr<AsyncReadData> pendingAsyncRead;
+};
+
+G_DEFINE_TYPE(WebKitSoupRequestInputStream, webkit_soup_request_input_stream, G_TYPE_MEMORY_INPUT_STREAM)
+
+static void webkitSoupRequestInputStreamReadAsyncResultComplete(WebKitSoupRequestInputStream* stream, GSimpleAsyncResult* result, void* buffer, gsize count, GCancellable* cancellable)
+{
+    GError* error = 0;
+    gssize bytesRead = G_INPUT_STREAM_GET_CLASS(stream)->read_fn(G_INPUT_STREAM(stream), buffer, count, cancellable, &error);
+    if (!error) {
+        g_simple_async_result_set_op_res_gssize(result, bytesRead);
+        stream->priv->bytesRead += bytesRead;
+    } else
+        g_simple_async_result_take_error(result, error);
+    g_simple_async_result_complete_in_idle(result);
+}
+
+static void webkitSoupRequestInputStreamPendingReadAsyncComplete(WebKitSoupRequestInputStream* stream)
+{
+    if (!stream->priv->pendingAsyncRead)
+        return;
+
+    AsyncReadData* data = ""
+    webkitSoupRequestInputStreamReadAsyncResultComplete(stream, data->result.get(), data->buffer, data->count, data->cancellable.get());
+    stream->priv->pendingAsyncRead.clear();
+}
+
+static bool webkitSoupRequestInputStreamHasDataToRead(WebKitSoupRequestInputStream* stream)
+{
+    return stream->priv->bytesRead < stream->priv->bytesReceived;
+}
+
+static bool webkitSoupRequestInputStreamIsWaitingForData(WebKitSoupRequestInputStream* stream)
+{
+    return !stream->priv->contentLength || stream->priv->bytesReceived < stream->priv->contentLength;
+}
+
+static void webkitSoupRequestInputStreamReadAsync(GInputStream* inputStream, void* buffer, gsize count, int priority, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+    WebKitSoupRequestInputStream* stream = WEBKIT_SOUP_REQUEST_INPUT_STREAM(inputStream);
+    GRefPtr<GSimpleAsyncResult> result = adoptGRef(g_simple_async_result_new(G_OBJECT(stream), callback, userData, reinterpret_cast<void*>(webkitSoupRequestInputStreamReadAsync)));
+
+    MutexLocker locker(stream->priv->readLock);
+
+    if (!webkitSoupRequestInputStreamHasDataToRead(stream) && !webkitSoupRequestInputStreamIsWaitingForData(stream)) {
+        g_simple_async_result_set_op_res_gssize(result.get(), 0);
+        g_simple_async_result_complete_in_idle(result.get());
+        return;
+    }
+
+    if (webkitSoupRequestInputStreamHasDataToRead(stream)) {
+        webkitSoupRequestInputStreamReadAsyncResultComplete(stream, result.get(), buffer, count, cancellable);
+        return;
+    }
+
+    stream->priv->pendingAsyncRead = adoptPtr(new AsyncReadData(result.get(), buffer, count, cancellable));
+}
+
+static gssize webkitSoupRequestInputStreamReadFinish(GInputStream* inputStream, GAsyncResult* result, GError** error)
+{
+    GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+    g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkitSoupRequestInputStreamReadAsync);
+
+    return g_simple_async_result_get_op_res_gssize(simpleResult);
+}
+
+static void webkitSoupRequestInputStreamFinalize(GObject* object)
+{
+    WEBKIT_SOUP_REQUEST_INPUT_STREAM(object)->priv->~WebKitSoupRequestInputStreamPrivate();
+    G_OBJECT_CLASS(webkit_soup_request_input_stream_parent_class)->finalize(object);
+}
+
+static void webkit_soup_request_input_stream_init(WebKitSoupRequestInputStream* stream)
+{
+    WebKitSoupRequestInputStreamPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(stream, WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM, WebKitSoupRequestInputStreamPrivate);
+    stream->priv = priv;
+    new (priv) WebKitSoupRequestInputStreamPrivate();
+}
+
+static void webkit_soup_request_input_stream_class_init(WebKitSoupRequestInputStreamClass* requestStreamClass)
+{
+    GObjectClass* gObjectClass = G_OBJECT_CLASS(requestStreamClass);
+    gObjectClass->finalize = webkitSoupRequestInputStreamFinalize;
+
+    GInputStreamClass* inputStreamClass = G_INPUT_STREAM_CLASS(requestStreamClass);
+    inputStreamClass->read_async = webkitSoupRequestInputStreamReadAsync;
+    inputStreamClass->read_finish = webkitSoupRequestInputStreamReadFinish;
+
+    g_type_class_add_private(requestStreamClass, sizeof(WebKitSoupRequestInputStreamPrivate));
+}
+
+GInputStream* webkitSoupRequestInputStreamNew(uint64_t contentLength)
+{
+    WebKitSoupRequestInputStream* stream = WEBKIT_SOUP_REQUEST_INPUT_STREAM(g_object_new(WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM, NULL));
+    stream->priv->contentLength = contentLength;
+    return G_INPUT_STREAM(stream);
+}
+
+void webkitSoupRequestInputStreamAddData(WebKitSoupRequestInputStream* stream, const void* data, size_t dataLength)
+{
+    if (webkitSoupRequestInputStreamFinished(stream))
+        return;
+
+    MutexLocker locker(stream->priv->readLock);
+
+    if (dataLength) {
+        // Truncate the dataLength to the contentLength if it's known.
+        if (stream->priv->contentLength && stream->priv->bytesReceived + dataLength > stream->priv->contentLength)
+            dataLength = stream->priv->contentLength - stream->priv->bytesReceived;
+        stream->priv->bytesReceived += dataLength;
+        g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(stream), g_memdup(data, dataLength), dataLength, g_free);
+    } else {
+        // We have received all the data, set contentLength to bytesReceived to indicate we have finished.
+        stream->priv->contentLength = stream->priv->bytesReceived;
+        // If there's a pending read to complete, read_fn will return 0 because we haven't added more data to the
+        // memory input stream. And if there isn't a pending read, the next call to read_async will return 0 too, because
+        // webkitSoupRequestInputStreamFinished() is now TRUE.
+    }
+
+    webkitSoupRequestInputStreamPendingReadAsyncComplete(stream);
+}
+
+bool webkitSoupRequestInputStreamFinished(WebKitSoupRequestInputStream* stream)
+{
+    return !webkitSoupRequestInputStreamIsWaitingForData(stream);
+}

Added: trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.h (0 => 116738)


--- trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.h	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.h	2012-05-11 08:14:39 UTC (rev 116738)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitSoupRequestInputStream_h
+#define WebKitSoupRequestInputStream_h
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM            (webkit_soup_request_input_stream_get_type())
+#define WEBKIT_SOUP_REQUEST_INPUT_STREAM(object)         (G_TYPE_CHECK_INSTANCE_CAST((object), WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM, WebKitSoupRequestInputStream))
+#define WEBKIT_IS_SOUP_REQUEST_INPUT_STREAM(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object), WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM))
+#define WEBKIT_SOUP_REQUEST_INPUT_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM, WebKitSoupRequestInputStreamClass))
+#define WEBKIT_IS_SOUP_REQUEST_INPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM))
+#define WEBKIT_SOUP_REQUEST_INPUT_STREAM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_SOUP_REQUEST_INPUT_STREAM, WebKitSoupRequestInputStreamClass))
+
+typedef struct _WebKitSoupRequestInputStream WebKitSoupRequestInputStream;
+typedef struct _WebKitSoupRequestInputStreamClass WebKitSoupRequestInputStreamClass;
+typedef struct _WebKitSoupRequestInputStreamPrivate WebKitSoupRequestInputStreamPrivate;
+
+struct _WebKitSoupRequestInputStream {
+    GMemoryInputStream parent;
+
+    WebKitSoupRequestInputStreamPrivate* priv;
+};
+
+struct _WebKitSoupRequestInputStreamClass {
+    GMemoryInputStreamClass parent;
+};
+
+GType webkit_soup_request_input_stream_get_type();
+GInputStream* webkitSoupRequestInputStreamNew(guint64 contentLength);
+void webkitSoupRequestInputStreamAddData(WebKitSoupRequestInputStream*, const void* data, size_t dataLength);
+bool webkitSoupRequestInputStreamFinished(WebKitSoupRequestInputStream*);
+
+G_END_DECLS
+
+#endif // WebKitSoupRequestInputStream_h

Modified: trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.cpp (116737 => 116738)


--- trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.cpp	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.cpp	2012-05-11 08:14:39 UTC (rev 116738)
@@ -23,6 +23,7 @@
 #include "DataReference.h"
 #include "MessageID.h"
 #include "WebKitSoupRequestGeneric.h"
+#include "WebKitSoupRequestInputStream.h"
 #include "WebProcess.h"
 #include "WebSoupRequestManagerProxyMessages.h"
 #include <WebCore/ErrorsGtk.h>
@@ -75,16 +76,25 @@
     soup_session_feature_add_feature(SOUP_SESSION_FEATURE(requester.get()), WEBKIT_TYPE_SOUP_REQUEST_GENERIC);
 }
 
-void WebSoupRequestManager::handleURIRequest(const CoreIPC::DataReference& requestData, const String& mimeType, uint64_t requestID)
+void WebSoupRequestManager::didHandleURIRequest(const CoreIPC::DataReference& requestData, uint64_t contentLength, const String& mimeType, uint64_t requestID)
 {
     GRefPtr<GSimpleAsyncResult> result = adoptGRef(m_requestMap.take(requestID));
     ASSERT(result.get());
 
     GRefPtr<WebKitSoupRequestGeneric> request = adoptGRef(WEBKIT_SOUP_REQUEST_GENERIC(g_async_result_get_source_object(G_ASYNC_RESULT(result.get()))));
     if (requestData.size()) {
-        webkitSoupRequestGenericSetContentLength(request.get(), requestData.size());
-        webkitSoupRequestGenericSetContentType(request.get(), mimeType.utf8().data());
-        GInputStream* dataStream = g_memory_input_stream_new_from_data(requestData.data(), requestData.size(), 0);
+        webkitSoupRequestGenericSetContentLength(request.get(), contentLength ? contentLength : -1);
+        webkitSoupRequestGenericSetContentType(request.get(), !mimeType.isEmpty() ? mimeType.utf8().data() : 0);
+
+        GInputStream* dataStream;
+        if (requestData.size() == contentLength) {
+            // We don't expect more data, so we can just create a GMemoryInputStream with all the data.
+            dataStream = g_memory_input_stream_new_from_data(g_memdup(requestData.data(), requestData.size()), contentLength, g_free);
+        } else {
+            dataStream = webkitSoupRequestInputStreamNew(contentLength);
+            webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size());
+            m_requestStreamMap.set(requestID, dataStream);
+        }
         g_simple_async_result_set_op_res_gpointer(result.get(), dataStream, g_object_unref);
     } else {
         GOwnPtr<char> uriString(soup_uri_to_string(soup_request_get_uri(SOUP_REQUEST(request.get())), FALSE));
@@ -96,6 +106,15 @@
     g_simple_async_result_complete(result.get());
 }
 
+void WebSoupRequestManager::didReceiveURIRequestData(const CoreIPC::DataReference& requestData, uint64_t requestID)
+{
+    GInputStream* dataStream = m_requestStreamMap.get(requestID);
+    ASSERT(dataStream);
+    webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size());
+    if (webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream)))
+        m_requestStreamMap.remove(requestID);
+}
+
 void WebSoupRequestManager::send(GSimpleAsyncResult* result)
 {
     GRefPtr<WebKitSoupRequestGeneric> request = adoptGRef(WEBKIT_SOUP_REQUEST_GENERIC(g_async_result_get_source_object(G_ASYNC_RESULT(result))));

Modified: trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.h (116737 => 116738)


--- trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.h	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.h	2012-05-11 08:14:39 UTC (rev 116738)
@@ -54,11 +54,13 @@
     void didReceiveWebSoupRequestManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 
     void registerURIScheme(const String& scheme);
-    void handleURIRequest(const CoreIPC::DataReference&, const String& mimeType, uint64_t requestID);
+    void didHandleURIRequest(const CoreIPC::DataReference&, uint64_t contentLength, const String& mimeType, uint64_t requestID);
+    void didReceiveURIRequestData(const CoreIPC::DataReference&, uint64_t requestID);
 
     WebProcess* m_process;
     GRefPtr<GPtrArray> m_schemes;
     HashMap<uint64_t, GSimpleAsyncResult*> m_requestMap;
+    HashMap<uint64_t, GInputStream*> m_requestStreamMap;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.messages.in (116737 => 116738)


--- trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.messages.in	2012-05-11 07:53:37 UTC (rev 116737)
+++ trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.messages.in	2012-05-11 08:14:39 UTC (rev 116738)
@@ -22,5 +22,6 @@
 
 messages -> WebSoupRequestManager {
     RegisterURIScheme(WTF::String uriScheme);
-    HandleURIRequest(CoreIPC::DataReference requestData, WTF::String mimeType, uint64_t requestID);
+    DidHandleURIRequest(CoreIPC::DataReference requestData, uint64_t contentLength, WTF::String mimeType, uint64_t requestID);
+    DidReceiveURIRequestData(CoreIPC::DataReference requestData, uint64_t requestID);
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to