[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

mrobinson at webkit.org mrobinson at webkit.org
Wed Dec 22 14:32:23 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit a6925c9720b53f98bedb231fce99abed1f453ac2
Author: mrobinson at webkit.org <mrobinson at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 12 21:44:43 2010 +0000

    2010-10-12  Sheriff Bot  <webkit.review.bot at gmail.com>
    
            Unreviewed, rolling out r69589.
            http://trac.webkit.org/changeset/69589
            https://bugs.webkit.org/show_bug.cgi?id=47547
    
            Wrong patch landed from a bug with two patches (Requested by
            mrobinson on #webkit).
    
            * platform/network/ResourceHandleInternal.h:
            (WebCore::ResourceHandleInternal::ResourceHandleInternal):
            * platform/network/soup/ResourceHandleSoup.cpp:
            (WebCore::ResourceHandleInternal::~ResourceHandleInternal):
            (WebCore::ResourceHandle::~ResourceHandle):
            (WebCore::restartedCallback):
            (WebCore::gotChunkCallback):
            (WebCore::finishedCallback):
            (WebCore::parseDataUrl):
            (WebCore::startHttp):
            * platform/network/soup/ResourceRequest.h:
            * platform/network/soup/ResourceRequestSoup.cpp:
    2010-10-12  Sheriff Bot  <webkit.review.bot at gmail.com>
    
            Unreviewed, rolling out r69589.
            http://trac.webkit.org/changeset/69589
            https://bugs.webkit.org/show_bug.cgi?id=47547
    
            Wrong patch landed from a bug with two patches (Requested by
            mrobinson on #webkit).
    
            * webkit/webkitdownload.cpp:
            (webkit_download_new_with_handle):
            (webkit_download_start):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69606 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index f38b308..0c6c5f3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,25 @@
+2010-10-12  Sheriff Bot  <webkit.review.bot at gmail.com>
+
+        Unreviewed, rolling out r69589.
+        http://trac.webkit.org/changeset/69589
+        https://bugs.webkit.org/show_bug.cgi?id=47547
+
+        Wrong patch landed from a bug with two patches (Requested by
+        mrobinson on #webkit).
+
+        * platform/network/ResourceHandleInternal.h:
+        (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+        * platform/network/soup/ResourceHandleSoup.cpp:
+        (WebCore::ResourceHandleInternal::~ResourceHandleInternal):
+        (WebCore::ResourceHandle::~ResourceHandle):
+        (WebCore::restartedCallback):
+        (WebCore::gotChunkCallback):
+        (WebCore::finishedCallback):
+        (WebCore::parseDataUrl):
+        (WebCore::startHttp):
+        * platform/network/soup/ResourceRequest.h:
+        * platform/network/soup/ResourceRequestSoup.cpp:
+
 2010-10-12  Simon Fraser  <simon.fraser at apple.com>
 
         Screen.availLeft should be signed
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index 9cccecd..96fbf00 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -46,8 +46,6 @@
 #endif
 
 #if USE(SOUP)
-#include "soup-requester.h"
-#include <GRefPtr.h>
 #include <libsoup/soup.h>
 class Frame;
 #endif
@@ -110,11 +108,15 @@ namespace WebCore {
             , m_formDataStream(loader)
 #endif
 #if USE(SOUP)
+            , m_msg(0)
             , m_cancelled(false)
+            , m_gfile(0)
+            , m_inputStream(0)
+            , m_cancellable(0)
             , m_buffer(0)
+            , m_bufferSize(0)
             , m_total(0)
             , m_idleHandler(0)
-            , m_gotChunkHandler(0)
 #endif
 #if PLATFORM(QT)
             , m_job(0)
@@ -131,9 +133,6 @@ namespace WebCore {
             m_user = url.user();
             m_pass = url.pass();
             m_firstRequest.removeCredentials();
-#if USE(SOUP)
-            m_requester = adoptPlatformRef(webkit_soup_requester_new());
-#endif
         }
         
         ~ResourceHandleInternal();
@@ -186,18 +185,16 @@ namespace WebCore {
         Vector<char> m_postBytes;
 #endif
 #if USE(SOUP)
-        PlatformRefPtr<SoupMessage> m_soupMessage;
+        SoupMessage* m_msg;
         ResourceResponse m_response;
         bool m_cancelled;
-        PlatformRefPtr<WebKitSoupRequest> m_soupRequest;
-        PlatformRefPtr<WebKitSoupRequester> m_requester;
-        PlatformRefPtr<GInputStream> m_inputStream;
-        PlatformRefPtr<GCancellable> m_cancellable;
+        GFile* m_gfile;
+        GInputStream* m_inputStream;
+        GCancellable* m_cancellable;
         char* m_buffer;
-        gsize m_total;
+        gsize m_bufferSize, m_total;
         guint m_idleHandler;
         RefPtr<NetworkingContext> m_context;
-        gulong m_gotChunkHandler;
 #endif
 #if PLATFORM(QT)
         QNetworkReplyHandler* m_job;
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index f768d8f..0d84388 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -45,8 +45,8 @@
 #include "ResourceHandleInternal.h"
 #include "ResourceResponse.h"
 #include "SharedBuffer.h"
-#include "soup-request-http.h"
 #include "TextEncoding.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <gio/gio.h>
@@ -58,8 +58,6 @@
 
 namespace WebCore {
 
-#define READ_BUFFER_SIZE 8192
-
 class WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable {
 public:
     WebCoreSynchronousLoader(ResourceError&, ResourceResponse &, Vector<char>&);
@@ -122,16 +120,16 @@ void WebCoreSynchronousLoader::run()
         g_main_loop_run(m_mainLoop);
 }
 
-static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying);
-static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
-static void readCallback(GObject*, GAsyncResult*, gpointer);
-static void closeCallback(GObject*, GAsyncResult*, gpointer);
-static bool startGio(ResourceHandle*, KURL);
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying);
+static bool startData(ResourceHandle* handle, String urlString);
+static bool startGio(ResourceHandle* handle, KURL url);
 
 ResourceHandleInternal::~ResourceHandleInternal()
 {
-    if (m_soupRequest)
-        g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0);
+    if (m_msg) {
+        g_object_unref(m_msg);
+        m_msg = 0;
+    }
 
     if (m_idleHandler) {
         g_source_remove(m_idleHandler);
@@ -141,7 +139,11 @@ ResourceHandleInternal::~ResourceHandleInternal()
 
 ResourceHandle::~ResourceHandle()
 {
-    cleanupSoupRequestOperation(this, true);
+    if (d->m_msg)
+        g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
+                                             0, 0, 0, 0, this);
+
+    cleanupGioOperation(this, true);
 }
 
 void ResourceHandle::prepareForURL(const KURL &url)
@@ -183,8 +185,9 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
     if (d->m_cancelled)
         return;
 
-    GOwnPtr<char> uri(soup_uri_to_string(soup_message_get_uri(msg), false));
-    String location = String::fromUTF8(uri.get());
+    char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
+    String location = String(uri);
+    g_free(uri);
     KURL newURL = KURL(handle->firstRequest().url(), location);
 
     ResourceRequest request = handle->firstRequest();
@@ -210,7 +213,7 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
     String firstPartyString = request.firstPartyForCookies().string();
     if (!firstPartyString.isEmpty()) {
         GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
-        soup_message_set_first_party(d->m_soupMessage.get(), firstParty.get());
+        soup_message_set_first_party(d->m_msg, firstParty.get());
     }
 #endif
 }
@@ -290,9 +293,53 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
         return;
 
     client->didReceiveData(handle.get(), chunk->data, chunk->length, false);
+}
+
+// Called at the end of the message, with all the necessary about the last informations.
+// Doesn't get called for redirects.
+static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
+{
+    RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data));
+    // TODO: maybe we should run this code even if there's no client?
+    if (!handle)
+        return;
+
+    ResourceHandleInternal* d = handle->getInternal();
+
+    ResourceHandleClient* client = handle->client();
+    if (!client)
+        return;
 
+    if (d->m_cancelled)
+        return;
+
+    if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
+        char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
+        ResourceError error(g_quark_to_string(SOUP_HTTP_ERROR),
+                            msg->status_code,
+                            uri,
+                            String::fromUTF8(msg->reason_phrase));
+        g_free(uri);
+        client->didFail(handle.get(), error);
+        return;
+    }
+
+    if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
+        fillResponseFromMessage(msg, &d->m_response);
+        client->didReceiveResponse(handle.get(), d->m_response);
+
+        // WebCore might have cancelled the job in the while
+        if (d->m_cancelled)
+            return;
+
+        if (msg->response_body->data)
+            client->didReceiveData(handle.get(), msg->response_body->data, msg->response_body->length, true);
+    }
+
+    client->didFinishLoading(handle.get(), 0);
 }
 
