ResourceHandleSoup.cpp revision 65f03d4f644ce73618e5f4f50dd694b26f55ae12
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" 48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "soup-request-http.h" 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextEncoding.h" 508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <errno.h> 518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <fcntl.h> 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <gio/gio.h> 536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <glib.h> 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <libsoup/soup.h> 558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <sys/stat.h> 566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <sys/types.h> 578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <unistd.h> 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#define READ_BUFFER_SIZE 8192 62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable { 648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianpublic: 658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian WebCoreSynchronousLoader(ResourceError&, ResourceResponse &, Vector<char>&); 668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ~WebCoreSynchronousLoader(); 678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); 698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); 7068513a70bcd92384395513322f1b801e7bf9c729Steve Block virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); 718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian virtual void didFail(ResourceHandle*, const ResourceError&); 728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void run(); 748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianprivate: 768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ResourceError& m_error; 778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ResourceResponse& m_response; 788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Vector<char>& m_data; 798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool m_finished; 808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian GMainLoop* m_mainLoop; 818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}; 828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWebCoreSynchronousLoader::WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data) 848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_error(error) 858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_response(response) 868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_data(data) 878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_finished(false) 888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_mainLoop = g_main_loop_new(0, false); 908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWebCoreSynchronousLoader::~WebCoreSynchronousLoader() 938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_main_loop_unref(m_mainLoop); 958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) 988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_response = response; 1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int) 1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_data.append(data, length); 1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 10768513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) 1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_main_loop_quit(m_mainLoop); 1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_finished = true; 1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::didFail(ResourceHandle* handle, const ResourceError& error) 1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_error = error; 11668513a70bcd92384395513322f1b801e7bf9c729Steve Block didFinishLoading(handle, 0); 1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WebCoreSynchronousLoader::run() 1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!m_finished) 1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_main_loop_run(m_mainLoop); 1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying); 126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void sendRequestCallback(GObject*, GAsyncResult*, gpointer); 127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void readCallback(GObject*, GAsyncResult*, gpointer); 128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void closeCallback(GObject*, GAsyncResult*, gpointer); 129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic bool startGio(ResourceHandle*, KURL); 130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectResourceHandleInternal::~ResourceHandleInternal() 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (m_soupRequest) 134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0); 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_idleHandler) { 137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project g_source_remove(m_idleHandler); 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_idleHandler = 0; 139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectResourceHandle::~ResourceHandle() 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(this, true); 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid ResourceHandle::prepareForURL(const KURL &url) 148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifdef HAVE_LIBSOUP_2_29_90 150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GOwnPtr<SoupURI> soupURI(soup_uri_new(url.prettyURL().utf8().data())); 151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!soupURI) 152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block soup_session_prepare_for_uri(ResourceHandle::defaultSession(), soupURI.get()); 154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// All other kinds of redirections, except for the *304* status code 158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// (SOUP_STATUS_NOT_MODIFIED) which needs to be fed into WebCore, will be 159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// handled by soup directly. 160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic gboolean statusWillBeHandledBySoup(guint statusCode) 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (SOUP_STATUS_IS_TRANSPORT_ERROR(statusCode) 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block || (SOUP_STATUS_IS_REDIRECTION(statusCode) && (statusCode != SOUP_STATUS_NOT_MODIFIED)) 164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block || (statusCode == SOUP_STATUS_UNAUTHORIZED)) 165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response) 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block response->updateFromSoupMessage(msg); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Called each time the message is going to be sent again except the first time. 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// It's used mostly to let webkit know about redirects. 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void restartedCallback(SoupMessage* msg, gpointer data) 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandle* handle = static_cast<ResourceHandle*>(data); 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!handle) 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleInternal* d = handle->getInternal(); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->m_cancelled) 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 186a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<char> uri(soup_uri_to_string(soup_message_get_uri(msg), false)); 187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String location = String::fromUTF8(uri.get()); 188967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch KURL newURL = KURL(handle->firstRequest().url(), location); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 190967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ResourceRequest request = handle->firstRequest(); 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceResponse response; 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project request.setURL(newURL); 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block request.setHTTPMethod(msg->method); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fillResponseFromMessage(msg, &response); 195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Should not set Referer after a redirect from a secure resource to non-secure one. 197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https")) { 198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block request.clearHTTPReferrer(); 199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block soup_message_headers_remove(msg->request_headers, "Referer"); 200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->client()) 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project d->client()->willSendRequest(handle, request, response); 2048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (d->m_cancelled) 2066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return; 2076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#ifdef HAVE_LIBSOUP_2_29_90 2098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Update the first party in case the base URL changed with the redirect 2108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block String firstPartyString = request.firstPartyForCookies().string(); 2118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!firstPartyString.isEmpty()) { 2128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); 213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_set_first_party(d->m_soupMessage.get(), firstParty.get()); 2148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 2158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#endif 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic void contentSniffedCallback(SoupMessage*, const char*, GHashTable*, gpointer); 21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void gotHeadersCallback(SoupMessage* msg, gpointer data) 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // For 401, we will accumulate the resource body, and only use it 223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // in case authentication with the soup feature doesn't happen. 224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // For 302 we accumulate the body too because it could be used by 225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // some servers to redirect with a clunky http-equiv=REFRESH 226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (statusWillBeHandledBySoup(msg->status_code)) { 2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian soup_message_body_set_accumulate(msg->response_body, TRUE); 2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // For all the other responses, we handle each chunk ourselves, 2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // and we don't need msg->response_body to contain all of the data 2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // we got, when we finish downloading. 2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian soup_message_body_set_accumulate(msg->response_body, FALSE); 2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data); 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // The content-sniffed callback will handle the response if WebCore 239231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // require us to sniff. 24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!handle || statusWillBeHandledBySoup(msg->status_code)) 241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (handle->shouldContentSniff()) { 24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Avoid MIME type sniffing if the response comes back as 304 Not Modified. 24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) { 24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER); 24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch g_signal_handlers_disconnect_by_func(msg, reinterpret_cast<gpointer>(contentSniffedCallback), handle.get()); 24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } else 24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ResourceHandleInternal* d = handle->getInternal(); 253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (d->m_cancelled) 254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ResourceHandleClient* client = handle->client(); 256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!client) 257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 2594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(d->m_response.isNull()); 2604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fillResponseFromMessage(msg, &d->m_response); 262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block client->didReceiveResponse(handle.get(), d->m_response); 2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// This callback will not be called if the content sniffer is disabled in startHttp. 2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data) 2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (sniffedType) { 2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const char* officialType = soup_message_headers_get_one(msg->response_headers, "Content-Type"); 2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!officialType || strcmp(officialType, sniffedType)) 2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch soup_message_headers_set_content_type(msg->response_headers, sniffedType, params); 2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 275231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (statusWillBeHandledBySoup(msg->status_code)) 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data); 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!handle) 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleInternal* d = handle->getInternal(); 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->m_cancelled) 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleClient* client = handle->client(); 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!client) 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(d->m_response.isNull()); 2894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fillResponseFromMessage(msg, &d->m_response); 2915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian client->didReceiveResponse(handle.get(), d->m_response); 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data) 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 296231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (statusWillBeHandledBySoup(msg->status_code)) 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data); 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!handle) 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleInternal* d = handle->getInternal(); 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->m_cancelled) 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleClient* client = handle->client(); 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!client) 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(!d->m_response.isNull()); 3104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian client->didReceiveData(handle.get(), chunk->data, chunk->length, false); 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic gboolean parseDataUrl(gpointer callbackData) 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ResourceHandle* handle = static_cast<ResourceHandle*>(callbackData); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleClient* client = handle->client(); 3185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ResourceHandleInternal* d = handle->getInternal(); 3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (d->m_cancelled) 3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian d->m_idleHandler = 0; 323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(client); 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!client) 3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return false; 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 328967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch String url = handle->firstRequest().url().string(); 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(url.startsWith("data:", false)); 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int index = url.find(','); 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (index == -1) { 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project client->cannotShowURL(handle); 3348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return false; 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String mediaType = url.substring(5, index - 5); 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isBase64 = mediaType.endsWith(";base64", false); 3408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isBase64) 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mediaType = mediaType.left(mediaType.length() - 7); 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mediaType.isEmpty()) 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mediaType = "text/plain;charset=US-ASCII"; 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String mimeType = extractMIMETypeFromMediaType(mediaType); 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String charset = extractCharsetFromMediaType(mediaType); 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(d->m_response.isNull()); 3504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 3514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setURL(handle->firstRequest().url()); 3524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setMimeType(mimeType); 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // For non base64 encoded data we have to convert to UTF-16 early 355a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // due to limitations in KURL 3564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setTextEncodingName(isBase64 ? charset : "UTF-16"); 3574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang client->didReceiveResponse(handle, d->m_response); 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 359a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The load may be cancelled, and the client may be destroyed 360a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // by any of the client reporting calls, so we check, and bail 361a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // out in either of those cases. 362dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (d->m_cancelled || !handle->client()) 363692e5dbf12901edacf14812a6fae25462920af42Steve Block return false; 364692e5dbf12901edacf14812a6fae25462920af42Steve Block 365a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupSession* session = handle->defaultSession(); 366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 367cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_soupRequest = adoptGRef(webkit_soup_requester_request(d->m_requester.get(), handle->firstRequest().url().string().utf8().data(), session, &error.outPtr())); 368a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (error) { 369a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupRequest = 0; 370a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didFinishLoading(handle, 0); 371a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return false; 372a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 373a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 374cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_inputStream = adoptGRef(webkit_soup_request_send(d->m_soupRequest.get(), 0, &error.outPtr())); 375a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (error) { 376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_inputStream = 0; 377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didFinishLoading(handle, 0); 378a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return false; 379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 381a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); 382a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_total = 0; 383a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 384a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle); 385a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // balanced by a deref() in cleanupSoupRequestOperation, which should always run 386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch handle->ref(); 387a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 388cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_cancellable = adoptGRef(g_cancellable_new()); 389a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 390a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_cancellable.get(), readCallback, GINT_TO_POINTER(!isBase64)); 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return false; 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic bool startData(ResourceHandle* handle, String urlString) 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(handle); 3980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ResourceHandleInternal* d = handle->getInternal(); 400635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 401635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // If parseDataUrl is called synchronously the job is not yet effectively started 402635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // and webkit won't never know that the data has been parsed even didFinishLoading is called. 403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block d->m_idleHandler = g_timeout_add(0, parseDataUrl, handle); 404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return true; 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic SoupSession* createSoupSession() 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return soup_session_async_new(); 4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 412231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Values taken from http://stevesouders.com/ua/index.php following 413231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// the rule "Do What Every Other Modern Browser Is Doing". They seem 414231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// to significantly improve page loading time compared to soup's 415231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// default values. 416231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#define MAX_CONNECTIONS 60 417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#define MAX_CONNECTIONS_PER_HOST 6 418231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic void ensureSessionIsInitialized(SoupSession* session) 4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (g_object_get_data(G_OBJECT(session), "webkit-init")) 4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); 4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!jar) 4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian soup_session_add_feature(session, SOUP_SESSION_FEATURE(defaultCookieJar())); 4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else 4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setDefaultCookieJar(jar); 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!soup_session_get_feature(session, SOUP_TYPE_LOGGER) && LogNetwork.state == WTFLogChannelOn) { 4318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(SOUP_LOGGER_LOG_BODY), -1); 4328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian soup_logger_attach(logger, session); 4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_object_unref(logger); 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 436231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block g_object_set(session, 437231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SOUP_SESSION_MAX_CONNS, MAX_CONNECTIONS, 438231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SOUP_SESSION_MAX_CONNS_PER_HOST, MAX_CONNECTIONS_PER_HOST, 439231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NULL); 440231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef)); 4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 444a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying = false) 445a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 446a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceHandleInternal* d = handle->getInternal(); 447a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 448a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_soupRequest) { 449a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", 0); 450a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupRequest.clear(); 451a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 452a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 453a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_inputStream) { 454a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", 0); 455a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_inputStream.clear(); 456a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 457a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 458a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_cancellable.clear(); 459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_soupMessage) { 461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA, 462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 0, 0, 0, 0, handle); 463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupMessage.clear(); 464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_buffer) { 467a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_slice_free1(READ_BUFFER_SIZE, d->m_buffer); 468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_buffer = 0; 469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!isDestroying) 472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch handle->deref(); 473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 474a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer userData) 476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); 478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!handle) 479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceHandleInternal* d = handle->getInternal(); 482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceHandleClient* client = handle->client(); 483a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 484a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_gotChunkHandler) { 485a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // No need to call gotChunkHandler anymore. Received data will 486a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // be reported by readCallback 487a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (g_signal_handler_is_connected(d->m_soupMessage.get(), d->m_gotChunkHandler)) 488a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_signal_handler_disconnect(d->m_soupMessage.get(), d->m_gotChunkHandler); 489a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 490a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 491a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_cancelled || !client) { 492a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 493a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 494a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 496a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 497a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GInputStream* in = webkit_soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr()); 498a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (error) { 500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupMessage* soupMsg = d->m_soupMessage.get(); 501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch gboolean isTransportError = d->m_soupMessage && SOUP_STATUS_IS_TRANSPORT_ERROR(soupMsg->status_code); 502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 503a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (isTransportError || (error->domain == G_IO_ERROR)) { 504a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get()); 505a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<char> uriStr(soup_uri_to_string(uri, false)); 506f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gint errorCode = isTransportError ? static_cast<gint>(soupMsg->status_code) : error->code; 507a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const gchar* errorMsg = isTransportError ? soupMsg->reason_phrase : error->message; 508a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const gchar* quarkStr = isTransportError ? g_quark_to_string(SOUP_HTTP_ERROR) : g_quark_to_string(G_IO_ERROR); 509a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceError resourceError(quarkStr, errorCode, uriStr.get(), String::fromUTF8(errorMsg)); 510a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 511a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 512a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didFail(handle.get(), resourceError); 513a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 515a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 516a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_soupMessage && statusWillBeHandledBySoup(d->m_soupMessage->status_code)) { 5174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(d->m_response.isNull()); 5184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 519a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch fillResponseFromMessage(soupMsg, &d->m_response); 520a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didReceiveResponse(handle.get(), d->m_response); 521a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 522f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // WebCore might have cancelled the job in the while. We 523f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // must check for response_body->length and not 524f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // response_body->data as libsoup always creates the 525f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // SoupBuffer for the body even if the length is 0 526f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!d->m_cancelled && soupMsg->response_body->length) 527a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true); 528a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 529a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 530a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // didReceiveData above might have cancelled it 531a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_cancelled || !client) { 532a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 533a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 534a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 535a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 536a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didFinishLoading(handle.get(), 0); 537a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 538a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 539a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 540a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_cancelled) { 541a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 542a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 543a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 544a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 545cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_inputStream = adoptGRef(in); 546a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); 547a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_total = 0; 548a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 549a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // readCallback needs it 550a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get()); 551a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Ensure a response is sent for any protocols that don't explicitly support responses 5534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // through got-headers signal or content sniffing. 5544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // (e.g. file and GIO based protocol). 5554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!handle->shouldContentSniff() && d->m_response.isNull()) { 5564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setURL(handle->firstRequest().url()); 5574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setMimeType(webkit_soup_request_get_content_type(d->m_soupRequest.get())); 5584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang d->m_response.setExpectedContentLength(webkit_soup_request_get_content_length(d->m_soupRequest.get())); 5594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang client->didReceiveResponse(handle.get(), d->m_response); 560a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 561a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_cancelled) { 562a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 563a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 564a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 565a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 566a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 567f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (d->m_defersLoading) 568f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch soup_session_pause_message(handle->defaultSession(), d->m_soupMessage.get()); 569f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 570a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 571a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, 0); 572a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 574231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic bool startHttp(ResourceHandle* handle) 5758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 5760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(handle); 577231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 5780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SoupSession* session = handle->defaultSession(); 5798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ensureSessionIsInitialized(session); 5808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ResourceHandleInternal* d = handle->getInternal(); 5820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 583967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ResourceRequest request(handle->firstRequest()); 584231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block KURL url(request.url()); 585231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block url.removeFragmentIdentifier(); 586231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block request.setURL(url); 587231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 588a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 589cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_soupRequest = adoptGRef(webkit_soup_requester_request(d->m_requester.get(), url.string().utf8().data(), session, &error.outPtr())); 590a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (error) { 591a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupRequest = 0; 5920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 593a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 594a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 595a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle); 596a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 597cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_soupMessage = adoptGRef(webkit_soup_request_http_get_message(WEBKIT_SOUP_REQUEST_HTTP(d->m_soupRequest.get()))); 598a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!d->m_soupMessage) 599a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return false; 600a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 601a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupMessage* soupMessage = d->m_soupMessage.get(); 602a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch request.updateSoupMessage(soupMessage); 603231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 6046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!handle->shouldContentSniff()) 605a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER); 6064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang else 6074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang g_signal_connect(soupMessage, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle); 6080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 609a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle); 610a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle); 611a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_gotChunkHandler = g_signal_connect(soupMessage, "got-chunk", G_CALLBACK(gotChunkCallback), handle); 6128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#ifdef HAVE_LIBSOUP_2_29_90 6148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block String firstPartyString = request.firstPartyForCookies().string(); 6158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!firstPartyString.isEmpty()) { 6168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); 617a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_set_first_party(soupMessage, firstParty.get()); 6188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 6198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#endif 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 621967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch FormData* httpBody = d->m_firstRequest.httpBody(); 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (httpBody && !httpBody->isEmpty()) { 6238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian size_t numElements = httpBody->elements().size(); 6248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // handle the most common case (i.e. no file upload) 6268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (numElements < 2) { 6278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Vector<char> body; 6288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian httpBody->flatten(body); 629a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_set_request(soupMessage, d->m_firstRequest.httpContentType().utf8().data(), 6308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian SOUP_MEMORY_COPY, body.data(), body.size()); 6318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else { 6328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian /* 6338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * we have more than one element to upload, and some may 6348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * be (big) files, which we will want to mmap instead of 6358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * copying into memory; TODO: support upload of non-local 6368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (think sftp://) files by using GIO? 6378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */ 638a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_body_set_accumulate(soupMessage->request_body, FALSE); 6398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (size_t i = 0; i < numElements; i++) { 6408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian const FormDataElement& element = httpBody->elements()[i]; 6418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (element.m_type == FormDataElement::data) 643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size()); 6448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else { 6458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian /* 6468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * mapping for uploaded files code inspired by technique used in 6478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * libsoup's simple-httpd test 6488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */ 649a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 650545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CString fileName = fileSystemRepresentation(element.m_filename); 651a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr()); 6528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (error) { 654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA, 6550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 0, 0, 0, 0, handle); 656a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupMessage.clear(); 6575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 6588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return false; 6598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 6608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping), 6628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_mapped_file_get_length(fileMapping), 6630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fileMapping, 6640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch reinterpret_cast<GDestroyNotify>(g_mapped_file_unref)); 665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_body_append_buffer(soupMessage->request_body, soupBuffer); 6668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian soup_buffer_free(soupBuffer); 6678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 6688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 6698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // balanced by a deref() in cleanupSoupRequestOperation, which should always run 6730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch handle->ref(); 6748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 675692e5dbf12901edacf14812a6fae25462920af42Steve Block // Make sure we have an Accept header for subresources; some sites 676692e5dbf12901edacf14812a6fae25462920af42Steve Block // want this to serve some of their subresources 677a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept")) 678a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*"); 679692e5dbf12901edacf14812a6fae25462920af42Steve Block 680f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Send the request only if it's not been explicitely deferred. 681f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!d->m_defersLoading) { 682cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_cancellable = adoptGRef(g_cancellable_new()); 683f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0); 684f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 68968513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool ResourceHandle::start(NetworkingContext* context) 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!d->m_soupMessage); 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The frame could be null if the ResourceHandle is not associated to any 6948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Frame, e.g. if we are downloading a file. 6958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If the frame is not null but the page is null this must be an attempted 69668513a70bcd92384395513322f1b801e7bf9c729Steve Block // load from an unload handler, so let's just block it. 69768513a70bcd92384395513322f1b801e7bf9c729Steve Block // If both the frame and the page are not null the context is valid. 69868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (context && !context->isValid()) 6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 701e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) { 702e14391e94c850b8bd03680c23b38978db68687a8John Reck // If credentials were specified for this request, add them to the url, 703e14391e94c850b8bd03680c23b38978db68687a8John Reck // so that they will be passed to NetworkRequest. 704e14391e94c850b8bd03680c23b38978db68687a8John Reck KURL urlWithCredentials(firstRequest().url()); 705e14391e94c850b8bd03680c23b38978db68687a8John Reck urlWithCredentials.setUser(d->m_user); 706e14391e94c850b8bd03680c23b38978db68687a8John Reck urlWithCredentials.setPass(d->m_pass); 707e14391e94c850b8bd03680c23b38978db68687a8John Reck d->m_firstRequest.setURL(urlWithCredentials); 708e14391e94c850b8bd03680c23b38978db68687a8John Reck } 709e14391e94c850b8bd03680c23b38978db68687a8John Reck 710967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch KURL url = firstRequest().url(); 7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String urlString = url.string(); 7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project String protocol = url.protocol(); 7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Used to set the authentication dialog toplevel; may be NULL 71568513a70bcd92384395513322f1b801e7bf9c729Steve Block d->m_context = context; 7168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(protocol, "data")) 7180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return startData(this, urlString); 7198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 720231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) { 721231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (startHttp(this)) 722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 723231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 7248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 725231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps")) { 7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: should we be doing any other protocols here? 727231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (startGio(this, url)) 728231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 7308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 7315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Error must not be reported immediately 7325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian this->scheduleFailure(InvalidURLFailure); 7335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return true; 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ResourceHandle::cancel() 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project d->m_cancelled = true; 740a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (d->m_soupMessage) 741a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch soup_session_cancel_message(defaultSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED); 7428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else if (d->m_cancellable) 743a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_cancellable_cancel(d->m_cancellable.get()); 7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<SharedBuffer> ResourceHandle::bufferedData() 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_NOT_REACHED(); 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ResourceHandle::supportsBufferedData() 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 757f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceHandle::platformSetDefersLoading(bool defersLoading) 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 759f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Initial implementation of this method was required for bug #44157. 760f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 761f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (d->m_cancelled) 762f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 763f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 764f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!defersLoading && !d->m_cancellable && d->m_soupRequest.get()) { 765cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_cancellable = adoptGRef(g_cancellable_new()); 766f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0); 767f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 768f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 769f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 770f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Only supported for http(s) transfers. Something similar would 771f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // probably be needed for data transfers done with GIO. 772f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!d->m_soupMessage) 773f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 774f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 775f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (defersLoading) 776f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch soup_session_pause_message(defaultSession(), d->m_soupMessage.get()); 777f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else 778f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch soup_session_unpause_message(defaultSession(), d->m_soupMessage.get()); 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ResourceHandle::loadsBlocked() 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*) 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Not having this function means that we'll ask the user about re-posting a form 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // even when we go back to a page that's still in the cache. 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project notImplemented(); 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 79468513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data) 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian WebCoreSynchronousLoader syncLoader(error, response, data); 797e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // FIXME: we should use the ResourceHandle::create method here, 798e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // but it makes us timeout in a couple of tests. See 799e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // https://bugs.webkit.org/show_bug.cgi?id=41823 800f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, false /*defersLoading*/, false /*shouldContentSniff*/)); 80168513a70bcd92384395513322f1b801e7bf9c729Steve Block handle->start(context); 8028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian syncLoader.run(); 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 806635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void closeCallback(GObject* source, GAsyncResult* res, gpointer) 8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 808231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); 809635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!handle) 810635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 811635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleInternal* d = handle->getInternal(); 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleClient* client = handle->client(); 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 815a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_input_stream_close_finish(d->m_inputStream.get(), res, 0); 816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 817643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 818643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // The load may have been cancelled, the client may have been 819643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // destroyed already. In such cases calling didFinishLoading is a 820643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // bad idea. 821643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (d->m_cancelled || !client) 822643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 823643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 82468513a70bcd92384395513322f1b801e7bf9c729Steve Block client->didFinishLoading(handle.get(), 0); 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer data) 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); 830635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!handle) 831635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 832635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 833a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool convertToUTF16 = static_cast<bool>(data); 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleInternal* d = handle->getInternal(); 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ResourceHandleClient* client = handle->client(); 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->m_cancelled || !client) { 838a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 842a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 844a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr()); 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (error) { 846a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get()); 847a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<char> uriStr(soup_uri_to_string(uri, false)); 848a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceError resourceError(g_quark_to_string(G_IO_ERROR), error->code, uriStr.get(), 8495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian error ? String::fromUTF8(error->message) : String()); 850a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 8518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian client->didFail(handle.get(), resourceError); 8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 8548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!bytesRead) { 856a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_input_stream_close_async(d->m_inputStream.get(), G_PRIORITY_DEFAULT, 8578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 0, closeCallback, 0); 8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // It's mandatory to have sent a response before sending data 8624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(!d->m_response.isNull()); 8634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 8648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian d->m_total += bytesRead; 865a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (G_LIKELY(!convertToUTF16)) 866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); 867a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else { 868a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // We have to convert it to UTF-16 due to limitations in KURL 869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String data = String::fromUTF8(d->m_buffer, bytesRead); 870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); 8718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 8728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // didReceiveData may cancel the load, which may release the last reference. 8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (d->m_cancelled || !client) { 875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch cleanupSoupRequestOperation(handle.get()); 8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 879a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 880a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_cancellable.get(), readCallback, data); 8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic bool startGio(ResourceHandle* handle, KURL url) 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(handle); 8860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 887967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST") 8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 890a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch SoupSession* session = handle->defaultSession(); 891a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ResourceHandleInternal* d = handle->getInternal(); 892a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 8938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // GIO doesn't know how to handle refs and queries, so remove them 8948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // TODO: use KURL.fileSystemPath after KURLGtk and FileSystemGtk are 8958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // using GIO internally, and providing URIs instead of file paths 8960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 8978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian url.setQuery(String()); 898643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.removePort(); 899a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CString urlStr = url.string().utf8(); 9008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 901a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GOwnPtr<GError> error; 902cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_soupRequest = adoptGRef(webkit_soup_requester_request(d->m_requester.get(), urlStr.data(), session, &error.outPtr())); 903a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (error) { 904a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch d->m_soupRequest = 0; 905a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return false; 906a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 907a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 908a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle); 909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 910a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // balanced by a deref() in cleanupSoupRequestOperation, which should always run 911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block handle->ref(); 912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 913cad810f21b803229eb11403f9209855525a25d57Steve Block d->m_cancellable = adoptGRef(g_cancellable_new()); 914a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0); 915a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianSoupSession* ResourceHandle::defaultSession() 9208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 9216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen static SoupSession* session = createSoupSession(); 9228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return session; 9248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 9258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 927