diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index f20f055..5816c61 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -116,6 +116,7 @@ namespace WebCore {
             , m_msg(0)
             , m_cancelled(false)
             , m_gfile(0)
+            , m_req(0)
             , m_inputStream(0)
             , m_cancellable(0)
             , m_buffer(0)
@@ -198,6 +199,7 @@ namespace WebCore {
         ResourceResponse m_response;
         bool m_cancelled;
         GFile* m_gfile;
+        SoupRequest* m_req;
         GInputStream* m_inputStream;
         GCancellable* m_cancellable;
         char* m_buffer;
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 90a842e..91bf399 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -120,8 +120,11 @@ void WebCoreSynchronousLoader::run()
         g_main_loop_run(m_mainLoop);
 }
 
+static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying);
+static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer);
+static void readCallback(GObject* source, GAsyncResult* res, gpointer);
+
 static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying);
-static bool startData(ResourceHandle* handle, String urlString);
 static bool startGio(ResourceHandle* handle, KURL url);
 
 ResourceHandleInternal::~ResourceHandleInternal()
@@ -131,6 +134,12 @@ ResourceHandleInternal::~ResourceHandleInternal()
         m_msg = 0;
     }
 
+    if (m_req) {
+        g_object_set_data(G_OBJECT(m_req), "webkit-resource", 0);
+        g_object_unref(m_req);
+        m_req = 0;
+    }
+
     if (m_idleHandler) {
         g_source_remove(m_idleHandler);
         m_idleHandler = 0;
@@ -293,50 +302,7 @@ 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());
 }
 
 // parseDataUrl() is taken from the CURL http backend.
@@ -428,7 +394,7 @@ static bool startData(ResourceHandle* handle, String urlString)
 
     // If parseDataUrl is called synchronously the job is not yet effectively started
     // and webkit won't never know that the data has been parsed even didFinishLoading is called.
-    d->m_idleHandler = g_timeout_add(0, parseDataUrl, handle);
+    d->m_idleHandler = g_idle_add(parseDataUrl, handle);
     return true;
 }
 