+// parseDataUrl() is taken from the CURL http backend.
 static gboolean parseDataUrl(gpointer callbackData)
 {
     ResourceHandle* handle = static_cast<ResourceHandle*>(callbackData);
@@ -317,6 +364,7 @@ static gboolean parseDataUrl(gpointer callbackData)
     }
 
     String mediaType = url.substring(5, index - 5);
+    String data = url.substring(index + 1);
 
     bool isBase64 = mediaType.endsWith(";base64", false);
     if (isBase64)
@@ -332,41 +380,42 @@ static gboolean parseDataUrl(gpointer callbackData)
     response.setURL(handle->firstRequest().url());
     response.setMimeType(mimeType);
 
-    // For non base64 encoded data we have to convert to UTF-16 early
-    // due to limitations in KURL
-    response.setTextEncodingName(isBase64 ? charset : "UTF-16");
-    client->didReceiveResponse(handle, response);
+    if (isBase64) {
+        data = decodeURLEscapeSequences(data);
+        response.setTextEncodingName(charset);
+        client->didReceiveResponse(handle, response);
+
+        // The load may be cancelled, and the client may be destroyed
+        // by any of the client reporting calls, so we check, and bail
+        // out in either of those cases.
+        if (d->m_cancelled || !handle->client())
+            return false;
+
+        // Use the GLib Base64, since WebCore's decoder isn't
+        // general-purpose and fails on Acid3 test 97 (whitespace).
+        size_t outLength = 0;
+        char* outData = 0;
+        outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength));
+        if (outData && outLength > 0)
+            client->didReceiveData(handle, outData, outLength, 0);
+        g_free(outData);
+    } else {
+        // We have to convert to UTF-16 early due to limitations in KURL
+        data = decodeURLEscapeSequences(data, TextEncoding(charset));
+        response.setTextEncodingName("UTF-16");
+        client->didReceiveResponse(handle, response);
+
+        if (d->m_cancelled || !handle->client())
+            return false;
+
+        if (data.length() > 0)
+            client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
+    }
 
