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/RunLoop.h>
39#include <wtf/MainThread.h>
40
41typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
42
43namespace WebCore {
44class ResourceBuffer;
45class ResourceHandle;
46class ResourceRequest;
47}
48
49namespace WebKit {
50
51class NetworkConnectionToWebProcess;
52class NetworkLoaderClient;
53class NetworkResourceLoadParameters;
54class RemoteNetworkingContext;
55class SandboxExtension;
56
57class NetworkResourceLoader : public RefCounted<NetworkResourceLoader>, public WebCore::ResourceHandleClient, public CoreIPC::MessageSender {
58public:
59    static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection)
60    {
61        return adoptRef(new NetworkResourceLoader(parameters, connection, nullptr));
62    }
63
64    static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
65    {
66        return adoptRef(new NetworkResourceLoader(parameters, connection, reply));
67    }
68    ~NetworkResourceLoader();
69
70    NetworkConnectionToWebProcess* connectionToWebProcess() const { return m_connection.get(); }
71
72    WebCore::ResourceLoadPriority priority() { return m_priority; }
73    WebCore::ResourceRequest& request() { return m_request; }
74
75    WebCore::ResourceHandle* handle() const { return m_handle.get(); }
76    void didConvertHandleToDownload();
77
78    void start();
79    void abort();
80
81    // ResourceHandleClient methods
82    virtual void willSendRequestAsync(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) OVERRIDE;
83    virtual void didSendData(WebCore::ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
84    virtual void didReceiveResponseAsync(WebCore::ResourceHandle*, const WebCore::ResourceResponse&) OVERRIDE;
85    virtual void didReceiveData(WebCore::ResourceHandle*, const char*, int, int encodedDataLength) OVERRIDE;
86    virtual void didReceiveBuffer(WebCore::ResourceHandle*, PassRefPtr<WebCore::SharedBuffer>, int encodedDataLength) OVERRIDE;
87    virtual void didFinishLoading(WebCore::ResourceHandle*, double finishTime) OVERRIDE;
88    virtual void didFail(WebCore::ResourceHandle*, const WebCore::ResourceError&) OVERRIDE;
89    virtual void wasBlocked(WebCore::ResourceHandle*) OVERRIDE;
90    virtual void cannotShowURL(WebCore::ResourceHandle*) OVERRIDE;
91    virtual bool shouldUseCredentialStorage(WebCore::ResourceHandle*) OVERRIDE;
92    virtual void shouldUseCredentialStorageAsync(WebCore::ResourceHandle*) OVERRIDE;
93    virtual void didReceiveAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) OVERRIDE;
94    virtual void didCancelAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) OVERRIDE;
95    virtual bool usesAsyncCallbacks() OVERRIDE { return true; }
96
97#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
98    virtual void canAuthenticateAgainstProtectionSpaceAsync(WebCore::ResourceHandle*, const WebCore::ProtectionSpace&) OVERRIDE;
99#endif
100
101#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
102    virtual bool supportsDataArray() OVERRIDE;
103    virtual void didReceiveDataArray(WebCore::ResourceHandle*, CFArrayRef) OVERRIDE;
104#endif
105
106#if PLATFORM(MAC)
107    static size_t fileBackedResourceMinimumSize();
108    virtual void willCacheResponseAsync(WebCore::ResourceHandle*, NSCachedURLResponse *) OVERRIDE;
109    virtual void willStopBufferingData(WebCore::ResourceHandle*, const char*, int) OVERRIDE;
110#endif // PLATFORM(MAC)
111
112    // Message handlers.
113    void didReceiveNetworkResourceLoaderMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
114
115#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
116    static void tryGetShareableHandleFromCFURLCachedResponse(ShareableResource::Handle&, CFCachedURLResponseRef);
117#endif
118
119    bool isSynchronous() const;
120    bool isLoadingMainResource() const { return m_isLoadingMainResource; }
121
122    void setHostRecord(HostRecord* hostRecord) { ASSERT(isMainThread()); m_hostRecord = hostRecord; }
123    HostRecord* hostRecord() const { ASSERT(isMainThread()); return m_hostRecord.get(); }
124
125    template<typename U> bool sendAbortingOnFailure(const U& message, unsigned messageSendFlags = 0)
126    {
127        bool result = messageSenderConnection()->send(message, messageSenderDestinationID(), messageSendFlags);
128        if (!result)
129            abort();
130        return result;
131    }
132
133
134#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
135    void continueCanAuthenticateAgainstProtectionSpace(bool);
136#endif
137    void continueWillSendRequest(const WebCore::ResourceRequest& newRequest);
138
139#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
140    static void tryGetShareableHandleFromSharedBuffer(ShareableResource::Handle&, WebCore::SharedBuffer*);
141#endif
142
143private:
144    NetworkResourceLoader(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>);
145
146    // CoreIPC::MessageSender
147    virtual CoreIPC::Connection* messageSenderConnection() OVERRIDE;
148    virtual uint64_t messageSenderDestinationID() OVERRIDE { return m_identifier; }
149
150    void continueDidReceiveResponse();
151
152    void cleanup();
153
154    void platformDidReceiveResponse(const WebCore::ResourceResponse&);
155
156    void consumeSandboxExtensions();
157    void invalidateSandboxExtensions();
158
159    RefPtr<RemoteNetworkingContext> m_networkingContext;
160    RefPtr<WebCore::ResourceHandle> m_handle;
161
162    // Keep the suggested request around while asynchronously asking to update it, because some parts of the request don't survive IPC.
163    WebCore::ResourceRequest m_suggestedRequestForWillSendRequest;
164
165    uint64_t m_bytesReceived;
166
167    bool m_handleConvertedToDownload;
168    OwnPtr<NetworkLoaderClient> m_networkLoaderClient;
169
170    ResourceLoadIdentifier m_identifier;
171    uint64_t m_webPageID;
172    uint64_t m_webFrameID;
173    WebCore::ResourceRequest m_request;
174    WebCore::ResourceLoadPriority m_priority;
175    WebCore::ContentSniffingPolicy m_contentSniffingPolicy;
176    WebCore::StoredCredentials m_allowStoredCredentials;
177    WebCore::ClientCredentialPolicy m_clientCredentialPolicy;
178    bool m_inPrivateBrowsingMode;
179    bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
180    bool m_isLoadingMainResource;
181
182    Vector<RefPtr<SandboxExtension>> m_requestBodySandboxExtensions;
183    Vector<RefPtr<SandboxExtension>> m_resourceSandboxExtensions;
184    bool m_sandboxExtensionsAreConsumed;
185
186    RefPtr<NetworkConnectionToWebProcess> m_connection;
187
188    RefPtr<HostRecord> m_hostRecord;
189};
190
191} // namespace WebKit
192
193#endif // ENABLE(NETWORK_PROCESS)
194
195#endif // NetworkResourceLoader_h
196