d426ad133c1b70d863d18a42c7e42ec53334edf1
[WebKit-https.git] / Source / WebCore / loader / NetscapePlugInStreamLoader.cpp
1 /*
2  * Copyright (C) 2006 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 #include "config.h"
30 #include "NetscapePlugInStreamLoader.h"
31
32 #include "DocumentLoader.h"
33 #include "FrameLoader.h"
34 #include "FrameLoaderClient.h"
35 #include <wtf/CompletionHandler.h>
36 #include <wtf/Ref.h>
37
38 #if ENABLE(CONTENT_EXTENSIONS)
39 #include "ResourceLoadInfo.h"
40 #endif
41
42 namespace WebCore {
43
44 // FIXME: Skip Content Security Policy check when associated plugin element is in a user agent shadow tree.
45 // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
46 NetscapePlugInStreamLoader::NetscapePlugInStreamLoader(Frame& frame, NetscapePlugInStreamLoaderClient& client)
47     : ResourceLoader(frame, ResourceLoaderOptions(
48         SendCallbackPolicy::SendCallbacks,
49         ContentSniffingPolicy::SniffContent,
50         DataBufferingPolicy::DoNotBufferData,
51         StoredCredentialsPolicy::Use,
52         ClientCredentialPolicy::MayAskClientForCredentials,
53         FetchOptions::Credentials::Include,
54         SecurityCheckPolicy::SkipSecurityCheck,
55         FetchOptions::Mode::NoCors,
56         CertificateInfoPolicy::DoNotIncludeCertificateInfo,
57         ContentSecurityPolicyImposition::DoPolicyCheck,
58         DefersLoadingPolicy::AllowDefersLoading,
59         CachingPolicy::AllowCaching))
60     , m_client(&client)
61 {
62 #if ENABLE(CONTENT_EXTENSIONS)
63     m_resourceType = ContentExtensions::ResourceType::PlugInStream;
64 #endif
65 }
66
67 NetscapePlugInStreamLoader::~NetscapePlugInStreamLoader() = default;
68
69 void NetscapePlugInStreamLoader::create(Frame& frame, NetscapePlugInStreamLoaderClient& client, ResourceRequest&& request, CompletionHandler<void(RefPtr<NetscapePlugInStreamLoader>&&)>&& completionHandler)
70 {
71     auto loader(adoptRef(*new NetscapePlugInStreamLoader(frame, client)));
72     loader->init(WTFMove(request), [loader = loader.copyRef(), completionHandler = WTFMove(completionHandler)] (bool initialized) mutable {
73         if (!initialized)
74             return completionHandler(nullptr);
75         completionHandler(WTFMove(loader));
76     });
77 }
78
79 bool NetscapePlugInStreamLoader::isDone() const
80 {
81     return !m_client;
82 }
83
84 void NetscapePlugInStreamLoader::releaseResources()
85 {
86     m_client = nullptr;
87     ResourceLoader::releaseResources();
88 }
89
90 void NetscapePlugInStreamLoader::init(ResourceRequest&& request, CompletionHandler<void(bool)>&& completionHandler)
91 {
92     ResourceLoader::init(WTFMove(request), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (bool success) mutable {
93         if (!success)
94             return completionHandler(false);
95         ASSERT(!reachedTerminalState());
96         m_documentLoader->addPlugInStreamLoader(*this);
97         m_isInitialized = true;
98         completionHandler(true);
99     });
100 }
101
102 void NetscapePlugInStreamLoader::willSendRequest(ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& callback)
103 {
104     m_client->willSendRequest(this, WTFMove(request), redirectResponse, [protectedThis = makeRef(*this), redirectResponse, callback = WTFMove(callback)] (ResourceRequest&& request) mutable {
105         if (!request.isNull())
106             protectedThis->willSendRequestInternal(WTFMove(request), redirectResponse, WTFMove(callback));
107         else
108             callback({ });
109     });
110 }
111
112 void NetscapePlugInStreamLoader::didReceiveResponse(const ResourceResponse& response, CompletionHandler<void()>&& policyCompletionHandler)
113 {
114     Ref<NetscapePlugInStreamLoader> protectedThis(*this);
115     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(policyCompletionHandler));
116
117     m_client->didReceiveResponse(this, response);
118
119     // Don't continue if the stream is cancelled
120     if (!m_client)
121         return;
122
123     ResourceLoader::didReceiveResponse(response, [this, protectedThis = WTFMove(protectedThis), response, completionHandlerCaller = WTFMove(completionHandlerCaller)]() mutable {
124         // Don't continue if the stream is cancelled
125         if (!m_client)
126             return;
127
128         if (!response.isHTTP())
129             return;
130
131         if (m_client->wantsAllStreams())
132             return;
133
134         // Status code can be null when serving from a Web archive.
135         if (response.httpStatusCode() && (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400))
136             cancel(frameLoader()->client().fileDoesNotExistError(response));
137     });
138 }
139
140 void NetscapePlugInStreamLoader::didReceiveData(const char* data, unsigned length, long long encodedDataLength, DataPayloadType dataPayloadType)
141 {
142     didReceiveDataOrBuffer(data, length, nullptr, encodedDataLength, dataPayloadType);
143 }
144
145 void NetscapePlugInStreamLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
146 {
147     didReceiveDataOrBuffer(nullptr, 0, WTFMove(buffer), encodedDataLength, dataPayloadType);
148 }
149
150 void NetscapePlugInStreamLoader::didReceiveDataOrBuffer(const char* data, int length, RefPtr<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
151 {
152     Ref<NetscapePlugInStreamLoader> protectedThis(*this);
153     
154     m_client->didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length);
155
156     ResourceLoader::didReceiveDataOrBuffer(data, length, WTFMove(buffer), encodedDataLength, dataPayloadType);
157 }
158
159 void NetscapePlugInStreamLoader::didFinishLoading(const NetworkLoadMetrics& networkLoadMetrics)
160 {
161     Ref<NetscapePlugInStreamLoader> protectedThis(*this);
162
163     notifyDone();
164
165     m_client->didFinishLoading(this);
166     ResourceLoader::didFinishLoading(networkLoadMetrics);
167 }
168
169 void NetscapePlugInStreamLoader::didFail(const ResourceError& error)
170 {
171     Ref<NetscapePlugInStreamLoader> protectedThis(*this);
172
173     notifyDone();
174
175     m_client->didFail(this, error);
176     ResourceLoader::didFail(error);
177 }
178
179 void NetscapePlugInStreamLoader::willCancel(const ResourceError& error)
180 {
181     m_client->didFail(this, error);
182 }
183
184 void NetscapePlugInStreamLoader::didCancel(const ResourceError&)
185 {
186     notifyDone();
187 }
188
189 void NetscapePlugInStreamLoader::notifyDone()
190 {
191     if (!m_isInitialized)
192         return;
193
194     m_documentLoader->removePlugInStreamLoader(*this);
195 }
196
197
198 }