1/*
2 * Copyright (C) 2005-2017 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#pragma once
30
31#include "FrameLoaderTypes.h"
32#include "ResourceLoader.h"
33#include <wtf/CompletionHandler.h>
34#include <wtf/text/WTFString.h>
35
36namespace WebCore {
37
38class CachedResource;
39class CachedResourceLoader;
40class NetworkLoadMetrics;
41class ResourceRequest;
42class SecurityOrigin;
43
44class SubresourceLoader final : public ResourceLoader {
45public:
46 WEBCORE_EXPORT static void create(Frame&, CachedResource&, ResourceRequest&&, const ResourceLoaderOptions&, CompletionHandler<void(RefPtr<SubresourceLoader>&&)>&&);
47
48 virtual ~SubresourceLoader();
49
50 void cancelIfNotFinishing();
51 bool isSubresourceLoader() const override;
52 CachedResource* cachedResource();
53 WEBCORE_EXPORT const HTTPHeaderMap* originalHeaders() const;
54
55 SecurityOrigin* origin() { return m_origin.get(); }
56#if PLATFORM(IOS_FAMILY)
57 void startLoading() override;
58
59 // FIXME: What is an "iOS" original request? Why is it necessary?
60 const ResourceRequest& iOSOriginalRequest() const override { return m_iOSOriginalRequest; }
61#endif
62
63 unsigned redirectCount() const { return m_redirectCount; }
64
65 void markInAsyncResponsePolicyCheck() { m_inAsyncResponsePolicyCheck = true; }
66 void didReceiveResponsePolicy();
67
68private:
69 SubresourceLoader(Frame&, CachedResource&, const ResourceLoaderOptions&);
70
71 void init(ResourceRequest&&, CompletionHandler<void(bool)>&&) override;
72
73 void willSendRequestInternal(ResourceRequest&&, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&&) override;
74 void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
75 void didReceiveResponse(const ResourceResponse&, CompletionHandler<void()>&& policyCompletionHandler) override;
76 void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType) override;
77 void didReceiveBuffer(Ref<SharedBuffer>&&, long long encodedDataLength, DataPayloadType) override;
78 void didFinishLoading(const NetworkLoadMetrics&) override;
79 void didFail(const ResourceError&) override;
80 void willCancel(const ResourceError&) override;
81 void didCancel(const ResourceError&) override;
82
83 void updateReferrerPolicy(const String&);
84
85#if PLATFORM(COCOA)
86 void willCacheResponseAsync(ResourceHandle*, NSCachedURLResponse*, CompletionHandler<void(NSCachedURLResponse *)>&&) override;
87#endif
88
89 void releaseResources() override;
90
91 bool checkForHTTPStatusCodeError();
92 bool checkResponseCrossOriginAccessControl(const ResourceResponse&, String&);
93 bool checkRedirectionCrossOriginAccessControl(const ResourceRequest& previousRequest, const ResourceResponse&, ResourceRequest& newRequest, String&);
94
95 void didReceiveDataOrBuffer(const char*, int, RefPtr<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
96
97 void notifyDone(LoadCompletionType);
98
99 void reportResourceTiming(const NetworkLoadMetrics&);
100
101#if USE(QUICK_LOOK)
102 bool shouldCreatePreviewLoaderForResponse(const ResourceResponse&) const;
103#endif
104
105 enum SubresourceLoaderState {
106 Uninitialized,
107 Initialized,
108 Finishing,
109#if PLATFORM(IOS_FAMILY)
110 CancelledWhileInitializing
111#endif
112 };
113
114 class RequestCountTracker {
115#if !COMPILER(MSVC)
116 WTF_MAKE_FAST_ALLOCATED;
117#endif
118 public:
119 RequestCountTracker(CachedResourceLoader&, const CachedResource&);
120 ~RequestCountTracker();
121 private:
122 CachedResourceLoader& m_cachedResourceLoader;
123 const CachedResource& m_resource;
124 };
125
126#if PLATFORM(IOS_FAMILY)
127 ResourceRequest m_iOSOriginalRequest;
128#endif
129 CachedResource* m_resource;
130 SubresourceLoaderState m_state;
131 Optional<RequestCountTracker> m_requestCountTracker;
132 RefPtr<SecurityOrigin> m_origin;
133 CompletionHandler<void()> m_policyForResponseCompletionHandler;
134 unsigned m_redirectCount { 0 };
135 bool m_loadingMultipartContent { false };
136 bool m_inAsyncResponsePolicyCheck { false };
137};
138
139}
140
141SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SubresourceLoader)
142static bool isType(const WebCore::ResourceLoader& loader) { return loader.isSubresourceLoader(); }
143SPECIALIZE_TYPE_TRAITS_END()
144