| 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. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
| 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| 15 * its contributors may be used to endorse or promote products derived | 15 * its contributors may be used to endorse or promote products derived |
| 16 * from this software without specific prior written permission. | 16 * from this software without specific prior written permission. |
| 17 * | 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 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 | 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 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 | 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 // Replacing an unreachable URL with alternate content looks like a server-s
ide | 186 // Replacing an unreachable URL with alternate content looks like a server-s
ide |
| 187 // redirect at this point, but we can replace a committed dataSource. | 187 // redirect at this point, but we can replace a committed dataSource. |
| 188 bool handlingUnreachableURL = false; | 188 bool handlingUnreachableURL = false; |
| 189 | 189 |
| 190 handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.fai
lingURL().isEmpty(); | 190 handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.fai
lingURL().isEmpty(); |
| 191 | 191 |
| 192 if (handlingUnreachableURL) | 192 if (handlingUnreachableURL) |
| 193 m_committed = false; | 193 m_committed = false; |
| 194 | 194 |
| 195 // We should never be getting a redirect callback after the data | 195 // We should never be getting a redirect callback after the data |
| 196 // source is committed, except in the unreachable URL case. It | 196 // source is committed, except in the unreachable URL case. It |
| 197 // would be a WebFoundation bug if it sent a redirect callback after commit. | 197 // would be a WebFoundation bug if it sent a redirect callback after commit. |
| 198 ASSERT(!m_committed); | 198 ASSERT(!m_committed); |
| 199 | 199 |
| 200 m_request = req; | 200 m_request = req; |
| 201 } | 201 } |
| 202 | 202 |
| 203 void DocumentLoader::setMainDocumentError(const ResourceError& error) | 203 void DocumentLoader::setMainDocumentError(const ResourceError& error) |
| 204 { | 204 { |
| 205 m_mainDocumentError = error; | 205 m_mainDocumentError = error; |
| 206 } | 206 } |
| 207 | 207 |
| 208 void DocumentLoader::mainReceivedError(const ResourceError& error) | 208 void DocumentLoader::mainReceivedError(const ResourceError& error) |
| 209 { | 209 { |
| 210 ASSERT(!error.isNull()); | 210 ASSERT(!error.isNull()); |
| 211 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); | 211 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); |
| 212 | 212 |
| 213 m_applicationCacheHost->failedLoadingMainResource(); | 213 m_applicationCacheHost->failedLoadingMainResource(); |
| 214 | 214 |
| 215 if (!frameLoader()) | 215 if (!frameLoader()) |
| 216 return; | 216 return; |
| 217 setMainDocumentError(error); | 217 setMainDocumentError(error); |
| 218 clearMainResourceLoader(); | 218 clearMainResourceLoader(); |
| 219 frameLoader()->receivedMainResourceError(error); | 219 frameLoader()->receivedMainResourceError(error); |
| 220 clearMainResourceHandle(); | 220 clearMainResourceHandle(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 // Cancels the data source's pending loads. Conceptually, a data source only lo
ads | 223 // Cancels the data source's pending loads. Conceptually, a data source only lo
ads |
| 224 // one document at a time, but one document may have many related resources. | 224 // one document at a time, but one document may have many related resources. |
| 225 // stopLoading will stop all loads initiated by the data source, | 225 // stopLoading will stop all loads initiated by the data source, |
| 226 // but not loads initiated by child frames' data sources -- that's the WebFrame'
s job. | 226 // but not loads initiated by child frames' data sources -- that's the WebFrame'
s job. |
| 227 void DocumentLoader::stopLoading() | 227 void DocumentLoader::stopLoading() |
| 228 { | 228 { |
| 229 RefPtr<Frame> protectFrame(m_frame); | 229 RefPtr<Frame> protectFrame(m_frame); |
| 230 RefPtr<DocumentLoader> protectLoader(this); | 230 RefPtr<DocumentLoader> protectLoader(this); |
| 231 | 231 |
| 232 // In some rare cases, calling FrameLoader::stopLoading could cause isLoadin
g() to return false. | 232 // In some rare cases, calling FrameLoader::stopLoading could cause isLoadin
g() to return false. |
| 233 // (This can happen when there's a single XMLHttpRequest currently loading a
nd stopLoading causes it | 233 // (This can happen when there's a single XMLHttpRequest currently loading a
nd stopLoading causes it |
| 234 // to stop loading. Because of this, we need to save it so we don't return e
arly. | 234 // to stop loading. Because of this, we need to save it so we don't return e
arly. |
| 235 bool loading = isLoading(); | 235 bool loading = isLoading(); |
| 236 | 236 |
| 237 if (m_committed) { | 237 if (m_committed) { |
| 238 // Attempt to stop the frame if the document loader is loading, or if it
is done loading but | 238 // Attempt to stop the frame if the document loader is loading, or if it
is done loading but |
| 239 // still parsing. Failure to do so can cause a world leak. | 239 // still parsing. Failure to do so can cause a world leak. |
| 240 Document* doc = m_frame->document(); | 240 Document* doc = m_frame->document(); |
| 241 | 241 |
| 242 if (loading || doc->parsing()) | 242 if (loading || doc->parsing()) |
| 243 m_frame->loader()->stopLoading(UnloadEventPolicyNone); | 243 m_frame->loader()->stopLoading(UnloadEventPolicyNone); |
| 244 } | 244 } |
| 245 | 245 |
| 246 // Always cancel multipart loaders | 246 // Always cancel multipart loaders |
| 247 cancelAll(m_multipartResourceLoaders); | 247 cancelAll(m_multipartResourceLoaders); |
| 248 | 248 |
| 249 clearArchiveResources(); | 249 clearArchiveResources(); |
| 250 | 250 |
| 251 if (!loading) { | 251 if (!loading) { |
| 252 // If something above restarted loading we might run into mysterious cra
shes like | 252 // If something above restarted loading we might run into mysterious cra
shes like |
| 253 // https://bugs.webkit.org/show_bug.cgi?id=62764 and <rdar://problem/932
8684> | 253 // https://bugs.webkit.org/show_bug.cgi?id=62764 and <rdar://problem/932
8684> |
| 254 ASSERT(!isLoading()); | 254 ASSERT(!isLoading()); |
| 255 return; | 255 return; |
| 256 } | 256 } |
| 257 | 257 |
| 258 // We might run in to infinite recursion if we're stopping loading as the re
sult of | 258 // We might run in to infinite recursion if we're stopping loading as the re
sult of |
| 259 // detaching from the frame, so break out of that recursion here. | 259 // detaching from the frame, so break out of that recursion here. |
| 260 // See <rdar://problem/9673866> for more details. | 260 // See <rdar://problem/9673866> for more details. |
| 261 if (m_isStopping) | 261 if (m_isStopping) |
| 262 return; | 262 return; |
| 263 | 263 |
| 264 m_isStopping = true; | 264 m_isStopping = true; |
| 265 | 265 |
| 266 if (isLoadingMainResource()) { | 266 if (isLoadingMainResource()) { |
| 267 // Stop the main resource loader and let it send the cancelled message. | 267 // Stop the main resource loader and let it send the cancelled message. |
| 268 cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); | 268 cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); |
| 269 } else if (!m_resourceLoaders.isEmpty()) { | 269 } else if (!m_resourceLoaders.isEmpty()) { |
| 270 // The main resource loader already finished loading. Set the cancelled
error on the | 270 // The main resource loader already finished loading. Set the cancelled
error on the |
| 271 // document and let the resourceLoaders send individual cancelled messag
es below. | 271 // document and let the resourceLoaders send individual cancelled messag
es below. |
| 272 setMainDocumentError(ResourceError::cancelledError(m_request.url())); | 272 setMainDocumentError(ResourceError::cancelledError(m_request.url())); |
| 273 } else { | 273 } else { |
| 274 // If there are no resource loaders, we need to manufacture a cancelled
message. | 274 // If there are no resource loaders, we need to manufacture a cancelled
message. |
| 275 // (A back/forward navigation has no resource loaders because its resour
ces are cached.) | 275 // (A back/forward navigation has no resource loaders because its resour
ces are cached.) |
| 276 mainReceivedError(ResourceError::cancelledError(m_request.url())); | 276 mainReceivedError(ResourceError::cancelledError(m_request.url())); |
| 277 } | 277 } |
| 278 | 278 |
| 279 stopLoadingSubresources(); | 279 stopLoadingSubresources(); |
| 280 | 280 |
| 281 m_isStopping = false; | 281 m_isStopping = false; |
| 282 } | 282 } |
| 283 | 283 |
| 284 void DocumentLoader::commitIfReady() | 284 void DocumentLoader::commitIfReady() |
| 285 { | 285 { |
| 286 if (!m_committed) { | 286 if (!m_committed) { |
| 287 m_committed = true; | 287 m_committed = true; |
| 288 frameLoader()->commitProvisionalLoad(); | 288 frameLoader()->commitProvisionalLoad(); |
| 289 } | 289 } |
| 290 } | 290 } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 void DocumentLoader::redirectReceived(CachedResource* resource, ResourceRequest&
request, const ResourceResponse& redirectResponse) | 438 void DocumentLoader::redirectReceived(CachedResource* resource, ResourceRequest&
request, const ResourceResponse& redirectResponse) |
| 439 { | 439 { |
| 440 ASSERT_UNUSED(resource, resource == m_mainResource); | 440 ASSERT_UNUSED(resource, resource == m_mainResource); |
| 441 willSendRequest(request, redirectResponse); | 441 willSendRequest(request, redirectResponse); |
| 442 } | 442 } |
| 443 | 443 |
| 444 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
Response& redirectResponse) | 444 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
Response& redirectResponse) |
| 445 { | 445 { |
| 446 // Note that there are no asserts here as there are for the other callbacks.
This is due to the | 446 // Note that there are no asserts here as there are for the other callbacks.
This is due to the |
| 447 // fact that this "callback" is sent when starting every load, and the state
of callback | 447 // fact that this "callback" is sent when starting every load, and the state
of callback |
| 448 // deferrals plays less of a part in this function in preventing the bad beh
avior deferring | 448 // deferrals plays less of a part in this function in preventing the bad beh
avior deferring |
| 449 // callbacks is meant to prevent. | 449 // callbacks is meant to prevent. |
| 450 ASSERT(!newRequest.isNull()); | 450 ASSERT(!newRequest.isNull()); |
| 451 | 451 |
| 452 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) { | 452 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) { |
| 453 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url())); | 453 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url())); |
| 454 return; | 454 return; |
| 455 } | 455 } |
| 456 | 456 |
| 457 ASSERT(timing()->fetchStart()); | 457 ASSERT(timing()->fetchStart()); |
| 458 if (!redirectResponse.isNull()) { | 458 if (!redirectResponse.isNull()) { |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 if (doc->hasActiveParser()) | 753 if (doc->hasActiveParser()) |
| 754 return true; | 754 return true; |
| 755 } | 755 } |
| 756 return frameLoader()->subframeIsLoading(); | 756 return frameLoader()->subframeIsLoading(); |
| 757 } | 757 } |
| 758 | 758 |
| 759 void DocumentLoader::createArchive() | 759 void DocumentLoader::createArchive() |
| 760 { | 760 { |
| 761 m_archive = MHTMLArchive::create(m_response.url(), mainResourceData().get())
; | 761 m_archive = MHTMLArchive::create(m_response.url(), mainResourceData().get())
; |
| 762 ASSERT(m_archive); | 762 ASSERT(m_archive); |
| 763 | 763 |
| 764 addAllArchiveResources(m_archive.get()); | 764 addAllArchiveResources(m_archive.get()); |
| 765 ArchiveResource* mainResource = m_archive->mainResource(); | 765 ArchiveResource* mainResource = m_archive->mainResource(); |
| 766 | 766 |
| 767 // The origin is the MHTML file, we need to set the base URL to the document
encoded in the MHTML so | 767 // The origin is the MHTML file, we need to set the base URL to the document
encoded in the MHTML so |
| 768 // relative URLs are resolved properly. | 768 // relative URLs are resolved properly. |
| 769 ensureWriter(mainResource->mimeType(), m_archive->mainResource()->url()); | 769 ensureWriter(mainResource->mimeType(), m_archive->mainResource()->url()); |
| 770 | 770 |
| 771 commitData(mainResource->data()->data(), mainResource->data()->size()); | 771 commitData(mainResource->data()->data(), mainResource->data()->size()); |
| 772 } | 772 } |
| 773 | 773 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 if (m_pageTitle == title) | 829 if (m_pageTitle == title) |
| 830 return; | 830 return; |
| 831 | 831 |
| 832 m_pageTitle = title; | 832 m_pageTitle = title; |
| 833 frameLoader()->didChangeTitle(this); | 833 frameLoader()->didChangeTitle(this); |
| 834 } | 834 } |
| 835 | 835 |
| 836 KURL DocumentLoader::urlForHistory() const | 836 KURL DocumentLoader::urlForHistory() const |
| 837 { | 837 { |
| 838 // Return the URL to be used for history and B/F list. | 838 // Return the URL to be used for history and B/F list. |
| 839 // Returns nil for WebDataProtocol URLs that aren't alternates | 839 // Returns nil for WebDataProtocol URLs that aren't alternates |
| 840 // for unreachable URLs, because these can't be stored in history. | 840 // for unreachable URLs, because these can't be stored in history. |
| 841 if (m_substituteData.isValid()) | 841 if (m_substituteData.isValid()) |
| 842 return unreachableURL(); | 842 return unreachableURL(); |
| 843 | 843 |
| 844 return m_originalRequestCopy.url(); | 844 return m_originalRequestCopy.url(); |
| 845 } | 845 } |
| 846 | 846 |
| 847 const KURL& DocumentLoader::originalURL() const | 847 const KURL& DocumentLoader::originalURL() const |
| 848 { | 848 { |
| 849 return m_originalRequestCopy.url(); | 849 return m_originalRequestCopy.url(); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 | 994 |
| 995 mainReceivedError(error); | 995 mainReceivedError(error); |
| 996 } | 996 } |
| 997 | 997 |
| 998 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loa
der) | 998 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loa
der) |
| 999 { | 999 { |
| 1000 m_multipartResourceLoaders.add(loader); | 1000 m_multipartResourceLoaders.add(loader); |
| 1001 m_resourceLoaders.remove(loader); | 1001 m_resourceLoaders.remove(loader); |
| 1002 checkLoadComplete(); | 1002 checkLoadComplete(); |
| 1003 if (Frame* frame = m_frame) | 1003 if (Frame* frame = m_frame) |
| 1004 frame->loader()->checkLoadComplete(); | 1004 frame->loader()->checkLoadComplete(); |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 void DocumentLoader::handledOnloadEvents() | 1007 void DocumentLoader::handledOnloadEvents() |
| 1008 { | 1008 { |
| 1009 m_wasOnloadHandled = true; | 1009 m_wasOnloadHandled = true; |
| 1010 applicationCacheHost()->stopDeferringEvents(); | 1010 applicationCacheHost()->stopDeferringEvents(); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 DocumentWriter* DocumentLoader::beginWriting(const String& mimeType, const Strin
g& encoding, const KURL& url) | 1013 DocumentWriter* DocumentLoader::beginWriting(const String& mimeType, const Strin
g& encoding, const KURL& url) |
| 1014 { | 1014 { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1070 // This is only called by ScriptController::executeScriptIfJavaScriptURL | 1070 // This is only called by ScriptController::executeScriptIfJavaScriptURL |
| 1071 // and always contains the result of evaluating a javascript: url. | 1071 // and always contains the result of evaluating a javascript: url. |
| 1072 // This is the <iframe src="javascript:'html'"> case. | 1072 // This is the <iframe src="javascript:'html'"> case. |
| 1073 void DocumentLoader::replaceDocument(const String& source, Document* ownerDocume
nt) | 1073 void DocumentLoader::replaceDocument(const String& source, Document* ownerDocume
nt) |
| 1074 { | 1074 { |
| 1075 m_frame->loader()->stopAllLoaders(); | 1075 m_frame->loader()->stopAllLoaders(); |
| 1076 m_writer = createWriterFor(m_frame, ownerDocument, m_frame->document()->url(
), mimeType(), m_writer ? m_writer->encoding() : "", m_writer ? m_writer->encod
ingWasChosenByUser() : false, true); | 1076 m_writer = createWriterFor(m_frame, ownerDocument, m_frame->document()->url(
), mimeType(), m_writer ? m_writer->encoding() : "", m_writer ? m_writer->encod
ingWasChosenByUser() : false, true); |
| 1077 if (!source.isNull()) | 1077 if (!source.isNull()) |
| 1078 m_writer->appendReplacingData(source); | 1078 m_writer->appendReplacingData(source); |
| 1079 endWriting(m_writer.get()); | 1079 endWriting(m_writer.get()); |
| 1080 // FIXME: This does not synchronously flush the parser but should! |
| 1080 } | 1081 } |
| 1081 | 1082 |
| 1082 } // namespace WebCore | 1083 } // namespace WebCore |
| OLD | NEW |