-    // The load may be cancelled, and the client may be destroyed
-    // by any of the client reporting calls, so we check, and bail
-    // out in either of those cases.
     if (d->m_cancelled || !handle->client())
         return false;
 
-    SoupSession* session = handle->defaultSession();
-    GOwnPtr<GError> error;
-    d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), handle->firstRequest().url().string().utf8().data(), session, &error.outPtr()));
-    if (error) {
-        d->m_soupRequest = 0;
-        return false;
-    }
-
-    d->m_inputStream = adoptPlatformRef(webkit_soup_request_send(d->m_soupRequest.get(), 0, &error.outPtr()));
-    if (error) {
-        d->m_inputStream = 0;
-        return false;
-    }
-
-    d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE));
-    d->m_total = 0;
-
-    g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle);
-    // balanced by a deref() in cleanupSoupRequestOperation, which should always run
-    handle->ref();
-
-    d->m_cancellable = adoptPlatformRef(g_cancellable_new());
-    g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT,
-                              d->m_cancellable.get(), readCallback, GINT_TO_POINTER(!isBase64));
+    client->didFinishLoading(handle, 0);
 
     return false;
 }
@@ -420,132 +469,6 @@ static void ensureSessionIsInitialized(SoupSession* session)
     g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
 }
 
-static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying = false)
-{
-    ResourceHandleInternal* d = handle->getInternal();
-
-    if (d->m_soupRequest) {
-        g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", 0);
-        d->m_soupRequest.clear();
-    }
-
-    if (d->m_inputStream) {
-        g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", 0);
-        d->m_inputStream.clear();
-    }
-
-    d->m_cancellable.clear();
-
-    if (d->m_soupMessage) {
-        g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA,
-                                             0, 0, 0, 0, handle);
-        d->m_soupMessage.clear();
-    }
-
-    if (d->m_buffer) {
-        g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);
-        d->m_buffer = 0;
-    }
-
-    if (!isDestroying)
-        handle->deref();
-}
-
-static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer userData)
-{
-    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
-    if (!handle)
-        return;
-
-    ResourceHandleInternal* d = handle->getInternal();
-    ResourceHandleClient* client = handle->client();
-
-    if (d->m_gotChunkHandler) {
-        // No need to call gotChunkHandler anymore. Received data will
-        // be reported by readCallback
-        if (g_signal_handler_is_connected(d->m_soupMessage.get(), d->m_gotChunkHandler))
-            g_signal_handler_disconnect(d->m_soupMessage.get(), d->m_gotChunkHandler);
-    }
-
-    if (d->m_cancelled || !client) {
-        cleanupSoupRequestOperation(handle.get());
-        return;
-    }
-
-    GOwnPtr<GError> error;
-    GInputStream* in = webkit_soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr());
-
-    if (error) {
-        SoupMessage* soupMsg = d->m_soupMessage.get();
-        gboolean isTransportError = d->m_soupMessage && SOUP_STATUS_IS_TRANSPORT_ERROR(soupMsg->status_code);
-
-        if (isTransportError || (error->domain == G_IO_ERROR)) {
-            SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get());
-            GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
-            gint errorCode = isTransportError ? soupMsg->status_code : error->code;
-            const gchar* errorMsg = isTransportError ? soupMsg->reason_phrase : error->message;
-            const gchar* quarkStr = isTransportError ? g_quark_to_string(SOUP_HTTP_ERROR) : g_quark_to_string(G_IO_ERROR);
-            ResourceError resourceError(quarkStr, errorCode, uriStr.get(), String::fromUTF8(errorMsg));
-
-            cleanupSoupRequestOperation(handle.get());
-            client->didFail(handle.get(), resourceError);
-            return;
-        }
-
-        if (d->m_soupMessage && soupMessage->status_code == SOUP_STATUS_UNAUTHORIZED) {
-            fillResponseFromMessage(soupMsg, &d->m_response);
-            client->didReceiveResponse(handle.get(), d->m_response);
-
-            // WebCore might have cancelled the job in the while
-            if (!d->m_cancelled && soupMsg->response_body->data)
-                client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true);
-        }
-
-        // didReceiveData above might have cancelled it
-        if (d->m_cancelled || !client) {
-            cleanupSoupRequestOperation(handle.get());
-            return;
-        }
-
-        client->didFinishLoading(handle.get(), 0);
-        return;
-    }
-
-    if (d->m_cancelled) {
-        cleanupSoupRequestOperation(handle.get());
-        return;
-    }
-
-    d->m_inputStream = adoptPlatformRef(in);
-    d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE));
-    d->m_total = 0;
-
-    // readCallback needs it
-    g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get());
-
-    // We need to check if it's a file: URL and if it is a regular
-    // file as it could be a directory. In that case Soup properly
-    // returns a stream whose content is a HTML with a list of files
-    // in the directory
-    if (equalIgnoringCase(handle->firstRequest().url().protocol(), "file")
-        && G_IS_FILE_INPUT_STREAM(in)) {
-        ResourceResponse response;
-
-        response.setURL(handle->firstRequest().url());
-        response.setMimeType(webkit_soup_request_get_content_type(d->m_soupRequest.get()));
-        response.setExpectedContentLength(webkit_soup_request_get_content_length(d->m_soupRequest.get()));
-        client->didReceiveResponse(handle.get(), response);
-
-        if (d->m_cancelled) {
-            cleanupSoupRequestOperation(handle.get());
-            return;
-        }
-    }
-
-    g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE,
-                              G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, 0);
-}
-
 static bool startHttp(ResourceHandle* handle)
 {
     ASSERT(handle);
@@ -560,37 +483,26 @@ static bool startHttp(ResourceHandle* handle)
     url.removeFragmentIdentifier();
     request.setURL(url);
 
-    GOwnPtr<GError> error;
-    d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), url.string().utf8().data(), session, &error.outPtr()));
-    if (error) {
-        d->m_soupRequest = 0;
+    d->m_msg = request.toSoupMessage();
+    if (!d->m_msg)
         return false;
-    }
-
-    g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
-
-    d->m_soupMessage = adoptPlatformRef(webkit_soup_request_http_get_message(WEBKIT_SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
-    if (!d->m_soupMessage)
-        return false;
-
-    SoupMessage* soupMessage = d->m_soupMessage.get();
-    request.updateSoupMessage(soupMessage);
 
     if (!handle->shouldContentSniff())
-        soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
+        soup_message_disable_feature(d->m_msg, SOUP_TYPE_CONTENT_SNIFFER);
 
-    g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle);
-    g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
-    g_signal_connect(soupMessage, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);
-    d->m_gotChunkHandler = g_signal_connect(soupMessage, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
+    g_signal_connect(d->m_msg, "restarted", G_CALLBACK(restartedCallback), handle);
+    g_signal_connect(d->m_msg, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
+    g_signal_connect(d->m_msg, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);
+    g_signal_connect(d->m_msg, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
 
 #ifdef HAVE_LIBSOUP_2_29_90
     String firstPartyString = request.firstPartyForCookies().string();
     if (!firstPartyString.isEmpty()) {
         GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
-        soup_message_set_first_party(soupMessage, firstParty.get());
+        soup_message_set_first_party(d->m_msg, firstParty.get());
     }
 #endif
+    g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle));
 
     FormData* httpBody = d->m_firstRequest.httpBody();
     if (httpBody && !httpBody->isEmpty()) {
@@ -600,7 +512,7 @@ static bool startHttp(ResourceHandle* handle)
         if (numElements < 2) {
             Vector<char> body;
             httpBody->flatten(body);
-            soup_message_set_request(soupMessage, d->m_firstRequest.httpContentType().utf8().data(),
+            soup_message_set_request(d->m_msg, d->m_firstRequest.httpContentType().utf8().data(),
                                      SOUP_MEMORY_COPY, body.data(), body.size());
         } else {
             /*
@@ -609,25 +521,27 @@ static bool startHttp(ResourceHandle* handle)
              * copying into memory; TODO: support upload of non-local
              * (think sftp://) files by using GIO?
              */
-            soup_message_body_set_accumulate(soupMessage->request_body, FALSE);
+            soup_message_body_set_accumulate(d->m_msg->request_body, FALSE);
             for (size_t i = 0; i < numElements; i++) {
                 const FormDataElement& element = httpBody->elements()[i];
 
                 if (element.m_type == FormDataElement::data)
-                    soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
+                    soup_message_body_append(d->m_msg->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
                 else {
                     /*
                      * mapping for uploaded files code inspired by technique used in
                      * libsoup's simple-httpd test
                      */
-                    GOwnPtr<GError> error;
+                    GError* error = 0;
                     CString fileName = fileSystemRepresentation(element.m_filename);
-                    GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr());
+                    GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error);
 
                     if (error) {
-                        g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA,
+                        g_error_free(error);
+                        g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
                                                              0, 0, 0, 0, handle);
-                        d->m_soupMessage.clear();
+                        g_object_unref(d->m_msg);
+                        d->m_msg = 0;
 
                         return false;
                     }
@@ -635,31 +549,38 @@ static bool startHttp(ResourceHandle* handle)
                     SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping),
                                                                         g_mapped_file_get_length(fileMapping),
                                                                         fileMapping,
+#if GLIB_CHECK_VERSION(2, 21, 3)
                                                                         reinterpret_cast<GDestroyNotify>(g_mapped_file_unref));
-                    soup_message_body_append_buffer(soupMessage->request_body, soupBuffer);
+#else
+                                                                        reinterpret_cast<GDestroyNotify>(g_mapped_file_free));
+#endif
+                    soup_message_body_append_buffer(d->m_msg->request_body, soupBuffer);
                     soup_buffer_free(soupBuffer);
                 }
             }
         }
     }
 
