e3e2629234c5573f19cc143b7005ae4d942ab983
[WebKit-https.git] / Source / WebCore / loader / ResourceLoader.cpp
1 /*
2  * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
3  *           (C) 2007 Graham Dennis (graham.dennis@gmail.com)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "ResourceLoader.h"
32
33 #include "ApplicationCacheHost.h"
34 #include "AuthenticationChallenge.h"
35 #include "ContentRuleListResults.h"
36 #include "CustomHeaderFields.h"
37 #include "DataURLDecoder.h"
38 #include "DiagnosticLoggingClient.h"
39 #include "DiagnosticLoggingKeys.h"
40 #include "DocumentLoader.h"
41 #include "Frame.h"
42 #include "FrameLoader.h"
43 #include "FrameLoaderClient.h"
44 #include "InspectorInstrumentation.h"
45 #include "LoaderStrategy.h"
46 #include "Logging.h"
47 #include "Page.h"
48 #include "PlatformStrategies.h"
49 #include "ProgressTracker.h"
50 #include "ResourceError.h"
51 #include "ResourceHandle.h"
52 #include "SecurityOrigin.h"
53 #include "SharedBuffer.h"
54 #include <wtf/CompletionHandler.h>
55 #include <wtf/Ref.h>
56
57 #if ENABLE(CONTENT_EXTENSIONS)
58 #include "UserContentController.h"
59 #endif
60
61 #if USE(QUICK_LOOK)
62 #include "PreviewConverter.h"
63 #include "PreviewLoader.h"
64 #endif
65
66 #undef RELEASE_LOG_IF_ALLOWED
67 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Network, "%p - ResourceLoader::" fmt, this, ##__VA_ARGS__)
68
69 namespace WebCore {
70
71 ResourceLoader::ResourceLoader(Frame& frame, ResourceLoaderOptions options)
72     : m_frame { &frame }
73     , m_documentLoader { frame.loader().activeDocumentLoader() }
74     , m_defersLoading { options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && frame.page()->defersLoading() }
75     , m_options { options }
76 {
77 }
78
79 ResourceLoader::~ResourceLoader()
80 {
81     ASSERT(m_reachedTerminalState);
82 }
83
84 void ResourceLoader::finishNetworkLoad()
85 {
86     platformStrategies()->loaderStrategy()->remove(this);
87
88     if (m_handle) {
89         ASSERT(m_handle->client() == this);
90         m_handle->clearClient();
91         m_handle = nullptr;
92     }
93 }
94
95 void ResourceLoader::releaseResources()
96 {
97     ASSERT(!m_reachedTerminalState);
98     
99     // It's possible that when we release the handle, it will be
100     // deallocated and release the last reference to this object.
101     // We need to retain to avoid accessing the object after it
102     // has been deallocated and also to avoid reentering this method.
103     Ref<ResourceLoader> protectedThis(*this);
104
105     m_frame = nullptr;
106     m_documentLoader = nullptr;
107     
108     // We need to set reachedTerminalState to true before we release
109     // the resources to prevent a double dealloc of WebView <rdar://problem/4372628>
110     m_reachedTerminalState = true;
111
112     finishNetworkLoad();
113
114     m_identifier = 0;
115
116     m_resourceData = nullptr;
117     m_deferredRequest = ResourceRequest();
118 }
119
120 void ResourceLoader::init(ResourceRequest&& clientRequest, CompletionHandler<void(bool)>&& completionHandler)
121 {
122 #if PLATFORM(IOS_FAMILY)
123     if (!m_documentLoader) {
124         // We should always have a DocumentLoader at this point, but crash reports indicate that it is sometimes null.
125         // See https://bugs.webkit.org/show_bug.cgi?id=187360
126         ASSERT_NOT_REACHED();
127         return completionHandler(false);
128     }
129 #endif
130     ASSERT(!m_handle);
131     ASSERT(m_request.isNull());
132     ASSERT(m_deferredRequest.isNull());
133     ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
134     
135     m_loadTiming.markStartTimeAndFetchStart();
136
137 #if PLATFORM(IOS_FAMILY)
138     // If the documentLoader was detached while this ResourceLoader was waiting its turn
139     // in ResourceLoadScheduler queue, don't continue.
140     if (!m_documentLoader->frame()) {
141         cancel();
142         return completionHandler(false);
143     }
144 #endif
145     
146     m_defersLoading = m_options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && m_frame->page()->defersLoading();
147
148     if (m_options.securityCheck == SecurityCheckPolicy::DoSecurityCheck && !m_frame->document()->securityOrigin().canDisplay(clientRequest.url())) {
149         FrameLoader::reportLocalLoadFailed(m_frame.get(), clientRequest.url().string());
150         releaseResources();
151         return completionHandler(false);
152     }
153
154     // The various plug-in implementations call directly to ResourceLoader::load() instead of piping requests
155     // through FrameLoader. As a result, they miss the FrameLoader::addExtraFieldsToRequest() step which sets
156     // up the 1st party for cookies URL and Same-Site info. Until plug-in implementations can be reigned in
157     // to pipe through that method, we need to make sure there is always both a 1st party for cookies set and
158     // Same-Site info. See <https://bugs.webkit.org/show_bug.cgi?id=26391>.
159     if (clientRequest.firstPartyForCookies().isNull()) {
160         if (Document* document = m_frame->document())
161             clientRequest.setFirstPartyForCookies(document->firstPartyForCookies());
162     }
163     FrameLoader::addSameSiteInfoToRequestIfNeeded(clientRequest, m_frame->document());
164
165     willSendRequestInternal(WTFMove(clientRequest), ResourceResponse(), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](ResourceRequest&& request) mutable {
166
167 #if PLATFORM(IOS_FAMILY)
168         // If this ResourceLoader was stopped as a result of willSendRequest, bail out.
169         if (m_reachedTerminalState)
170             return completionHandler(false);
171 #endif
172
173         if (request.isNull()) {
174             cancel();
175             return completionHandler(false);
176         }
177
178         m_request = WTFMove(request);
179         m_originalRequest = m_request;
180         completionHandler(true);
181     });
182 }
183
184 void ResourceLoader::deliverResponseAndData(const ResourceResponse& response, RefPtr<SharedBuffer>&& buffer)
185 {
186     didReceiveResponse(response, [this, protectedThis = makeRef(*this), buffer = WTFMove(buffer)]() mutable {
187         if (reachedTerminalState())
188             return;
189
190         if (buffer) {
191             unsigned size = buffer->size();
192             didReceiveBuffer(buffer.releaseNonNull(), size, DataPayloadWholeResource);
193             if (reachedTerminalState())
194                 return;
195         }
196
197         NetworkLoadMetrics emptyMetrics;
198         didFinishLoading(emptyMetrics);
199     });
200 }
201
202 void ResourceLoader::start()
203 {
204     ASSERT(!m_handle);
205     ASSERT(!m_request.isNull());
206     ASSERT(m_deferredRequest.isNull());
207     ASSERT(frameLoader());
208
209 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
210     if (m_documentLoader->scheduleArchiveLoad(*this, m_request))
211         return;
212 #endif
213
214     if (m_documentLoader->applicationCacheHost().maybeLoadResource(*this, m_request, m_request.url()))
215         return;
216
217     if (m_defersLoading) {
218         m_deferredRequest = m_request;
219         return;
220     }
221
222     if (m_reachedTerminalState)
223         return;
224
225     if (m_request.url().protocolIsData()) {
226         loadDataURL();
227         return;
228     }
229
230 #if USE(SOUP)
231     if (m_request.url().protocolIs("resource")) {
232         loadGResource();
233         return;
234     }
235 #endif
236
237     m_handle = ResourceHandle::create(frameLoader()->networkingContext(), m_request, this, m_defersLoading, m_options.sniffContent == ContentSniffingPolicy::SniffContent, m_options.sniffContentEncoding == ContentEncodingSniffingPolicy::Sniff);
238 }
239
240 void ResourceLoader::setDefersLoading(bool defers)
241 {
242     if (m_options.defersLoadingPolicy == DefersLoadingPolicy::DisallowDefersLoading)
243         return;
244
245     m_defersLoading = defers;
246     if (m_handle)
247         m_handle->setDefersLoading(defers);
248
249     platformStrategies()->loaderStrategy()->setDefersLoading(*this, defers);
250 }
251
252 FrameLoader* ResourceLoader::frameLoader() const
253 {
254     if (!m_frame)
255         return nullptr;
256     return &m_frame->loader();
257 }
258
259 void ResourceLoader::loadDataURL()
260 {
261     auto url = m_request.url();
262     ASSERT(url.protocolIsData());
263
264     DataURLDecoder::ScheduleContext scheduleContext;
265 #if HAVE(RUNLOOP_TIMER)
266     if (auto* scheduledPairs = m_frame->page()->scheduledRunLoopPairs())
267         scheduleContext.scheduledPairs = *scheduledPairs;
268 #endif
269     DataURLDecoder::decode(url, scheduleContext, [this, protectedThis = makeRef(*this), url](auto decodeResult) mutable {
270         if (this->reachedTerminalState())
271             return;
272         if (!decodeResult) {
273             RELEASE_LOG_IF_ALLOWED("loadDataURL: decoding of data failed (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
274             protectedThis->didFail(ResourceError(errorDomainWebKitInternal, 0, url, "Data URL decoding failed"));
275             return;
276         }
277         if (this->wasCancelled())
278             return;
279         auto& result = decodeResult.value();
280         auto dataSize = result.data ? result.data->size() : 0;
281
282         ResourceResponse dataResponse { url, result.mimeType, static_cast<long long>(dataSize), result.charset };
283         dataResponse.setHTTPStatusCode(200);
284         dataResponse.setHTTPStatusText("OK"_s);
285         dataResponse.setHTTPHeaderField(HTTPHeaderName::ContentType, result.contentType);
286         dataResponse.setSource(ResourceResponse::Source::Network);
287         this->didReceiveResponse(dataResponse, [this, protectedThis = WTFMove(protectedThis), dataSize, data = result.data.releaseNonNull()]() mutable {
288             if (!this->reachedTerminalState() && dataSize && m_request.httpMethod() != "HEAD")
289                 this->didReceiveBuffer(WTFMove(data), dataSize, DataPayloadWholeResource);
290
291             if (!this->reachedTerminalState()) {
292                 NetworkLoadMetrics emptyMetrics;
293                 this->didFinishLoading(emptyMetrics);
294             }
295         });
296     });
297 }
298
299 void ResourceLoader::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
300 {
301     m_options.dataBufferingPolicy = dataBufferingPolicy;
302
303     // Reset any already buffered data
304     if (dataBufferingPolicy == DataBufferingPolicy::DoNotBufferData)
305         m_resourceData = nullptr;
306 }
307
308 void ResourceLoader::willSwitchToSubstituteResource()
309 {
310     ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
311     platformStrategies()->loaderStrategy()->remove(this);
312     if (m_handle)
313         m_handle->cancel();
314 }
315
316 void ResourceLoader::addDataOrBuffer(const char* data, unsigned length, SharedBuffer* buffer, DataPayloadType dataPayloadType)
317 {
318     if (m_options.dataBufferingPolicy == DataBufferingPolicy::DoNotBufferData)
319         return;
320
321     if (!m_resourceData || dataPayloadType == DataPayloadWholeResource) {
322         if (buffer)
323             m_resourceData = buffer;
324         else
325             m_resourceData = SharedBuffer::create(data, length);
326         return;
327     }
328     
329     if (buffer)
330         m_resourceData->append(*buffer);
331     else
332         m_resourceData->append(data, length);
333 }
334
335 void ResourceLoader::clearResourceData()
336 {
337     if (m_resourceData)
338         m_resourceData->clear();
339 }
340
341 bool ResourceLoader::isSubresourceLoader() const
342 {
343     return false;
344 }
345
346 void ResourceLoader::willSendRequestInternal(ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
347 {
348     // Protect this in this delegate method since the additional processing can do
349     // anything including possibly derefing this; one example of this is Radar 3266216.
350     Ref<ResourceLoader> protectedThis(*this);
351
352     ASSERT(!m_reachedTerminalState);
353 #if ENABLE(CONTENT_EXTENSIONS)
354     ASSERT(m_resourceType != ContentExtensions::ResourceType::Invalid);
355 #endif
356
357     // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
358     bool createdResourceIdentifier = false;
359     if (!m_identifier) {
360         m_identifier = m_frame->page()->progress().createUniqueIdentifier();
361         createdResourceIdentifier = true;
362     }
363
364 #if ENABLE(CONTENT_EXTENSIONS)
365     if (!redirectResponse.isNull() && frameLoader()) {
366         Page* page = frameLoader()->frame().page();
367         if (page && m_documentLoader) {
368             auto results = page->userContentProvider().processContentRuleListsForLoad(request.url(), m_resourceType, *m_documentLoader);
369             bool blockedLoad = results.summary.blockedLoad;
370             ContentExtensions::applyResultsToRequest(WTFMove(results), page, request);
371             if (blockedLoad) {
372                 RELEASE_LOG_IF_ALLOWED("willSendRequestinternal: resource load canceled because of content blocker (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
373                 didFail(blockedByContentBlockerError());
374                 completionHandler({ });
375                 return;
376             }
377         }
378     }
379 #endif
380
381     if (request.isNull()) {
382         RELEASE_LOG_IF_ALLOWED("willSendRequestinternal: resource load canceled because of empty request (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
383         didFail(cannotShowURLError());
384         completionHandler({ });
385         return;
386     }
387
388     if (m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks) {
389         if (createdResourceIdentifier)
390             frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);
391
392 #if PLATFORM(IOS_FAMILY)
393         // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out
394         if (m_reachedTerminalState) {
395             completionHandler(WTFMove(request));
396             return;
397         }
398 #endif
399
400         frameLoader()->notifier().willSendRequest(this, request, redirectResponse);
401     }
402     else
403         InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse);
404
405 #if USE(QUICK_LOOK)
406     if (auto previewConverter = m_documentLoader->previewConverter())
407         request = previewConverter->safeRequest(request);
408 #endif
409
410     bool isRedirect = !redirectResponse.isNull();
411     if (isRedirect)
412         platformStrategies()->loaderStrategy()->crossOriginRedirectReceived(this, request.url());
413
414     m_request = request;
415
416     if (isRedirect) {
417         auto& redirectURL = request.url();
418         if (!m_documentLoader->isCommitted())
419             frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
420
421         if (redirectURL.protocolIsData()) {
422             // Handle data URL decoding locally.
423             finishNetworkLoad();
424             loadDataURL();
425         }
426     }
427     completionHandler(WTFMove(request));
428 }
429
430 void ResourceLoader::willSendRequest(ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
431 {
432     willSendRequestInternal(WTFMove(request), redirectResponse, WTFMove(completionHandler));
433 }
434
435 void ResourceLoader::didSendData(unsigned long long, unsigned long long)
436 {
437 }
438
439 static void logResourceResponseSource(Frame* frame, ResourceResponse::Source source)
440 {
441     if (!frame || !frame->page())
442         return;
443
444     String sourceKey;
445     switch (source) {
446     case ResourceResponse::Source::Network:
447         sourceKey = DiagnosticLoggingKeys::networkKey();
448         break;
449     case ResourceResponse::Source::DiskCache:
450         sourceKey = DiagnosticLoggingKeys::diskCacheKey();
451         break;
452     case ResourceResponse::Source::DiskCacheAfterValidation:
453         sourceKey = DiagnosticLoggingKeys::diskCacheAfterValidationKey();
454         break;
455     case ResourceResponse::Source::ServiceWorker:
456         sourceKey = DiagnosticLoggingKeys::serviceWorkerKey();
457         break;
458     case ResourceResponse::Source::MemoryCache:
459     case ResourceResponse::Source::MemoryCacheAfterValidation:
460     case ResourceResponse::Source::ApplicationCache:
461     case ResourceResponse::Source::InspectorOverride:
462     case ResourceResponse::Source::Unknown:
463         return;
464     }
465
466     frame->page()->diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::resourceResponseSourceKey(), sourceKey, ShouldSample::Yes);
467 }
468
469 bool ResourceLoader::shouldAllowResourceToAskForCredentials() const
470 {
471     return m_canCrossOriginRequestsAskUserForCredentials || m_frame->tree().top().document()->securityOrigin().canRequest(m_request.url());
472 }
473
474 void ResourceLoader::didBlockAuthenticationChallenge()
475 {
476     m_wasAuthenticationChallengeBlocked = true;
477     if (m_options.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials)
478         return;
479     ASSERT(!shouldAllowResourceToAskForCredentials());
480     FrameLoader::reportAuthenticationChallengeBlocked(m_frame.get(), m_request.url(), "it is a cross-origin request"_s);
481 }
482
483 void ResourceLoader::didReceiveResponse(const ResourceResponse& r, CompletionHandler<void()>&& policyCompletionHandler)
484 {
485     ASSERT(!m_reachedTerminalState);
486     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(policyCompletionHandler));
487
488     // Protect this in this delegate method since the additional processing can do
489     // anything including possibly derefing this; one example of this is Radar 3266216.
490     Ref<ResourceLoader> protectedThis(*this);
491
492     logResourceResponseSource(m_frame.get(), r.source());
493
494     m_response = r;
495
496     if (m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks)
497         frameLoader()->notifier().didReceiveResponse(this, m_response);
498 }
499
500 void ResourceLoader::didReceiveData(const char* data, unsigned length, long long encodedDataLength, DataPayloadType dataPayloadType)
501 {
502     // The following assertions are not quite valid here, since a subclass
503     // might override didReceiveData in a way that invalidates them. This
504     // happens with the steps listed in 3266216
505     // ASSERT(con == connection);
506     // ASSERT(!m_reachedTerminalState);
507
508     didReceiveDataOrBuffer(data, length, nullptr, encodedDataLength, dataPayloadType);
509 }
510
511 void ResourceLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
512 {
513     didReceiveDataOrBuffer(nullptr, 0, WTFMove(buffer), encodedDataLength, dataPayloadType);
514 }
515
516 void ResourceLoader::didReceiveDataOrBuffer(const char* data, unsigned length, RefPtr<SharedBuffer>&& buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
517 {
518     // This method should only get data+length *OR* a SharedBuffer.
519     ASSERT(!buffer || (!data && !length));
520
521     // Protect this in this delegate method since the additional processing can do
522     // anything including possibly derefing this; one example of this is Radar 3266216.
523     Ref<ResourceLoader> protectedThis(*this);
524
525     addDataOrBuffer(data, length, buffer.get(), dataPayloadType);
526
527     // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
528     // However, with today's computers and networking speeds, this won't happen in practice.
529     // Could be an issue with a giant local file.
530     if (m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks && m_frame)
531         frameLoader()->notifier().didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length, static_cast<int>(encodedDataLength));
532 }
533
534 void ResourceLoader::didFinishLoading(const NetworkLoadMetrics& networkLoadMetrics)
535 {
536     RELEASE_LOG_IF_ALLOWED("didFinishLoading: (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
537
538     didFinishLoadingOnePart(networkLoadMetrics);
539
540     // If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
541     // the resources a second time, they have been released by cancel.
542     if (wasCancelled())
543         return;
544     releaseResources();
545 }
546
547 void ResourceLoader::didFinishLoadingOnePart(const NetworkLoadMetrics& networkLoadMetrics)
548 {
549     // If load has been cancelled after finishing (which could happen with a
550     // JavaScript that changes the window location), do nothing.
551     if (wasCancelled())
552         return;
553     ASSERT(!m_reachedTerminalState);
554
555     if (m_notifiedLoadComplete)
556         return;
557     m_notifiedLoadComplete = true;
558     if (m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks)
559         frameLoader()->notifier().didFinishLoad(this, networkLoadMetrics);
560 }
561
562 void ResourceLoader::didFail(const ResourceError& error)
563 {
564     RELEASE_LOG_IF_ALLOWED("didFail: (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
565
566     if (wasCancelled())
567         return;
568     ASSERT(!m_reachedTerminalState);
569
570     // Protect this in this delegate method since the additional processing can do
571     // anything including possibly derefing this; one example of this is Radar 3266216.
572     Ref<ResourceLoader> protectedThis(*this);
573
574     cleanupForError(error);
575     releaseResources();
576 }
577
578 void ResourceLoader::cleanupForError(const ResourceError& error)
579 {
580     if (m_notifiedLoadComplete)
581         return;
582     m_notifiedLoadComplete = true;
583     if (m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks && m_identifier)
584         frameLoader()->notifier().didFailToLoad(this, error);
585 }
586
587 void ResourceLoader::cancel()
588 {
589     cancel(ResourceError());
590 }
591
592 void ResourceLoader::cancel(const ResourceError& error)
593 {
594     // If the load has already completed - succeeded, failed, or previously cancelled - do nothing.
595     if (m_reachedTerminalState)
596         return;
597        
598     ResourceError nonNullError = error.isNull() ? cancelledError() : error;
599     
600     // willCancel() and didFailToLoad() both call out to clients that might do 
601     // something causing the last reference to this object to go away.
602     Ref<ResourceLoader> protectedThis(*this);
603     
604     // If we re-enter cancel() from inside willCancel(), we want to pick up from where we left 
605     // off without re-running willCancel()
606     if (m_cancellationStatus == NotCancelled) {
607         m_cancellationStatus = CalledWillCancel;
608         
609         willCancel(nonNullError);
610     }
611
612     // If we re-enter cancel() from inside didFailToLoad(), we want to pick up from where we 
613     // left off without redoing any of this work.
614     if (m_cancellationStatus == CalledWillCancel) {
615         m_cancellationStatus = Cancelled;
616
617         if (m_handle)
618             m_handle->clearAuthentication();
619
620         m_documentLoader->cancelPendingSubstituteLoad(this);
621         if (m_handle) {
622             m_handle->cancel();
623             m_handle = nullptr;
624         }
625         cleanupForError(nonNullError);
626     }
627
628     // If cancel() completed from within the call to willCancel() or didFailToLoad(),
629     // we don't want to redo didCancel() or releasesResources().
630     if (m_reachedTerminalState)
631         return;
632
633     didCancel(nonNullError);
634
635     if (m_cancellationStatus == FinishedCancel)
636         return;
637     m_cancellationStatus = FinishedCancel;
638
639     releaseResources();
640 }
641
642 ResourceError ResourceLoader::cancelledError()
643 {
644     return frameLoader()->cancelledError(m_request);
645 }
646
647 ResourceError ResourceLoader::blockedError()
648 {
649     return frameLoader()->client().blockedError(m_request);
650 }
651
652 ResourceError ResourceLoader::blockedByContentBlockerError()
653 {
654     return frameLoader()->client().blockedByContentBlockerError(m_request);
655 }
656
657 ResourceError ResourceLoader::cannotShowURLError()
658 {
659     return frameLoader()->client().cannotShowURLError(m_request);
660 }
661
662 void ResourceLoader::willSendRequestAsync(ResourceHandle* handle, ResourceRequest&& request, ResourceResponse&& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
663 {
664     RefPtr<ResourceHandle> protectedHandle(handle);
665     if (documentLoader()->applicationCacheHost().maybeLoadFallbackForRedirect(this, request, redirectResponse)) {
666         RELEASE_LOG_IF_ALLOWED("willSendRequestAsync: exiting early because maybeLoadFallbackForRedirect returned false (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
667         completionHandler(WTFMove(request));
668         return;
669     }
670     willSendRequestInternal(WTFMove(request), redirectResponse, WTFMove(completionHandler));
671 }
672
673 void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
674 {
675     didSendData(bytesSent, totalBytesToBeSent);
676 }
677
678 void ResourceLoader::didReceiveResponseAsync(ResourceHandle*, ResourceResponse&& response, CompletionHandler<void()>&& completionHandler)
679 {
680     if (documentLoader()->applicationCacheHost().maybeLoadFallbackForResponse(this, response)) {
681         completionHandler();
682         return;
683     }
684     didReceiveResponse(response, WTFMove(completionHandler));
685 }
686
687 void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, unsigned length, int encodedDataLength)
688 {
689     didReceiveData(data, length, encodedDataLength, DataPayloadBytes);
690 }
691
692 void ResourceLoader::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int encodedDataLength)
693 {
694     didReceiveBuffer(WTFMove(buffer), encodedDataLength, DataPayloadBytes);
695 }
696
697 void ResourceLoader::didFinishLoading(ResourceHandle*)
698 {
699     NetworkLoadMetrics emptyMetrics;
700     didFinishLoading(emptyMetrics);
701 }
702
703 void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error)
704 {
705     if (documentLoader()->applicationCacheHost().maybeLoadFallbackForError(this, error))
706         return;
707     didFail(error);
708 }
709
710 void ResourceLoader::wasBlocked(ResourceHandle*)
711 {
712     RELEASE_LOG_IF_ALLOWED("wasBlocked: resource load canceled because of content blocker (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
713     didFail(blockedError());
714 }
715
716 void ResourceLoader::cannotShowURL(ResourceHandle*)
717 {
718     RELEASE_LOG_IF_ALLOWED("wasBlocked: resource load canceled because of invalid URL (frame = %p, frameLoader = %p, resourceID = %lu)", frame(), frameLoader(), identifier());
719     didFail(cannotShowURLError());
720 }
721
722 bool ResourceLoader::shouldUseCredentialStorage()
723 {
724     if (m_options.storedCredentialsPolicy != StoredCredentialsPolicy::Use)
725         return false;
726
727     Ref<ResourceLoader> protectedThis(*this);
728     return frameLoader()->client().shouldUseCredentialStorage(documentLoader(), identifier());
729 }
730
731 bool ResourceLoader::isAllowedToAskUserForCredentials() const
732 {
733     if (m_options.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials)
734         return false;
735     if (!shouldAllowResourceToAskForCredentials())
736         return false;
737     return m_options.credentials == FetchOptions::Credentials::Include || (m_options.credentials == FetchOptions::Credentials::SameOrigin && m_frame->document()->securityOrigin().canRequest(originalRequest().url()));
738 }
739
740 bool ResourceLoader::shouldIncludeCertificateInfo() const
741 {
742     if (m_options.certificateInfoPolicy == CertificateInfoPolicy::IncludeCertificateInfo)
743         return true;
744     if (UNLIKELY(InspectorInstrumentation::hasFrontends()))
745         return true;
746     return false;
747 }
748
749 void ResourceLoader::didReceiveAuthenticationChallenge(ResourceHandle* handle, const AuthenticationChallenge& challenge)
750 {
751     ASSERT_UNUSED(handle, handle == m_handle);
752     ASSERT(m_handle->hasAuthenticationChallenge());
753
754     // Protect this in this delegate method since the additional processing can do
755     // anything including possibly derefing this; one example of this is Radar 3266216.
756     Ref<ResourceLoader> protectedThis(*this);
757
758     if (m_options.storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
759         if (isAllowedToAskUserForCredentials()) {
760             frameLoader()->notifier().didReceiveAuthenticationChallenge(this, challenge);
761             return;
762         }
763         didBlockAuthenticationChallenge();
764     }
765     challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
766     ASSERT(!m_handle || !m_handle->hasAuthenticationChallenge());
767 }
768
769 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
770 void ResourceLoader::canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle*, const ProtectionSpace& protectionSpace, CompletionHandler<void(bool)>&& completionHandler)
771 {
772     completionHandler(canAuthenticateAgainstProtectionSpace(protectionSpace));
773 }
774
775 bool ResourceLoader::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace)
776 {
777     Ref<ResourceLoader> protectedThis(*this);
778     return frameLoader()->client().canAuthenticateAgainstProtectionSpace(documentLoader(), identifier(), protectionSpace);
779 }
780
781 #endif
782     
783 #if PLATFORM(IOS_FAMILY)
784
785 RetainPtr<CFDictionaryRef> ResourceLoader::connectionProperties(ResourceHandle*)
786 {
787     return frameLoader()->connectionProperties(this);
788 }
789
790 #endif
791
792 void ResourceLoader::receivedCancellation(const AuthenticationChallenge&)
793 {
794     cancel();
795 }
796
797 #if PLATFORM(COCOA)
798
799 void ResourceLoader::schedule(SchedulePair& pair)
800 {
801     if (m_handle)
802         m_handle->schedule(pair);
803 }
804
805 void ResourceLoader::unschedule(SchedulePair& pair)
806 {
807     if (m_handle)
808         m_handle->unschedule(pair);
809 }
810
811 #endif
812
813 #if USE(QUICK_LOOK)
814 bool ResourceLoader::isQuickLookResource() const
815 {
816     return !!m_previewLoader;
817 }
818 #endif
819
820 bool ResourceLoader::isAlwaysOnLoggingAllowed() const
821 {
822     return frameLoader() && frameLoader()->isAlwaysOnLoggingAllowed();
823 }
824
825 }