18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Alp Toker <alp@atoker.com>
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Xan Lopez <xan@gnome.org>
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2008, 2010 Collabora Ltd.
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2009 Holger Hans Peter Freyther
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2009 Christian Dywan <christian@imendio.com>
88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2009 Igalia S.L.
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 John Kjellberg <john.kjellberg@power.alstom.com>
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceHandle.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Base64.h"
316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "CString.h"
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "ChromeClient.h"
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "CookieJarSoup.h"
345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "CachedResourceLoader.h"
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "FileSystem.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "GOwnPtrSoup.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTTPParsers.h"
398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Logging.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NotImplemented.h"
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Page.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceError.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceHandleClient.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceHandleInternal.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceResponse.h"
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SharedBuffer.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextEncoding.h"
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <errno.h>
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <fcntl.h>
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <gio/gio.h>
526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <glib.h>
532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#define LIBSOUP_USE_UNSTABLE_REQUEST_API
542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <libsoup/soup-request-http.h>
552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <libsoup/soup-requester.h>
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <libsoup/soup.h>
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <sys/stat.h>
586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <sys/types.h>
598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <unistd.h>
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#define READ_BUFFER_SIZE 8192
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
65ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass WebCoreSynchronousLoader : public ResourceHandleClient {
66ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(WebCoreSynchronousLoader);
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianpublic:
688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    WebCoreSynchronousLoader(ResourceError&, ResourceResponse &, Vector<char>&);
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ~WebCoreSynchronousLoader();
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
7368513a70bcd92384395513322f1b801e7bf9c729Steve Block    virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    virtual void didFail(ResourceHandle*, const ResourceError&);
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void run();
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianprivate:
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ResourceError& m_error;
808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ResourceResponse& m_response;
818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Vector<char>& m_data;
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool m_finished;
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    GMainLoop* m_mainLoop;
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian};
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWebCoreSynchronousLoader::WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : m_error(error)
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_response(response)
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_data(data)
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_finished(false)
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_mainLoop = g_main_loop_new(0, false);
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWebCoreSynchronousLoader::~WebCoreSynchronousLoader()
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    g_main_loop_unref(m_mainLoop);
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_response = response;
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_data.append(data, length);
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
11068513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double)
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    g_main_loop_quit(m_mainLoop);
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_finished = true;
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didFail(ResourceHandle* handle, const ResourceError& error)
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_error = error;
11968513a70bcd92384395513322f1b801e7bf9c729Steve Block    didFinishLoading(handle, 0);
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::run()
1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_finished)
1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        g_main_loop_run(m_mainLoop);
1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying);
129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void readCallback(GObject*, GAsyncResult*, gpointer);
131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void closeCallback(GObject*, GAsyncResult*, gpointer);
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool startNonHTTPRequest(ResourceHandle*, KURL);
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectResourceHandleInternal::~ResourceHandleInternal()
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_soupRequest)
137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0);
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectResourceHandle::~ResourceHandle()
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    cleanupSoupRequestOperation(this, true);
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void ensureSessionIsInitialized(SoupSession* session)
1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Values taken from http://stevesouders.com/ua/index.php following
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // the rule "Do What Every Other Modern Browser Is Doing". They seem
1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // to significantly improve page loading time compared to soup's
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // default values.
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    static const int maxConnections = 60;
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    static const int maxConnectionsPerHost = 6;
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (g_object_get_data(G_OBJECT(session), "webkit-init"))
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    SoupCookieJar* jar = SOUP_COOKIE_JAR(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!jar)
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_session_add_feature(session, SOUP_SESSION_FEATURE(defaultCookieJar()));
1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    else
1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setDefaultCookieJar(jar);
1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!soup_session_get_feature(session, SOUP_TYPE_LOGGER) && LogNetwork.state == WTFLogChannelOn) {
1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(SOUP_LOGGER_LOG_BODY), -1);
1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_session_add_feature(session, SOUP_SESSION_FEATURE(logger));
1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        g_object_unref(logger);
1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!soup_session_get_feature(session, SOUP_TYPE_REQUESTER)) {
17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        SoupRequester* requester = soup_requester_new();
17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        soup_session_add_feature(session, SOUP_SESSION_FEATURE(requester));
17281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        g_object_unref(requester);
17381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    g_object_set(session,
1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 SOUP_SESSION_MAX_CONNS, maxConnections,
1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 SOUP_SESSION_MAX_CONNS_PER_HOST, maxConnectionsPerHost,
1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                 NULL);
1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid ResourceHandle::prepareForURL(const KURL &url)
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    GOwnPtr<SoupURI> soupURI(soup_uri_new(url.prettyURL().utf8().data()));
186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!soupURI)
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    soup_session_prepare_for_uri(ResourceHandle::defaultSession(), soupURI.get());
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// All other kinds of redirections, except for the *304* status code
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// (SOUP_STATUS_NOT_MODIFIED) which needs to be fed into WebCore, will be
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// handled by soup directly.
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic gboolean statusWillBeHandledBySoup(guint statusCode)
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (SOUP_STATUS_IS_TRANSPORT_ERROR(statusCode)
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        || (SOUP_STATUS_IS_REDIRECTION(statusCode) && (statusCode != SOUP_STATUS_NOT_MODIFIED))
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        || (statusCode == SOUP_STATUS_UNAUTHORIZED))
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return true;
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return false;
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response)
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    response->updateFromSoupMessage(msg);
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Called each time the message is going to be sent again except the first time.
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// It's used mostly to let webkit know about redirects.
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void restartedCallback(SoupMessage* msg, gpointer data)
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandle* handle = static_cast<ResourceHandle*>(data);
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!handle)
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleInternal* d = handle->getInternal();
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->m_cancelled)
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    GOwnPtr<char> uri(soup_uri_to_string(soup_message_get_uri(msg), false));
221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String location = String::fromUTF8(uri.get());
222967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    KURL newURL = KURL(handle->firstRequest().url(), location);
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
224967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ResourceRequest request = handle->firstRequest();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceResponse response;
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    request.setURL(newURL);
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    request.setHTTPMethod(msg->method);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fillResponseFromMessage(msg, &response);
229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
230643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Should not set Referer after a redirect from a secure resource to non-secure one.
231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https")) {
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        request.clearHTTPReferrer();
233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        soup_message_headers_remove(msg->request_headers, "Referer");
234643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->client())
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        d->client()->willSendRequest(handle, request, response);
2388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
2396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (d->m_cancelled)
2406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
2416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
2428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    // Update the first party in case the base URL changed with the redirect
2438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    String firstPartyString = request.firstPartyForCookies().string();
2448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!firstPartyString.isEmpty()) {
2458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        soup_message_set_first_party(d->m_soupMessage.get(), firstParty.get());
2478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    }
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic void contentSniffedCallback(SoupMessage*, const char*, GHashTable*, gpointer);
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void gotHeadersCallback(SoupMessage* msg, gpointer data)
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For 401, we will accumulate the resource body, and only use it
255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // in case authentication with the soup feature doesn't happen.
256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // For 302 we accumulate the body too because it could be used by
257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // some servers to redirect with a clunky http-equiv=REFRESH
258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (statusWillBeHandledBySoup(msg->status_code)) {
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        soup_message_body_set_accumulate(msg->response_body, TRUE);
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For all the other responses, we handle each chunk ourselves,
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // and we don't need msg->response_body to contain all of the data
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // we got, when we finish downloading.
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    soup_message_body_set_accumulate(msg->response_body, FALSE);
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // The content-sniffed callback will handle the response if WebCore
271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // require us to sniff.
27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!handle || statusWillBeHandledBySoup(msg->status_code))
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (handle->shouldContentSniff()) {
27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Avoid MIME type sniffing if the response comes back as 304 Not Modified.
27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) {
27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER);
27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            g_signal_handlers_disconnect_by_func(msg, reinterpret_cast<gpointer>(contentSniffedCallback), handle.get());
28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        } else
28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return;
28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
28365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ResourceHandleInternal* d = handle->getInternal();
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (d->m_cancelled)
286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ResourceHandleClient* client = handle->client();
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!client)
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
290231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2914576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(d->m_response.isNull());
2924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
293231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    fillResponseFromMessage(msg, &d->m_response);
294231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    client->didReceiveResponse(handle.get(), d->m_response);
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2972fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void wroteBodyDataCallback(SoupMessage*, SoupBuffer* buffer, gpointer data)
2982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
2992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
3002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!handle)
3012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(buffer);
3042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ResourceHandleInternal* internal = handle->getInternal();
3052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    internal->m_bodyDataSent += buffer->length;
3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (internal->m_cancelled)
3082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ResourceHandleClient* client = handle->client();
3102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!client)
3112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    client->didSendData(handle.get(), internal->m_bodyDataSent, internal->m_bodySize);
3142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// This callback will not be called if the content sniffer is disabled in startHTTPRequest.
3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data)
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (sniffedType) {
3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        const char* officialType = soup_message_headers_get_one(msg->response_headers, "Content-Type");
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (!officialType || strcmp(officialType, sniffedType))
3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            soup_message_headers_set_content_type(msg->response_headers, sniffedType, params);
3240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (statusWillBeHandledBySoup(msg->status_code))
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!handle)
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleInternal* d = handle->getInternal();
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->m_cancelled)
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleClient* client = handle->client();
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client)
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(d->m_response.isNull());
3404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fillResponseFromMessage(msg, &d->m_response);
3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    client->didReceiveResponse(handle.get(), d->m_response);
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (statusWillBeHandledBySoup(msg->status_code))
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!handle)
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleInternal* d = handle->getInternal();
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->m_cancelled)
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleClient* client = handle->client();
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client)
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(!d->m_response.isNull());
3614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block    // -1 means we do not provide any data about transfer size to inspector so it would use
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Content-Length headers or content size to show transfer size.
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block    client->didReceiveData(handle.get(), chunk->data, chunk->length, -1);
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic SoupSession* createSoupSession()
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return soup_session_async_new();
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
373a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying = false)
374a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
375a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ResourceHandleInternal* d = handle->getInternal();
376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_soupRequest) {
378a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", 0);
379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_soupRequest.clear();
380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
381a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
382a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_inputStream) {
383a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", 0);
384a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_inputStream.clear();
385a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
387a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    d->m_cancellable.clear();
388a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
389a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_soupMessage) {
390a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA,
391a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                             0, 0, 0, 0, handle);
392a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_soupMessage.clear();
393a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
394a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
395a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_buffer) {
396a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);
397a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_buffer = 0;
398a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
400a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!isDestroying)
401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        handle->deref();
402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer userData)
405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
407a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!handle)
408a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
409a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
410a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ResourceHandleInternal* d = handle->getInternal();
411a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ResourceHandleClient* client = handle->client();
412a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
413a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_gotChunkHandler) {
414a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // No need to call gotChunkHandler anymore. Received data will
415a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // be reported by readCallback
416a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (g_signal_handler_is_connected(d->m_soupMessage.get(), d->m_gotChunkHandler))
417a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            g_signal_handler_disconnect(d->m_soupMessage.get(), d->m_gotChunkHandler);
418a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
419a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
420a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_cancelled || !client) {
421a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cleanupSoupRequestOperation(handle.get());
422a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
423a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
424a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
425a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    GOwnPtr<GError> error;
4262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    GInputStream* in = soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr());
427a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
428a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (error) {
429a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        SoupMessage* soupMsg = d->m_soupMessage.get();
430a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        gboolean isTransportError = d->m_soupMessage && SOUP_STATUS_IS_TRANSPORT_ERROR(soupMsg->status_code);
431a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
432a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (isTransportError || (error->domain == G_IO_ERROR)) {
4332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            SoupURI* uri = soup_request_get_uri(d->m_soupRequest.get());
434a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
435f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            gint errorCode = isTransportError ? static_cast<gint>(soupMsg->status_code) : error->code;
436a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            const gchar* errorMsg = isTransportError ? soupMsg->reason_phrase : error->message;
437a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            const gchar* quarkStr = isTransportError ? g_quark_to_string(SOUP_HTTP_ERROR) : g_quark_to_string(G_IO_ERROR);
438a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            ResourceError resourceError(quarkStr, errorCode, uriStr.get(), String::fromUTF8(errorMsg));
439a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
440a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            cleanupSoupRequestOperation(handle.get());
441a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            client->didFail(handle.get(), resourceError);
442a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return;
443a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
444a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
445a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (d->m_soupMessage && statusWillBeHandledBySoup(d->m_soupMessage->status_code)) {
4464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            ASSERT(d->m_response.isNull());
4474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
448a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            fillResponseFromMessage(soupMsg, &d->m_response);
449a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            client->didReceiveResponse(handle.get(), d->m_response);
450a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
451f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // WebCore might have cancelled the job in the while. We
452f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // must check for response_body->length and not
453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // response_body->data as libsoup always creates the
454f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // SoupBuffer for the body even if the length is 0
455f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!d->m_cancelled && soupMsg->response_body->length)
45681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, soupMsg->response_body->length);
457a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
458a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // didReceiveData above might have cancelled it
460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (d->m_cancelled || !client) {
461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            cleanupSoupRequestOperation(handle.get());
462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return;
463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        client->didFinishLoading(handle.get(), 0);
466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
467a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_cancelled) {
470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cleanupSoupRequestOperation(handle.get());
471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
474cad810f21b803229eb11403f9209855525a25d57Steve Block    d->m_inputStream = adoptGRef(in);
475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE));
476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // readCallback needs it
478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get());
479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
4802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // If not using SoupMessage we need to call didReceiveResponse now.
4812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // (This will change later when SoupRequest supports content sniffing.)
4822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!d->m_soupMessage) {
4834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        d->m_response.setURL(handle->firstRequest().url());
4842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        const gchar* contentType = soup_request_get_content_type(d->m_soupRequest.get());
4852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        d->m_response.setMimeType(extractMIMETypeFromMediaType(contentType));
4862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        d->m_response.setTextEncodingName(extractCharsetFromMediaType(contentType));
4872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        d->m_response.setExpectedContentLength(soup_request_get_content_length(d->m_soupRequest.get()));
4884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        client->didReceiveResponse(handle.get(), d->m_response);
489a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
490a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (d->m_cancelled) {
491a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            cleanupSoupRequestOperation(handle.get());
492a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return;
493a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
494a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
496f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (d->m_defersLoading)
497f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch         soup_session_pause_message(handle->defaultSession(), d->m_soupMessage.get());
498f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE,
500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                              G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, 0);
501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5032fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool addFormElementsToSoupMessage(SoupMessage* message, const char* contentType, FormData* httpBody, unsigned long& totalBodySize)
5042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
5052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    size_t numElements = httpBody->elements().size();
5062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (numElements < 2) { // No file upload is the most common case.
5072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Vector<char> body;
5082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        httpBody->flatten(body);
5092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        totalBodySize = body.size();
5102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_message_set_request(message, contentType, SOUP_MEMORY_COPY, body.data(), body.size());
5112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return true;
5122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
5132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // We have more than one element to upload, and some may be large files,
5152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // which we will want to mmap instead of copying into memory
5162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    soup_message_body_set_accumulate(message->request_body, FALSE);
5172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (size_t i = 0; i < numElements; i++) {
5182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        const FormDataElement& element = httpBody->elements()[i];
5192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (element.m_type == FormDataElement::data) {
5212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            totalBodySize += element.m_data.size();
5222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            soup_message_body_append(message->request_body, SOUP_MEMORY_TEMPORARY,
5232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                     element.m_data.data(), element.m_data.size());
5242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            continue;
5252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
5262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // This technique is inspired by libsoup's simple-httpd test.
5282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        GOwnPtr<GError> error;
5292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        CString fileName = fileSystemRepresentation(element.m_filename);
5302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr());
5312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (error)
5322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return false;
5332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        gsize mappedFileSize = g_mapped_file_get_length(fileMapping);
5352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        totalBodySize += mappedFileSize;
5362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping),
5372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                                            mappedFileSize, fileMapping,
5382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                                            reinterpret_cast<GDestroyNotify>(g_mapped_file_unref));
5392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_message_body_append_buffer(message->request_body, soupBuffer);
5402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_buffer_free(soupBuffer);
5412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
5422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return true;
5442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
5452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5462fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool startHTTPRequest(ResourceHandle* handle)
5478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(handle);
549231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
5500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SoupSession* session = handle->defaultSession();
5518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ensureSessionIsInitialized(session);
5522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
5538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ResourceHandleInternal* d = handle->getInternal();
5550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
556967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ResourceRequest request(handle->firstRequest());
557231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    KURL url(request.url());
558231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    url.removeFragmentIdentifier();
559231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    request.setURL(url);
560231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
561a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    GOwnPtr<GError> error;
5622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    d->m_soupRequest = adoptGRef(soup_requester_request(requester, url.string().utf8().data(), &error.outPtr()));
563a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (error) {
564a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_soupRequest = 0;
5650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return false;
566a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
567a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
568a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
569a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    d->m_soupMessage = adoptGRef(soup_request_http_get_message(SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
571a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!d->m_soupMessage)
572a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
574a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    SoupMessage* soupMessage = d->m_soupMessage.get();
575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    request.updateSoupMessage(soupMessage);
576231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
5776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!handle->shouldContentSniff())
578a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
5794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    else
5804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        g_signal_connect(soupMessage, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);
5810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
582a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle);
583a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
5842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    g_signal_connect(soupMessage, "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
585a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    d->m_gotChunkHandler = g_signal_connect(soupMessage, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
5868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    String firstPartyString = request.firstPartyForCookies().string();
5888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!firstPartyString.isEmpty()) {
5898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
590a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        soup_message_set_first_party(soupMessage, firstParty.get());
5918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    }
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
593967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    FormData* httpBody = d->m_firstRequest.httpBody();
5942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    CString contentType = d->m_firstRequest.httpContentType().utf8().data();
5952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (httpBody && !httpBody->isEmpty()
5962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {
5972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // We failed to prepare the body data, so just fail this load.
5982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, handle);
5992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        d->m_soupMessage.clear();
6002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return false;
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
603a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // balanced by a deref() in cleanupSoupRequestOperation, which should always run
6040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    handle->ref();
6058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
606692e5dbf12901edacf14812a6fae25462920af42Steve Block    // Make sure we have an Accept header for subresources; some sites
607692e5dbf12901edacf14812a6fae25462920af42Steve Block    // want this to serve some of their subresources
608a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
609a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
610692e5dbf12901edacf14812a6fae25462920af42Steve Block
611f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Send the request only if it's not been explicitely deferred.
612f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!d->m_defersLoading) {
613cad810f21b803229eb11403f9209855525a25d57Steve Block        d->m_cancellable = adoptGRef(g_cancellable_new());
6142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
615f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
62068513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool ResourceHandle::start(NetworkingContext* context)
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(!d->m_soupMessage);
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The frame could be null if the ResourceHandle is not associated to any
6258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Frame, e.g. if we are downloading a file.
6268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If the frame is not null but the page is null this must be an attempted
62768513a70bcd92384395513322f1b801e7bf9c729Steve Block    // load from an unload handler, so let's just block it.
62868513a70bcd92384395513322f1b801e7bf9c729Steve Block    // If both the frame and the page are not null the context is valid.
62968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (context && !context->isValid())
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
632e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) {
633e14391e94c850b8bd03680c23b38978db68687a8John Reck        // If credentials were specified for this request, add them to the url,
634e14391e94c850b8bd03680c23b38978db68687a8John Reck        // so that they will be passed to NetworkRequest.
635e14391e94c850b8bd03680c23b38978db68687a8John Reck        KURL urlWithCredentials(firstRequest().url());
636e14391e94c850b8bd03680c23b38978db68687a8John Reck        urlWithCredentials.setUser(d->m_user);
637e14391e94c850b8bd03680c23b38978db68687a8John Reck        urlWithCredentials.setPass(d->m_pass);
638e14391e94c850b8bd03680c23b38978db68687a8John Reck        d->m_firstRequest.setURL(urlWithCredentials);
639e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
640e14391e94c850b8bd03680c23b38978db68687a8John Reck
641967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    KURL url = firstRequest().url();
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String urlString = url.string();
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String protocol = url.protocol();
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Used to set the authentication dialog toplevel; may be NULL
64668513a70bcd92384395513322f1b801e7bf9c729Steve Block    d->m_context = context;
6478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
648231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) {
6492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (startHTTPRequest(this))
650231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return true;
651231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
6528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (startNonHTTPRequest(this, url))
6542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return true;
6558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Error must not be reported immediately
6575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    this->scheduleFailure(InvalidURLFailure);
6585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return true;
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ResourceHandle::cancel()
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    d->m_cancelled = true;
665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (d->m_soupMessage)
666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        soup_session_cancel_message(defaultSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED);
6678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else if (d->m_cancellable)
668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_cancellable_cancel(d->m_cancellable.get());
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ResourceHandle::supportsBufferedData()
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
682f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceHandle::platformSetDefersLoading(bool defersLoading)
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
684f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Initial implementation of this method was required for bug #44157.
685f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
686f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (d->m_cancelled)
687f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
688f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
689f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!defersLoading && !d->m_cancellable && d->m_soupRequest.get()) {
690cad810f21b803229eb11403f9209855525a25d57Steve Block        d->m_cancellable = adoptGRef(g_cancellable_new());
6912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
692f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
693f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
694f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
695f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Only supported for http(s) transfers. Something similar would
696f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // probably be needed for data transfers done with GIO.
697f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!d->m_soupMessage)
698f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
699f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
70081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SoupMessage* soupMessage = d->m_soupMessage.get();
70181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (soupMessage->status_code != SOUP_STATUS_NONE)
70281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
70381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
704f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (defersLoading)
70581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        soup_session_pause_message(defaultSession(), soupMessage);
706f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    else
70781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        soup_session_unpause_message(defaultSession(), soupMessage);
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ResourceHandle::loadsBlocked()
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Not having this function means that we'll ask the user about re-posting a form
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // even when we go back to a page that's still in the cache.
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    notImplemented();
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
72368513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data)
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    WebCoreSynchronousLoader syncLoader(error, response, data);
7262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RefPtr<ResourceHandle> handle = create(context, request, &syncLoader, false /*defersLoading*/, false /*shouldContentSniff*/);
7272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!handle)
7282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
7292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // If the request has already failed, do not run the main loop, or else we'll block indefinitely.
7312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (handle->d->m_scheduledFailureType != NoFailure)
7322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
7338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    syncLoader.run();
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
737635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void closeCallback(GObject* source, GAsyncResult* res, gpointer)
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
740635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!handle)
741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
742635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleInternal* d = handle->getInternal();
744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_input_stream_close_finish(d->m_inputStream.get(), res, 0);
745a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    cleanupSoupRequestOperation(handle.get());
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer data)
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!handle)
752635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
753635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
754a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool convertToUTF16 = static_cast<bool>(data);
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleInternal* d = handle->getInternal();
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ResourceHandleClient* client = handle->client();
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->m_cancelled || !client) {
759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cleanupSoupRequestOperation(handle.get());
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    GOwnPtr<GError> error;
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (error) {
7672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        SoupURI* uri = soup_request_get_uri(d->m_soupRequest.get());
768a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
769a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ResourceError resourceError(g_quark_to_string(G_IO_ERROR), error->code, uriStr.get(),
7705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                                    error ? String::fromUTF8(error->message) : String());
771a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cleanupSoupRequestOperation(handle.get());
7728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        client->didFail(handle.get(), resourceError);
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
7758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!bytesRead) {
7772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Finish the load. We do not wait for the stream to
7782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // close. Instead we better notify WebCore as soon as possible
7792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        client->didFinishLoading(handle.get(), 0);
7802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
781a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        g_input_stream_close_async(d->m_inputStream.get(), G_PRIORITY_DEFAULT,
7828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                                   0, closeCallback, 0);
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7864576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // It's mandatory to have sent a response before sending data
7874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(!d->m_response.isNull());
7884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
789a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (G_LIKELY(!convertToUTF16))
79081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        client->didReceiveData(handle.get(), d->m_buffer, bytesRead, bytesRead);
791a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    else {
792a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // We have to convert it to UTF-16 due to limitations in KURL
793a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        String data = String::fromUTF8(d->m_buffer, bytesRead);
79481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), bytesRead);
7958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
7968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // didReceiveData may cancel the load, which may release the last reference.
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (d->m_cancelled || !client) {
799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cleanupSoupRequestOperation(handle.get());
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
803a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT,
804a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                              d->m_cancellable.get(), readCallback, data);
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8072fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool startNonHTTPRequest(ResourceHandle* handle, KURL url)
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(handle);
8100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
811967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
814a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    SoupSession* session = handle->defaultSession();
8152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ensureSessionIsInitialized(session);
8162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
817a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ResourceHandleInternal* d = handle->getInternal();
818a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
819a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CString urlStr = url.string().utf8();
8208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
821a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    GOwnPtr<GError> error;
8222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    d->m_soupRequest = adoptGRef(soup_requester_request(requester, urlStr.data(), &error.outPtr()));
823a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (error) {
824a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        d->m_soupRequest = 0;
825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
826a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
829231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // balanced by a deref() in cleanupSoupRequestOperation, which should always run
831231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    handle->ref();
832231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
833cad810f21b803229eb11403f9209855525a25d57Steve Block    d->m_cancellable = adoptGRef(g_cancellable_new());
8342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
835a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianSoupSession* ResourceHandle::defaultSession()
8408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static SoupSession* session = createSoupSession();
8428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return session;
8448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
847