-    // balanced by a deref() in cleanupSoupRequestOperation, which should always run
+    // balanced by a deref() in finishedCallback, which should always run
     handle->ref();
 
     // Make sure we have an Accept header for subresources; some sites
     // want this to serve some of their subresources
-    if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
-        soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
+    if (!soup_message_headers_get_one(d->m_msg->request_headers, "Accept"))
+        soup_message_headers_append(d->m_msg->request_headers, "Accept", "*/*");
 
-    d->m_cancellable = adoptPlatformRef(g_cancellable_new());
-    webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
+    // Balanced in ResourceHandleInternal's destructor; we need to
+    // keep our own ref, because after queueing the message, the
+    // session owns the initial reference.
+    g_object_ref(d->m_msg);
+    soup_session_queue_message(session, d->m_msg, finishedCallback, handle);
 
     return true;
 }
 
 bool ResourceHandle::start(NetworkingContext* context)
 {
-    ASSERT(!d->m_soupMessage);
+    ASSERT(!d->m_msg);
 
     // The frame could be null if the ResourceHandle is not associated to any
     // Frame, e.g. if we are downloading a file.
@@ -699,10 +620,10 @@ bool ResourceHandle::start(NetworkingContext* context)
 void ResourceHandle::cancel()
 {
     d->m_cancelled = true;
-    if (d->m_soupMessage)
-        soup_session_cancel_message(defaultSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED);
+    if (d->m_msg)
+        soup_session_cancel_message(defaultSession(), d->m_msg, SOUP_STATUS_CANCELLED);
     else if (d->m_cancellable)
-        g_cancellable_cancel(d->m_cancellable.get());
+        g_cancellable_cancel(d->m_cancellable);
 }
 
 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
@@ -746,6 +667,38 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const
     syncLoader.run();
 }
 