@@ -469,6 +435,125 @@ 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_req) {
+        g_object_set_data(G_OBJECT(d->m_req), "webkit-resource", 0);
+        g_object_unref(d->m_req);
+        d->m_req = 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 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 (userData) {
+        // No need to call gotChunkHandler anymore. Received data will
+        // be reported by readCallback
+        gulong gotChunkHandler = GPOINTER_TO_UINT (userData);
+        if (g_signal_handler_is_connected (d->m_msg, gotChunkHandler))
+            g_signal_handler_disconnect (d->m_msg, gotChunkHandler);
+    }
+
+    if (d->m_cancelled || !client) {
+        cleanupSoupRequestOperation(handle.get());
+        return;
+    }
+
+    GError *error = 0;
+    GInputStream* in = soup_request_send_finish(d->m_req, res, &error);
+
+    if (error) {
+
+        if (d->m_msg && SOUP_STATUS_IS_TRANSPORT_ERROR(d->m_msg->status_code)) {
+            SoupURI* uri = soup_request_get_uri(d->m_req);
+            char* uristr = soup_uri_to_string(uri, false);
+            ResourceError resourceError(g_quark_to_string(SOUP_HTTP_ERROR),
+                                        d->m_msg->status_code,
+                                        uristr,
+                                        String::fromUTF8(d->m_msg->reason_phrase));
+            g_free(uristr);
+            g_error_free(error);
+            cleanupSoupRequestOperation(handle.get());
+            client->didFail(handle.get(), resourceError);
+            return;
+        }
+
+        if (error->domain == G_IO_ERROR) {
+            SoupURI* uri = soup_request_get_uri(d->m_req);
+            char* uristr = soup_uri_to_string(uri, false);
+            ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
+                                        error->code,
+                                        uristr,
+                                        error ? String::fromUTF8(error->message) : String());
+            g_free(uristr);
+            g_error_free(error);
+            cleanupSoupRequestOperation(handle.get());
+            client->didFail(handle.get(), resourceError);
+            return;
+        }
+
+        g_error_free(error);
+
+        if (d->m_msg && d->m_msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
+            fillResponseFromMessage(d->m_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 (d->m_msg->response_body->data)
+                client->didReceiveData(handle.get(), d->m_msg->response_body->data, d->m_msg->response_body->length, true);
+        }
+
+        client->didFinishLoading(handle.get());
+        return;
+    }
+
+    if (d->m_cancelled) {
+        cleanupSoupRequestOperation(handle.get());
+        return;
+    }
+
+    d->m_inputStream = 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 bool startHttp(ResourceHandle* handle)
 {
     ASSERT(handle);
@@ -483,7 +568,17 @@ static bool startHttp(ResourceHandle* handle)
     url.removeFragmentIdentifier();
     request.setURL(url);
 
-    d->m_msg = request.toSoupMessage();
+    GError* error = 0;
+    d->m_req = soup_session_request(session, url.string().utf8().data(), &error);
+    if (error) {
+        g_error_free(error);
+        return false;
+    }
+    g_object_set_data(G_OBJECT(d->m_req), "webkit-resource", handle);
+
+    d->m_msg = soup_request_http_get_message(SOUP_REQUEST_HTTP(d->m_req));
+    request.updateSoupMessage(d->m_msg);
+
     if (!d->m_msg)
         return false;
 
@@ -493,7 +588,7 @@ static bool startHttp(ResourceHandle* 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);
+    gulong gotChunkHandler = g_signal_connect(d->m_msg, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
 
 #ifdef HAVE_LIBSOUP_2_29_90
     String firstPartyString = request.firstPartyForCookies().string();
@@ -502,7 +597,7 @@ static bool startHttp(ResourceHandle* handle)
         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));
+    //    g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle));
 
     FormData* httpBody = d->m_request.httpBody();
     if (httpBody && !httpBody->isEmpty()) {
@@ -571,15 +666,14 @@ static bool startHttp(ResourceHandle* handle)
     if (!soup_message_headers_get_one(d->m_msg->request_headers, "Accept"))
         soup_message_headers_append(d->m_msg->request_headers, "Accept", "*/*");
 
-    // 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);
+    d->m_cancellable = g_cancellable_new();
+    soup_request_send_async(d->m_req, d->m_cancellable,
+                            sendRequestCallback, GUINT_TO_POINTER(gotChunkHandler));
 
     return true;
 }
 
+
 bool ResourceHandle::start(Frame* frame)
 {
     ASSERT(!d->m_msg);
@@ -600,7 +694,7 @@ bool ResourceHandle::start(Frame* frame)
     d->m_frame = frame;
 
     if (equalIgnoringCase(protocol, "data"))
-        return startData(this, urlString);
+        return startData(this, url);
 
     if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) {
         if (startHttp(this))
@@ -709,7 +803,6 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
     ResourceHandleClient* client = handle->client();
 
     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
@@ -718,6 +811,11 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
         return;
 
     client->didFinishLoading(handle.get());
+
+    if (d->m_gfile)
+        cleanupGioOperation(handle.get());
+    else
+        cleanupSoupRequestOperation(handle.get());
 }
 
 static void readCallback(GObject* source, GAsyncResult* res, gpointer)
@@ -738,14 +836,18 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
 
     gssize bytesRead = g_input_stream_read_finish(d->m_inputStream, res, &error);
     if (error) {
-        char* uri = g_file_get_uri(d->m_gfile);
+        SoupURI* uri = soup_request_get_uri(d->m_req);
+        char* uristr = soup_uri_to_string(uri, false);
         ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
                                     error->code,
-                                    uri,
+                                    uristr,
                                     error ? String::fromUTF8(error->message) : String());
-        g_free(uri);
+        g_free(uristr);
         g_error_free(error);
-        cleanupGioOperation(handle.get());
+        if (d->m_gfile)
+            cleanupGioOperation(handle.get());
+        else
+            cleanupSoupRequestOperation(handle.get());
         client->didFail(handle.get(), resourceError);
         return;
     }
@@ -761,7 +863,10 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
 
     // didReceiveData may cancel the load, which may release the last reference.
     if (d->m_cancelled) {
-        cleanupGioOperation(handle.get());
+        if (d->m_gfile)
+            cleanupGioOperation(handle.get());
+        else
+            cleanupSoupRequestOperation(handle.get());
         return;
     }
 
diff --git a/WebCore/platform/network/soup/ResourceRequest.h b/WebCore/platform/network/soup/ResourceRequest.h
index a1d916f..c1c7116 100644
--- a/WebCore/platform/network/soup/ResourceRequest.h
+++ b/WebCore/platform/network/soup/ResourceRequest.h
@@ -67,6 +67,7 @@ namespace WebCore {
             updateFromSoupMessage(soupMessage);
         }
 
+        void updateSoupMessage(SoupMessage* soupMessage) const;
         SoupMessage* toSoupMessage() const;
         void updateFromSoupMessage(SoupMessage* soupMessage);
 
diff --git a/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
index 62deb01..afaae9e 100644
--- a/WebCore/platform/network/soup/ResourceRequestSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2009 Gustavo Noronha Silva
  *
@@ -33,6 +34,29 @@ 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());
