OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 , m_fetcher(FrameFetchContext::createContextAndFetcher(this)) | 88 , m_fetcher(FrameFetchContext::createContextAndFetcher(this)) |
89 , m_originalRequest(req) | 89 , m_originalRequest(req) |
90 , m_substituteData(substituteData) | 90 , m_substituteData(substituteData) |
91 , m_request(req) | 91 , m_request(req) |
92 , m_isClientRedirect(false) | 92 , m_isClientRedirect(false) |
93 , m_replacesCurrentHistoryItem(false) | 93 , m_replacesCurrentHistoryItem(false) |
94 , m_navigationType(NavigationTypeOther) | 94 , m_navigationType(NavigationTypeOther) |
95 , m_documentLoadTiming(*this) | 95 , m_documentLoadTiming(*this) |
96 , m_timeOfLastDataReceived(0.0) | 96 , m_timeOfLastDataReceived(0.0) |
97 , m_applicationCacheHost(ApplicationCacheHost::create(this)) | 97 , m_applicationCacheHost(ApplicationCacheHost::create(this)) |
98 , m_state(Provisional) | 98 , m_state(NotStarted) |
99 , m_inDataReceived(false) | 99 , m_inDataReceived(false) |
100 , m_dataBuffer(SharedBuffer::create()) | 100 , m_dataBuffer(SharedBuffer::create()) |
101 { | 101 { |
102 timing().markNavigationStart(); | |
103 } | 102 } |
104 | 103 |
105 FrameLoader* DocumentLoader::frameLoader() const | 104 FrameLoader* DocumentLoader::frameLoader() const |
106 { | 105 { |
107 if (!m_frame) | 106 if (!m_frame) |
108 return nullptr; | 107 return nullptr; |
109 return &m_frame->loader(); | 108 return &m_frame->loader(); |
110 } | 109 } |
111 | 110 |
112 ResourceLoader* DocumentLoader::mainResourceLoader() const | 111 ResourceLoader* DocumentLoader::mainResourceLoader() const |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 m_state = Committed; | 243 m_state = Committed; |
245 frameLoader()->commitProvisionalLoad(); | 244 frameLoader()->commitProvisionalLoad(); |
246 } | 245 } |
247 } | 246 } |
248 | 247 |
249 bool DocumentLoader::isLoading() const | 248 bool DocumentLoader::isLoading() const |
250 { | 249 { |
251 if (document() && document()->hasActiveParser()) | 250 if (document() && document()->hasActiveParser()) |
252 return true; | 251 return true; |
253 | 252 |
254 return m_state < MainResourceDone || m_fetcher->isFetching(); | 253 return (m_state > NotStarted && m_state < MainResourceDone) || m_fetcher->is
Fetching(); |
255 } | 254 } |
256 | 255 |
257 void DocumentLoader::notifyFinished(Resource* resource) | 256 void DocumentLoader::notifyFinished(Resource* resource) |
258 { | 257 { |
259 ASSERT_UNUSED(resource, m_mainResource == resource); | 258 ASSERT_UNUSED(resource, m_mainResource == resource); |
260 ASSERT(m_mainResource); | 259 ASSERT(m_mainResource); |
261 | 260 |
262 RefPtrWillBeRawPtr<DocumentLoader> protect(this); | 261 RefPtrWillBeRawPtr<DocumentLoader> protect(this); |
263 | 262 |
264 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { | 263 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 if (((status >= 301 && status <= 303) || status == 307) | 305 if (((status >= 301 && status <= 303) || status == 307) |
307 && m_originalRequest.httpMethod() == "POST") | 306 && m_originalRequest.httpMethod() == "POST") |
308 return true; | 307 return true; |
309 | 308 |
310 return false; | 309 return false; |
311 } | 310 } |
312 | 311 |
313 void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& reque
st, const ResourceResponse& redirectResponse) | 312 void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& reque
st, const ResourceResponse& redirectResponse) |
314 { | 313 { |
315 ASSERT_UNUSED(resource, resource == m_mainResource); | 314 ASSERT_UNUSED(resource, resource == m_mainResource); |
| 315 willSendRequest(request, redirectResponse); |
| 316 } |
| 317 |
| 318 void DocumentLoader::updateRequest(Resource* resource, const ResourceRequest& re
quest) |
| 319 { |
| 320 ASSERT_UNUSED(resource, resource == m_mainResource); |
| 321 m_request = request; |
| 322 } |
| 323 |
| 324 static bool isFormSubmission(NavigationType type) |
| 325 { |
| 326 return type == NavigationTypeFormSubmitted || type == NavigationTypeFormResu
bmitted; |
| 327 } |
| 328 |
| 329 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
Response& redirectResponse) |
| 330 { |
| 331 // Note that there are no asserts here as there are for the other callbacks.
This is due to the |
| 332 // fact that this "callback" is sent when starting every load, and the state
of callback |
| 333 // deferrals plays less of a part in this function in preventing the bad beh
avior deferring |
| 334 // callbacks is meant to prevent. |
| 335 ASSERT(!newRequest.isNull()); |
| 336 if (isFormSubmission(m_navigationType) && !m_frame->document()->contentSecur
ityPolicy()->allowFormAction(newRequest.url())) { |
| 337 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url())); |
| 338 return; |
| 339 } |
| 340 |
| 341 ASSERT(timing().fetchStart()); |
| 342 if (!redirectResponse.isNull()) { |
| 343 // If the redirecting url is not allowed to display content from the tar
get origin, |
| 344 // then block the redirect. |
| 345 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redire
ctResponse.url()); |
| 346 if (!redirectingOrigin->canDisplay(newRequest.url())) { |
| 347 FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string(
)); |
| 348 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url(
))); |
| 349 return; |
| 350 } |
| 351 timing().addRedirect(redirectResponse.url(), newRequest.url()); |
| 352 } |
316 | 353 |
317 // If we're fielding a redirect in response to a POST, force a load from ori
gin, since | 354 // If we're fielding a redirect in response to a POST, force a load from ori
gin, since |
318 // this is a common site technique to return to a page viewing some data tha
t the POST | 355 // this is a common site technique to return to a page viewing some data tha
t the POST |
319 // just modified. | 356 // just modified. |
320 if (request.cachePolicy() == UseProtocolCachePolicy && isRedirectAfterPost(r
equest, redirectResponse)) | 357 if (newRequest.cachePolicy() == UseProtocolCachePolicy && isRedirectAfterPos
t(newRequest, redirectResponse)) |
321 request.setCachePolicy(ReloadBypassingCache); | 358 newRequest.setCachePolicy(ReloadBypassingCache); |
322 | 359 |
323 m_request = request; | 360 m_request = newRequest; |
324 | 361 |
325 // Add the fragment to the new request url. Note that this is only done on m
_request, | 362 if (redirectResponse.isNull()) |
326 // not on the request that will be passed back out of blink. The network sta
ck doesn't care | 363 return; |
327 // about the fragment, and doesn't expect the URL to change unless it is inv
alidated. | |
328 KURL url = request.url(); | |
329 if (m_originalRequest.url().hasFragmentIdentifier()) { | |
330 url.setFragmentIdentifier(m_originalRequest.url().fragmentIdentifier()); | |
331 m_request.setURL(url); | |
332 } | |
333 | 364 |
334 // If the redirecting url is not allowed to display content from the target
origin, | 365 appendRedirect(newRequest.url()); |
335 // then block the redirect. | |
336 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redirectRe
sponse.url()); | |
337 if (!redirectingOrigin->canDisplay(url)) { | |
338 FrameLoader::reportLocalLoadFailed(m_frame, url.string()); | |
339 cancelMainResourceLoad(ResourceError::cancelledError(url)); | |
340 return; | |
341 } | |
342 | |
343 timing().addRedirect(redirectResponse.url(), url); | |
344 appendRedirect(url); | |
345 frameLoader()->receivedMainResourceRedirect(m_request.url()); | 366 frameLoader()->receivedMainResourceRedirect(m_request.url()); |
346 if (!frameLoader()->shouldContinueForNavigationPolicy(request, SubstituteDat
a(), this, CheckContentSecurityPolicy, m_navigationType, NavigationPolicyCurrent
Tab, replacesCurrentHistoryItem())) | 367 if (!frameLoader()->shouldContinueForNavigationPolicy(newRequest, Substitute
Data(), this, CheckContentSecurityPolicy, m_navigationType, NavigationPolicyCurr
entTab, replacesCurrentHistoryItem())) |
347 cancelMainResourceLoad(ResourceError::cancelledError(url)); | 368 cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); |
348 } | 369 } |
349 | 370 |
350 static bool canShowMIMEType(const String& mimeType, Page* page) | 371 static bool canShowMIMEType(const String& mimeType, Page* page) |
351 { | 372 { |
352 if (Platform::current()->mimeRegistry()->supportsMIMEType(mimeType) == WebMi
meRegistry::IsSupported) | 373 if (Platform::current()->mimeRegistry()->supportsMIMEType(mimeType) == WebMi
meRegistry::IsSupported) |
353 return true; | 374 return true; |
354 PluginData* pluginData = page->pluginData(); | 375 PluginData* pluginData = page->pluginData(); |
355 return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mim
eType); | 376 return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mim
eType); |
356 } | 377 } |
357 | 378 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 if (m_request.url().isEmpty() && !frameLoader()->stateMachine()->creatingIni
tialEmptyDocument()) | 715 if (m_request.url().isEmpty() && !frameLoader()->stateMachine()->creatingIni
tialEmptyDocument()) |
695 m_request.setURL(blankURL()); | 716 m_request.setURL(blankURL()); |
696 m_response = ResourceResponse(m_request.url(), "text/html", 0, nullAtom, Str
ing()); | 717 m_response = ResourceResponse(m_request.url(), "text/html", 0, nullAtom, Str
ing()); |
697 finishedLoading(monotonicallyIncreasingTime()); | 718 finishedLoading(monotonicallyIncreasingTime()); |
698 return true; | 719 return true; |
699 } | 720 } |
700 | 721 |
701 void DocumentLoader::startLoadingMainResource() | 722 void DocumentLoader::startLoadingMainResource() |
702 { | 723 { |
703 RefPtrWillBeRawPtr<DocumentLoader> protect(this); | 724 RefPtrWillBeRawPtr<DocumentLoader> protect(this); |
704 ASSERT(m_state == Provisional); | 725 m_mainDocumentError = ResourceError(); |
| 726 timing().markNavigationStart(); |
| 727 ASSERT(!m_mainResource); |
| 728 ASSERT(m_state == NotStarted); |
| 729 m_state = Provisional; |
705 | 730 |
706 if (maybeLoadEmpty()) | 731 if (maybeLoadEmpty()) |
707 return; | 732 return; |
708 | 733 |
| 734 ASSERT(timing().navigationStart()); |
709 ASSERT(!timing().fetchStart()); | 735 ASSERT(!timing().fetchStart()); |
710 timing().markFetchStart(); | 736 timing().markFetchStart(); |
| 737 willSendRequest(m_request, ResourceResponse()); |
| 738 |
| 739 // willSendRequest() may lead to our LocalFrame being detached or cancelling
the load via nulling the ResourceRequest. |
| 740 if (!m_frame || m_request.isNull()) |
| 741 return; |
| 742 |
| 743 m_applicationCacheHost->willStartLoadingMainResource(m_request); |
711 prepareSubframeArchiveLoadIfNeeded(); | 744 prepareSubframeArchiveLoadIfNeeded(); |
712 | 745 |
| 746 ResourceRequest request(m_request); |
713 DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions, | 747 DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions, |
714 (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, Ch
eckContentSecurityPolicy, DocumentContext)); | 748 (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, Ch
eckContentSecurityPolicy, DocumentContext)); |
715 FetchRequest fetchRequest(m_request, FetchInitiatorTypeNames::document, main
ResourceLoadOptions); | 749 FetchRequest cachedResourceRequest(request, FetchInitiatorTypeNames::documen
t, mainResourceLoadOptions); |
716 | 750 m_mainResource = RawResource::fetchMainResource(cachedResourceRequest, fetch
er(), m_substituteData); |
717 m_mainResource = RawResource::fetchMainResource(fetchRequest, fetcher(), m_s
ubstituteData); | |
718 if (!m_mainResource) { | 751 if (!m_mainResource) { |
719 m_request = ResourceRequest(); | 752 m_request = ResourceRequest(); |
| 753 // If the load was aborted by clearing m_request, it's possible the Appl
icationCacheHost |
| 754 // is now in a state where starting an empty load will be inconsistent.
Replace it with |
| 755 // a new ApplicationCacheHost. |
| 756 if (m_applicationCacheHost) |
| 757 m_applicationCacheHost->detachFromDocumentLoader(); |
| 758 m_applicationCacheHost = ApplicationCacheHost::create(this); |
720 maybeLoadEmpty(); | 759 maybeLoadEmpty(); |
721 return; | 760 return; |
722 } | 761 } |
723 | |
724 m_mainResource->addClient(this); | 762 m_mainResource->addClient(this); |
725 if (!m_mainResource) | |
726 return; | |
727 | 763 |
728 // A bunch of headers are set when the underlying ResourceLoader is created,
and m_request needs to include those. | 764 // A bunch of headers are set when the underlying ResourceLoader is created,
and m_request needs to include those. |
729 // However, if there was a fragment identifier on m_request, the cache will
have stripped it. m_request should include | 765 if (mainResourceLoader()) |
730 // the fragment identifier, so reset the url. | 766 request = mainResourceLoader()->originalRequest(); |
731 m_request = m_mainResource->resourceRequest(); | 767 // If there was a fragment identifier on m_request, the cache will have stri
pped it. m_request should include |
732 m_request.setURL(m_originalRequest.url()); | 768 // the fragment identifier, so add that back in. |
| 769 if (equalIgnoringFragmentIdentifier(m_request.url(), request.url())) |
| 770 request.setURL(m_request.url()); |
| 771 m_request = request; |
733 } | 772 } |
734 | 773 |
735 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) | 774 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) |
736 { | 775 { |
737 RefPtrWillBeRawPtr<DocumentLoader> protect(this); | 776 RefPtrWillBeRawPtr<DocumentLoader> protect(this); |
738 ResourceError error = resourceError.isNull() ? ResourceError::cancelledError
(m_request.url()) : resourceError; | 777 ResourceError error = resourceError.isNull() ? ResourceError::cancelledError
(m_request.url()) : resourceError; |
739 | 778 |
740 if (mainResourceLoader()) | 779 if (mainResourceLoader()) |
741 mainResourceLoader()->cancel(error); | 780 mainResourceLoader()->cancel(error); |
742 | 781 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 { | 833 { |
795 m_writer = createWriterFor(ownerDocument, init, mimeType(), m_writer ? m_wri
ter->encoding() : emptyAtom, true, ForceSynchronousParsing); | 834 m_writer = createWriterFor(ownerDocument, init, mimeType(), m_writer ? m_wri
ter->encoding() : emptyAtom, true, ForceSynchronousParsing); |
796 if (!source.isNull()) | 835 if (!source.isNull()) |
797 m_writer->appendReplacingData(source); | 836 m_writer->appendReplacingData(source); |
798 endWriting(m_writer.get()); | 837 endWriting(m_writer.get()); |
799 } | 838 } |
800 | 839 |
801 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); | 840 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); |
802 | 841 |
803 } // namespace blink | 842 } // namespace blink |
OLD | NEW |