+// GIO-based loader
+
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false)
+{
+    ResourceHandleInternal* d = handle->getInternal();
+
+    if (d->m_gfile) {
+        g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);
+        g_object_unref(d->m_gfile);
+        d->m_gfile = 0;
+    }
+
+    if (d->m_cancellable) {
+        g_object_unref(d->m_cancellable);
+        d->m_cancellable = 0;
+    }
+
+    if (d->m_inputStream) {
+        g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", 0);
+        g_object_unref(d->m_inputStream);
+        d->m_inputStream = 0;
+    }
+
+    if (d->m_buffer) {
+        g_free(d->m_buffer);
+        d->m_buffer = 0;
+    }
+
+    if (!isDestroying)
+        handle->deref();
+}
+
 static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
 {
     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
@@ -755,8 +708,8 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
     ResourceHandleInternal* d = handle->getInternal();
     ResourceHandleClient* client = handle->client();
 
-    g_input_stream_close_finish(d->m_inputStream.get(), res, 0);
-    cleanupSoupRequestOperation(handle.get());
+    g_input_stream_close_finish(d->m_inputStream, res, 0);
+    cleanupGioOperation(handle.get());
 
     // The load may have been cancelled, the client may have been
     // destroyed already. In such cases calling didFinishLoading is a
@@ -767,92 +720,210 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
     client->didFinishLoading(handle.get(), 0);
 }
 
