1 /*
2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2008 Holger Hans Peter Freyther
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "config.h"
31 #include "ResourceHandle.h"
32
33 #include "ChromeClientQt.h"
34 #include "CachedResourceLoader.h"
35 #include "Frame.h"
36 #include "FrameNetworkingContext.h"
37 #include "FrameLoaderClientQt.h"
38 #include "NotImplemented.h"
39 #include "Page.h"
40 #include "QNetworkReplyHandler.h"
41 #include "ResourceHandleClient.h"
42 #include "ResourceHandleInternal.h"
43 #include "SharedBuffer.h"
44
45 #include <QAbstractNetworkCache>
46 #include <QCoreApplication>
47 #include <QUrl>
48 #include <QNetworkAccessManager>
49 #include <QNetworkRequest>
50 #include <QNetworkReply>
51
52 namespace WebCore {
53
54 class WebCoreSynchronousLoader : public ResourceHandleClient {
55 public:
WebCoreSynchronousLoader(ResourceError & error,ResourceResponse & response,Vector<char> & data)56 WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
57 : m_error(error)
58 , m_response(response)
59 , m_data(data)
60 {}
61
didReceiveResponse(ResourceHandle *,const ResourceResponse & response)62 virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { m_response = response; }
didReceiveData(ResourceHandle *,const char * data,int length,int)63 virtual void didReceiveData(ResourceHandle*, const char* data, int length, int) { m_data.append(data, length); }
didFinishLoading(ResourceHandle *,double)64 virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) {}
didFail(ResourceHandle *,const ResourceError & error)65 virtual void didFail(ResourceHandle*, const ResourceError& error) { m_error = error; }
66 private:
67 ResourceError& m_error;
68 ResourceResponse& m_response;
69 Vector<char>& m_data;
70 };
71
~ResourceHandleInternal()72 ResourceHandleInternal::~ResourceHandleInternal()
73 {
74 }
75
~ResourceHandle()76 ResourceHandle::~ResourceHandle()
77 {
78 if (d->m_job)
79 cancel();
80 }
81
start(NetworkingContext * context)82 bool ResourceHandle::start(NetworkingContext* context)
83 {
84 // If NetworkingContext is invalid then we are no longer attached to a Page,
85 // this must be an attempted load from an unload event handler, so let's just block it.
86 if (context && !context->isValid())
87 return false;
88
89 if (!d->m_user.isEmpty() || !d->m_pass.isEmpty()) {
90 // If credentials were specified for this request, add them to the url,
91 // so that they will be passed to QNetworkRequest.
92 KURL urlWithCredentials(firstRequest().url());
93 urlWithCredentials.setUser(d->m_user);
94 urlWithCredentials.setPass(d->m_pass);
95 d->m_firstRequest.setURL(urlWithCredentials);
96 }
97
98 getInternal()->m_context = context;
99 ResourceHandleInternal *d = getInternal();
100 d->m_job = new QNetworkReplyHandler(this, QNetworkReplyHandler::AsynchronousLoad, d->m_defersLoading);
101 return true;
102 }
103
cancel()104 void ResourceHandle::cancel()
105 {
106 if (d->m_job) {
107 d->m_job->abort();
108 d->m_job = 0;
109 }
110 }
111
loadsBlocked()112 bool ResourceHandle::loadsBlocked()
113 {
114 return false;
115 }
116
willLoadFromCache(ResourceRequest & request,Frame * frame)117 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame)
118 {
119 if (!frame)
120 return false;
121
122 QNetworkAccessManager* manager = 0;
123 QAbstractNetworkCache* cache = 0;
124 if (frame->loader()->networkingContext()) {
125 manager = frame->loader()->networkingContext()->networkAccessManager();
126 cache = manager->cache();
127 }
128
129 if (!cache)
130 return false;
131
132 QNetworkCacheMetaData data = cache->metaData(request.url());
133 if (data.isValid()) {
134 request.setCachePolicy(ReturnCacheDataDontLoad);
135 return true;
136 }
137
138 return false;
139 }
140
supportsBufferedData()141 bool ResourceHandle::supportsBufferedData()
142 {
143 return false;
144 }
145
bufferedData()146 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
147 {
148 ASSERT_NOT_REACHED();
149 return 0;
150 }
151
loadResourceSynchronously(NetworkingContext * context,const ResourceRequest & request,StoredCredentials,ResourceError & error,ResourceResponse & response,Vector<char> & data)152 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data)
153 {
154 WebCoreSynchronousLoader syncLoader(error, response, data);
155 RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false));
156
157 ResourceHandleInternal* d = handle->getInternal();
158 if (!d->m_user.isEmpty() || !d->m_pass.isEmpty()) {
159 // If credentials were specified for this request, add them to the url,
160 // so that they will be passed to QNetworkRequest.
161 KURL urlWithCredentials(d->m_firstRequest.url());
162 urlWithCredentials.setUser(d->m_user);
163 urlWithCredentials.setPass(d->m_pass);
164 d->m_firstRequest.setURL(urlWithCredentials);
165 }
166 d->m_context = context;
167
168 // starting in deferred mode gives d->m_job the chance of being set before sending the request.
169 d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::SynchronousLoad, true);
170 d->m_job->setLoadingDeferred(false);
171 }
172
platformSetDefersLoading(bool defers)173 void ResourceHandle::platformSetDefersLoading(bool defers)
174 {
175 if (!d->m_job)
176 return;
177 d->m_job->setLoadingDeferred(defers);
178 }
179
180 } // namespace WebCore
181