1/*
2 * Copyright (C) 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef NetworkResourceLoader_h
27#define NetworkResourceLoader_h
28
29#if ENABLE(NETWORK_PROCESS)
30
31#include "HostRecord.h"
32#include "MessageSender.h"
33#include "NetworkConnectionToWebProcessMessages.h"
34#include "ShareableResource.h"
35#include <WebCore/ResourceHandleClient.h>
36#include <WebCore/ResourceLoaderOptions.h>
37#include <WebCore/ResourceRequest.h>
38#include <WebCore/SessionID.h>
39#include <wtf/MainThread.h>
40#include <wtf/RunLoop.h>
41
42typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
43
44namespace WebCore {
45class BlobDataFileReference;
46class ResourceBuffer;
47class ResourceHandle;
48class ResourceRequest;
49}
50
51namespace WebKit {
52
53class NetworkConnectionToWebProcess;
54class NetworkLoaderClient;
55class NetworkResourceLoadParameters;
56class RemoteNetworkingContext;
57class SandboxExtension;
58
59class NetworkResourceLoader : public RefCounted<NetworkResourceLoader>, public WebCore::ResourceHandleClient, public IPC::MessageSender {
60public:
61    static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection)
62    {
63        return adoptRef(new NetworkResourceLoader(parameters, connection, nullptr));
64    }
65
66    static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
67    {
68        return adoptRef(new NetworkResourceLoader(parameters, connection, reply));
69    }
70    ~NetworkResourceLoader();
71
72    NetworkConnectionToWebProcess* connectionToWebProcess() const { return m_connection.get(); }
73
74    WebCore::ResourceLoadPriority priority() { return m_priority; }
75    WebCore::ResourceRequest& request() { return m_request; }
76    WebCore::SessionID sessionID() const { return m_sessionID; }
77
78    WebCore::ResourceHandle* handle() const { return m_handle.get(); }
79    void didConvertHandleToDownload();
80
81    void start();
82    void abort();
83
84    void setDefersLoading(bool);
85    bool defersLoading() const { return m_defersLoading; }
86
87    // ResourceHandleClient methods
88    virtual void willSendRequestAsync(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) override;
89    virtual void didSendData(WebCore::ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
90    virtual void didReceiveResponseAsync(WebCore::ResourceHandle*, const WebCore::ResourceResponse&) override;
91    virtual void didReceiveData(WebCore::ResourceHandle*, const char*, unsigned, int encodedDataLength) override;
92    virtual void didReceiveBuffer(WebCore::ResourceHandle*, PassRefPtr<WebCore::SharedBuffer>, int encodedDataLength) override;
93    virtual void didFinishLoading(WebCore::ResourceHandle*, double finishTime) override;
94    virtual void didFail(WebCore::ResourceHandle*, const WebCore::ResourceError&) override;
95    virtual void wasBlocked(WebCore::ResourceHandle*) override;
96    virtual void cannotShowURL(WebCore::ResourceHandle*) override;
97    virtual bool shouldUseCredentialStorage(WebCore::ResourceHandle*) override;
98    virtual void didReceiveAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) override;
99    virtual void didCancelAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) override;
100    virtual void receivedCancellation(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) override;
101    virtual bool usesAsyncCallbacks() override { return true; }
102
103#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
104    virtual void canAuthenticateAgainstProtectionSpaceAsync(WebCore::ResourceHandle*, const WebCore::ProtectionSpace&) override;
105#endif
106
107#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
108    virtual bool supportsDataArray() override;
109    virtual void didReceiveDataArray(WebCore::ResourceHandle*, CFArrayRef) override;
110#endif
111
112#if PLATFORM(COCOA)
113    static size_t fileBackedResourceMinimumSize();
114
115#if USE(CFNETWORK)
116    virtual void willCacheResponseAsync(WebCore::ResourceHandle*, CFCachedURLResponseRef) override;
117#else
118    virtual void willCacheResponseAsync(WebCore::ResourceHandle*, NSCachedURLResponse *) override;
119#endif
120#endif
121
122    // Message handlers.
123    void didReceiveNetworkResourceLoaderMessage(IPC::Connection*, IPC::MessageDecoder&);
124
125#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
126    static void tryGetShareableHandleFromCFURLCachedResponse(ShareableResource::Handle&, CFCachedURLResponseRef);
127    static void tryGetShareableHandleFromSharedBuffer(ShareableResource::Handle&, WebCore::SharedBuffer*);
128#endif
129
130    bool isSynchronous() const;
131    bool isLoadingMainResource() const { return m_isLoadingMainResource; }
132
133    void setHostRecord(HostRecord* hostRecord) { ASSERT(RunLoop::isMain()); m_hostRecord = hostRecord; }
134    HostRecord* hostRecord() const { ASSERT(RunLoop::isMain()); return m_hostRecord.get(); }
135
136    template<typename T>
137    bool sendAbortingOnFailure(T&& message, unsigned messageSendFlags = 0)
138    {
139        bool result = messageSenderConnection()->send(std::forward<T>(message), messageSenderDestinationID(), messageSendFlags);
140        if (!result)
141            abort();
142        return result;
143    }
144
145#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
146    void continueCanAuthenticateAgainstProtectionSpace(bool);
147#endif
148    void continueWillSendRequest(const WebCore::ResourceRequest& newRequest);
149
150    WebCore::SharedBuffer* bufferedData() const { return m_bufferedData.get(); }
151
152private:
153    NetworkResourceLoader(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>);
154
155    // IPC::MessageSender
156    virtual IPC::Connection* messageSenderConnection() override;
157    virtual uint64_t messageSenderDestinationID() override { return m_identifier; }
158
159    void continueDidReceiveResponse();
160
161    void cleanup();
162
163    void platformDidReceiveResponse(const WebCore::ResourceResponse&);
164
165    void consumeSandboxExtensions();
166    void invalidateSandboxExtensions();
167
168    RefPtr<RemoteNetworkingContext> m_networkingContext;
169    RefPtr<WebCore::ResourceHandle> m_handle;
170
171    // Keep the suggested request around while asynchronously asking to update it, because some parts of the request don't survive IPC.
172    WebCore::ResourceRequest m_suggestedRequestForWillSendRequest;
173
174    uint64_t m_bytesReceived;
175
176    bool m_handleConvertedToDownload;
177    std::unique_ptr<NetworkLoaderClient> m_networkLoaderClient;
178
179    ResourceLoadIdentifier m_identifier;
180    uint64_t m_webPageID;
181    uint64_t m_webFrameID;
182    WebCore::SessionID m_sessionID;
183    WebCore::ResourceRequest m_request;
184    WebCore::ResourceRequest m_deferredRequest;
185    WebCore::ResourceLoadPriority m_priority;
186    WebCore::ContentSniffingPolicy m_contentSniffingPolicy;
187    WebCore::StoredCredentials m_allowStoredCredentials;
188    WebCore::ClientCredentialPolicy m_clientCredentialPolicy;
189    bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
190    bool m_isLoadingMainResource;
191    bool m_defersLoading;
192
193    Vector<RefPtr<SandboxExtension>> m_requestBodySandboxExtensions;
194    Vector<RefPtr<SandboxExtension>> m_resourceSandboxExtensions;
195    Vector<RefPtr<WebCore::BlobDataFileReference>> m_fileReferences;
196    bool m_sandboxExtensionsAreConsumed;
197
198    RefPtr<NetworkConnectionToWebProcess> m_connection;
199
200    RefPtr<HostRecord> m_hostRecord;
201    RefPtr<WebCore::SharedBuffer> m_bufferedData;
202};
203
204} // namespace WebKit
205
206#endif // ENABLE(NETWORK_PROCESS)
207
208#endif // NetworkResourceLoader_h
209