-static void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer data)
+static void readCallback(GObject* source, GAsyncResult* res, gpointer)
 {
     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
     if (!handle)
         return;
 
-    bool convertToUTF16 = static_cast<bool>(data);
     ResourceHandleInternal* d = handle->getInternal();
     ResourceHandleClient* client = handle->client();
 
     if (d->m_cancelled || !client) {
-        cleanupSoupRequestOperation(handle.get());
+        cleanupGioOperation(handle.get());
         return;
     }
 
-    GOwnPtr<GError> error;
+    GError* error = 0;
 
-    gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
+    gssize bytesRead = g_input_stream_read_finish(d->m_inputStream, res, &error);
     if (error) {
-        SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get());
-        GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
-        ResourceError resourceError(g_quark_to_string(G_IO_ERROR), error->code, uriStr.get(),
+        char* uri = g_file_get_uri(d->m_gfile);
+        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
+                                    error->code,
+                                    uri,
                                     error ? String::fromUTF8(error->message) : String());
-        cleanupSoupRequestOperation(handle.get());
+        g_free(uri);
+        g_error_free(error);
+        cleanupGioOperation(handle.get());
         client->didFail(handle.get(), resourceError);
         return;
     }
 
     if (!bytesRead) {
-        g_input_stream_close_async(d->m_inputStream.get(), G_PRIORITY_DEFAULT,
+        g_input_stream_close_async(d->m_inputStream, G_PRIORITY_DEFAULT,
                                    0, closeCallback, 0);
         return;
     }
 
     d->m_total += bytesRead;
-    if (G_LIKELY(!convertToUTF16))
-        client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
-    else {
-        // We have to convert it to UTF-16 due to limitations in KURL
-        String data = String::fromUTF8(d->m_buffer, bytesRead);
-        client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
-    }
+    client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
 
     // didReceiveData may cancel the load, which may release the last reference.
+    if (d->m_cancelled) {
+        cleanupGioOperation(handle.get());
+        return;
+    }
+
+    g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
+                              G_PRIORITY_DEFAULT, d->m_cancellable,
+                              readCallback, 0);
+}
+
+static void openCallback(GObject* source, GAsyncResult* res, gpointer)
+{
+    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+    if (!handle)
+        return;
+
+    ResourceHandleInternal* d = handle->getInternal();
+    ResourceHandleClient* client = handle->client();
+
     if (d->m_cancelled || !client) {
-        cleanupSoupRequestOperation(handle.get());
+        cleanupGioOperation(handle.get());
+        return;
+    }
+
+    GError* error = 0;
+    GFileInputStream* in = g_file_read_finish(G_FILE(source), res, &error);
+    if (error) {
+        char* uri = g_file_get_uri(d->m_gfile);
+        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
+                                    error->code,
+                                    uri,
+                                    error ? String::fromUTF8(error->message) : String());
+        g_free(uri);
+        g_error_free(error);
+        cleanupGioOperation(handle.get());
+        client->didFail(handle.get(), resourceError);
         return;
     }
 
-    g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT,
-                              d->m_cancellable.get(), readCallback, data);
+    d->m_inputStream = G_INPUT_STREAM(in);
+    d->m_bufferSize = 8192;
+    d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize));
+    d->m_total = 0;
+
+    g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get());
+    g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
+                              G_PRIORITY_DEFAULT, d->m_cancellable,
+                              readCallback, 0);
 }
 
+static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
+{
+    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+    if (!handle)
+        return;
+
+    ResourceHandleInternal* d = handle->getInternal();
+    ResourceHandleClient* client = handle->client();
+
+    if (d->m_cancelled) {
+        cleanupGioOperation(handle.get());
+        return;
+    }
+
+    ResourceResponse response;
+
+    char* uri = g_file_get_uri(d->m_gfile);
+    response.setURL(KURL(KURL(), uri));
+    g_free(uri);
+
+    GError* error = 0;
+    GFileInfo* info = g_file_query_info_finish(d->m_gfile, res, &error);
+
+    if (error) {
+        // FIXME: to be able to handle ftp URIs properly, we must
+        // check if the error is G_IO_ERROR_NOT_MOUNTED, and if so,
+        // call g_file_mount_enclosing_volume() to mount the ftp
+        // server (and then keep track of the fact that we mounted it,
+        // and set a timeout to unmount it later after it's been idle
+        // for a while).
+        char* uri = g_file_get_uri(d->m_gfile);
+        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
+                                    error->code,
+                                    uri,
+                                    error ? String::fromUTF8(error->message) : String());
+        g_free(uri);
+        g_error_free(error);
+        cleanupGioOperation(handle.get());
+        client->didFail(handle.get(), resourceError);
+        return;
+    }
+
+    if (g_file_info_get_file_type(info) != G_FILE_TYPE_REGULAR) {
+        // FIXME: what if the URI points to a directory? Should we
+        // generate a listing? How? What do other backends do here?
+        char* uri = g_file_get_uri(d->m_gfile);
+        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
+                                    G_IO_ERROR_FAILED,
+                                    uri,
+                                    String());
+        g_free(uri);
+        cleanupGioOperation(handle.get());
+        client->didFail(handle.get(), resourceError);
+        return;
+    }
+
+    // According to http://library.gnome.org/devel/gio/stable/gio-GContentType.html
+    // GContentType on Unix is the mime type, but not on Win32.
+    GOwnPtr<gchar> mimeType(g_content_type_get_mime_type(g_file_info_get_content_type(info)));
+    response.setMimeType(mimeType.get());
+    response.setExpectedContentLength(g_file_info_get_size(info));
+
+    GTimeVal tv;
+    g_file_info_get_modification_time(info, &tv);
+    response.setLastModifiedDate(tv.tv_sec);
+
+    client->didReceiveResponse(handle.get(), response);
+
+    if (d->m_cancelled) {
+        cleanupGioOperation(handle.get());
+        return;
+    }
+
+    g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
+                      openCallback, 0);
+}
 static bool startGio(ResourceHandle* handle, KURL url)
 {
     ASSERT(handle);
 
+    ResourceHandleInternal* d = handle->getInternal();
+
     if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
         return false;
 
-    SoupSession* session = handle->defaultSession();
-    ResourceHandleInternal* d = handle->getInternal();
-
     // GIO doesn't know how to handle refs and queries, so remove them
     // TODO: use KURL.fileSystemPath after KURLGtk and FileSystemGtk are
     // using GIO internally, and providing URIs instead of file paths
     url.removeFragmentIdentifier();
     url.setQuery(String());
     url.removePort();
-    CString urlStr = url.string().utf8();
-
-    GOwnPtr<GError> error;
-    d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), urlStr.data(), session, &error.outPtr()));
-    if (error) {
-        d->m_soupRequest = 0;
-        return false;
-    }
 
-    g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
+#if !OS(WINDOWS)
+    // we avoid the escaping for local files, because
+    // g_filename_from_uri (used internally by GFile) has problems
+    // decoding strings with arbitrary percent signs
+    if (url.isLocalFile())
+        d->m_gfile = g_file_new_for_path(url.prettyURL().utf8().data() + sizeof("file://") - 1);
+    else
+#endif
+        d->m_gfile = g_file_new_for_uri(url.string().utf8().data());
+    g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle);
 
-    // balanced by a deref() in cleanupSoupRequestOperation, which should always run
+    // balanced by a deref() in cleanupGioOperation, which should always run
     handle->ref();
 
-    d->m_cancellable = adoptPlatformRef(g_cancellable_new());
-    webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
-
+    d->m_cancellable = g_cancellable_new();
+    g_file_query_info_async(d->m_gfile,
+                            G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+                            G_FILE_ATTRIBUTE_STANDARD_SIZE,
+                            G_FILE_QUERY_INFO_NONE,
+                            G_PRIORITY_DEFAULT, d->m_cancellable,
+                            queryInfoCallback, 0);
     return true;
 }
 
diff --git a/WebCore/platform/network/soup/ResourceRequest.h b/WebCore/platform/network/soup/ResourceRequest.h
index 879a47f..c2c4419 100644
--- a/WebCore/platform/network/soup/ResourceRequest.h
+++ b/WebCore/platform/network/soup/ResourceRequest.h
@@ -67,9 +67,8 @@ namespace WebCore {
             updateFromSoupMessage(soupMessage);
         }
 
-        void updateSoupMessage(SoupMessage*) const;
         SoupMessage* toSoupMessage() const;
-        void updateFromSoupMessage(SoupMessage*);
+        void updateFromSoupMessage(SoupMessage* soupMessage);
 
         SoupMessageFlags soupMessageFlags() const { return m_soupFlags; }
         void setSoupMessageFlags(SoupMessageFlags soupFlags) { m_soupFlags = soupFlags; }
diff --git a/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
index 380fc84..62deb01 100644
--- a/WebCore/platform/network/soup/ResourceRequestSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
@@ -33,29 +33,6 @@ using namespace std;
 
 namespace WebCore {
 
-void ResourceRequest::updateSoupMessage(SoupMessage* soupMessage) const
-{
-    g_object_set(soupMessage, SOUP_MESSAGE_METHOD, httpMethod().utf8().data(), NULL);
-
-    const HTTPHeaderMap& headers = httpHeaderFields();
-    SoupMessageHeaders* soupHeaders = soupMessage->request_headers;
-    if (!headers.isEmpty()) {
-        HTTPHeaderMap::const_iterator end = headers.end();
-        for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
-            soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
-    }
-
-#ifdef HAVE_LIBSOUP_2_29_90
-    String firstPartyString = firstPartyForCookies().string();
-    if (!firstPartyString.isEmpty()) {
-        GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
-        soup_message_set_first_party(soupMessage, firstParty.get());
-    }
-#endif
-
-    soup_message_set_flags(soupMessage, m_soupFlags);
-}
-
 SoupMessage* ResourceRequest::toSoupMessage() const
 {
     SoupMessage* soupMessage = soup_message_new(httpMethod().utf8().data(), url().string().utf8().data());
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index 7adcd00..34d3e7b 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,16 @@
+2010-10-12  Sheriff Bot  <webkit.review.bot at gmail.com>
+
+        Unreviewed, rolling out r69589.
+        http://trac.webkit.org/changeset/69589
+        https://bugs.webkit.org/show_bug.cgi?id=47547
+
+        Wrong patch landed from a bug with two patches (Requested by
+        mrobinson on #webkit).
+
+        * webkit/webkitdownload.cpp:
+        (webkit_download_new_with_handle):
+        (webkit_download_start):
+
 2010-10-12  Sergio Villar Senin  <svillar at igalia.com>
 
         Reviewed by Martin Robinson.
diff --git a/WebKit/gtk/webkit/webkitdownload.cpp b/WebKit/gtk/webkit/webkitdownload.cpp
index 18b64ab..1472cb5 100644
--- a/WebKit/gtk/webkit/webkitdownload.cpp
+++ b/WebKit/gtk/webkit/webkitdownload.cpp
@@ -419,8 +419,8 @@ WebKitDownload* webkit_download_new_with_handle(WebKitNetworkRequest* request, W
     g_return_val_if_fail(request, NULL);
 
     ResourceHandleInternal* d = handle->getInternal();
-    if (d->m_soupMessage)
-        soup_session_pause_message(webkit_get_default_session(), d->m_soupMessage.get());
+    if (d->m_msg)
+        soup_session_pause_message(webkit_get_default_session(), d->m_msg);
 
     WebKitDownload* download = WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, "network-request", request, NULL));
     WebKitDownloadPrivate* priv = download->priv;
@@ -492,8 +492,8 @@ void webkit_download_start(WebKitDownload* download)
         priv->resourceHandle->setClient(priv->downloadClient);
 
         ResourceHandleInternal* d = priv->resourceHandle->getInternal();
-        if (d->m_soupMessage)
-            soup_session_unpause_message(webkit_get_default_session(), d->m_soupMessage.get());
+        if (d->m_msg)
+            soup_session_unpause_message(webkit_get_default_session(), d->m_msg);
     }
 
     priv->timer = g_timer_new();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list