1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 4 * Copyright (C) Research In Motion Limited 2009. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef FrameLoader_h 32 #define FrameLoader_h 33 34 #include "CachePolicy.h" 35 #include "FrameLoaderStateMachine.h" 36 #include "FrameLoaderTypes.h" 37 #include "HistoryController.h" 38 #include "IconDatabaseBase.h" 39 #include "PolicyChecker.h" 40 #include "ResourceLoadNotifier.h" 41 #include "ScriptValue.h" 42 #include "SubframeLoader.h" 43 #include "ThreadableLoader.h" 44 #include "Timer.h" 45 #include <wtf/Forward.h> 46 #include <wtf/HashSet.h> 47 48 namespace WebCore { 49 50 class Archive; 51 class AuthenticationChallenge; 52 class CachedFrameBase; 53 class CachedPage; 54 class CachedResource; 55 class Chrome; 56 class DOMWrapperWorld; 57 class Document; 58 class DocumentLoader; 59 class Event; 60 class FormData; 61 class FormState; 62 class FormSubmission; 63 class Frame; 64 class FrameLoaderClient; 65 class FrameNetworkingContext; 66 class HistoryItem; 67 class HTMLFormElement; 68 class IconLoader; 69 class NavigationAction; 70 class NetworkingContext; 71 class Page; 72 class ProtectionSpace; 73 class ResourceError; 74 class ResourceLoader; 75 class ResourceRequest; 76 class ResourceResponse; 77 class ScriptSourceCode; 78 class ScriptValue; 79 class SecurityOrigin; 80 class SerializedScriptValue; 81 class SharedBuffer; 82 class StringWithDirection; 83 class SubstituteData; 84 class TextResourceDecoder; 85 86 struct FrameLoadRequest; 87 struct WindowFeatures; 88 89 bool isBackForwardLoadType(FrameLoadType); 90 91 class FrameLoader { 92 WTF_MAKE_NONCOPYABLE(FrameLoader); 93 public: 94 FrameLoader(Frame*, FrameLoaderClient*); 95 ~FrameLoader(); 96 97 void init(); 98 99 Frame* frame() const { return m_frame; } 100 101 PolicyChecker* policyChecker() const { return &m_policyChecker; } 102 HistoryController* history() const { return &m_history; } 103 ResourceLoadNotifier* notifier() const { return &m_notifer; } 104 SubframeLoader* subframeLoader() const { return &m_subframeLoader; } 105 106 // FIXME: This is not cool, people. There are too many different functions that all start loads. 107 // We should aim to consolidate these into a smaller set of functions, and try to reuse more of 108 // the logic by extracting common code paths. 109 110 void prepareForLoadStart(); 111 void setupForReplace(); 112 void setupForReplaceByMIMEType(const String& newMIMEType); 113 114 void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*); 115 116 void loadFrameRequest(const FrameLoadRequest&, bool lockHistory, bool lockBackForwardList, // Called by submitForm, calls loadPostRequest and loadURL. 117 PassRefPtr<Event>, PassRefPtr<FormState>, ReferrerPolicy); 118 119 void load(const ResourceRequest&, bool lockHistory); // Called by WebFrame, calls load(ResourceRequest, SubstituteData). 120 void load(const ResourceRequest&, const SubstituteData&, bool lockHistory); // Called both by WebFrame and internally, calls load(DocumentLoader*). 121 void load(const ResourceRequest&, const String& frameName, bool lockHistory); // Called by WebPluginController. 122 123 #if ENABLE(WEB_ARCHIVE) 124 void loadArchive(PassRefPtr<Archive>); 125 #endif 126 127 static void reportLocalLoadFailed(Frame*, const String& url); 128 129 unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data); 130 131 bool canHandleRequest(const ResourceRequest&); 132 133 // Also not cool. 134 void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem); 135 void stopForUserCancel(bool deferCheckLoadComplete = false); 136 137 bool isLoadingMainResource() const { return m_isLoadingMainResource; } 138 bool isLoading() const; 139 bool frameHasLoaded() const; 140 void transferLoadingResourcesFromPage(Page*); 141 void dispatchTransferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*); 142 143 int numPendingOrLoadingRequests(bool recurse) const; 144 String referrer() const; 145 String outgoingReferrer() const; 146 String outgoingOrigin() const; 147 148 DocumentLoader* activeDocumentLoader() const; 149 DocumentLoader* documentLoader() const { return m_documentLoader.get(); } 150 DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); } 151 DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); } 152 FrameState state() const { return m_state; } 153 static double timeOfLastCompletedLoad(); 154 155 bool shouldUseCredentialStorage(ResourceLoader*); 156 #if USE(PROTECTION_SPACE_AUTH_CALLBACK) 157 bool canAuthenticateAgainstProtectionSpace(ResourceLoader* loader, const ProtectionSpace& protectionSpace); 158 #endif 159 const ResourceRequest& originalRequest() const; 160 const ResourceRequest& initialRequest() const; 161 void receivedMainResourceError(const ResourceError&, bool isComplete); 162 163 bool willLoadMediaElementURL(KURL&); 164 165 void handleFallbackContent(); 166 bool isStopping() const; 167 168 void finishedLoading(); 169 170 ResourceError cancelledError(const ResourceRequest&) const; 171 ResourceError fileDoesNotExistError(const ResourceResponse&) const; 172 ResourceError blockedError(const ResourceRequest&) const; 173 ResourceError cannotShowURLError(const ResourceRequest&) const; 174 ResourceError interruptionForPolicyChangeError(const ResourceRequest&) const; 175 176 bool isHostedByObjectElement() const; 177 bool isLoadingMainFrame() const; 178 bool canShowMIMEType(const String& MIMEType) const; 179 bool representationExistsForURLScheme(const String& URLScheme); 180 String generatedMIMETypeForURLScheme(const String& URLScheme); 181 182 void reload(bool endToEndReload = false); 183 void reloadWithOverrideEncoding(const String& overrideEncoding); 184 185 void didReceiveServerRedirectForProvisionalLoadForFrame(); 186 void finishedLoadingDocument(DocumentLoader*); 187 bool isReplacing() const; 188 void setReplacing(); 189 void revertToProvisional(DocumentLoader*); 190 void setMainDocumentError(DocumentLoader*, const ResourceError&); 191 void mainReceivedCompleteError(DocumentLoader*, const ResourceError&); 192 bool subframeIsLoading() const; 193 void willChangeTitle(DocumentLoader*); 194 void didChangeTitle(DocumentLoader*); 195 void didChangeIcons(DocumentLoader*); 196 197 FrameLoadType loadType() const; 198 199 CachePolicy subresourceCachePolicy() const; 200 201 void didFirstLayout(); 202 203 void didFirstVisuallyNonEmptyLayout(); 204 205 void loadedResourceFromMemoryCache(const CachedResource*); 206 void tellClientAboutPastMemoryCacheLoads(); 207 208 void checkLoadComplete(); 209 void detachFromParent(); 210 void detachViewsAndDocumentLoader(); 211 212 void addExtraFieldsToSubresourceRequest(ResourceRequest&); 213 void addExtraFieldsToMainResourceRequest(ResourceRequest&); 214 215 static void addHTTPOriginIfNeeded(ResourceRequest&, String origin); 216 217 FrameLoaderClient* client() const { return m_client; } 218 219 void setDefersLoading(bool); 220 221 void changeLocation(PassRefPtr<SecurityOrigin>, const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool refresh = false); 222 void urlSelected(const KURL&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy); 223 224 void submitForm(PassRefPtr<FormSubmission>); 225 226 void stop(); 227 void stopLoading(UnloadEventPolicy); 228 bool closeURL(); 229 230 void didExplicitOpen(); 231 232 // Callbacks from DocumentWriter 233 void didBeginDocument(bool dispatchWindowObjectAvailable); 234 void didEndDocument(); 235 void willSetEncoding(); 236 237 KURL iconURL(); 238 void commitIconURLToIconDatabase(const KURL&); 239 240 KURL baseURL() const; 241 242 void handledOnloadEvents(); 243 String userAgent(const KURL&) const; 244 245 void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); 246 void dispatchDidClearWindowObjectsInAllWorlds(); 247 void dispatchDocumentElementAvailable(); 248 249 void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); } 250 251 bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } 252 SandboxFlags sandboxFlags() const { return m_sandboxFlags; } 253 // The following sandbox flags will be forced, regardless of changes to 254 // the sandbox attribute of any parent frames. 255 void setForcedSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags = flags; m_sandboxFlags |= flags; } 256 257 // Mixed content related functions. 258 static bool isMixedContent(SecurityOrigin* context, const KURL&); 259 void checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&); 260 void checkIfRunInsecureContent(SecurityOrigin* context, const KURL&); 261 262 Frame* opener(); 263 void setOpener(Frame*); 264 265 bool isProcessingUserGesture(); 266 267 void resetMultipleFormSubmissionProtection(); 268 269 void checkCallImplicitClose(); 270 271 void frameDetached(); 272 273 void setOutgoingReferrer(const KURL&); 274 275 void loadDone(); 276 void finishedParsing(); 277 void checkCompleted(); 278 279 void checkDidPerformFirstNavigation(); 280 281 bool isComplete() const; 282 283 KURL completeURL(const String& url); 284 285 void cancelAndClear(); 286 287 void setTitle(const StringWithDirection&); 288 void setIconURL(const String&); 289 290 void commitProvisionalLoad(); 291 bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; } 292 293 FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; } 294 295 void startIconLoader(); 296 void iconLoadDecisionReceived(IconLoadDecision); 297 void continueIconLoadWithDecision(IconLoadDecision); 298 299 bool shouldAllowNavigation(Frame* targetFrame) const; 300 Frame* findFrameForNavigation(const AtomicString& name); 301 302 void applyUserAgent(ResourceRequest& request); 303 304 bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&); 305 306 void open(CachedFrameBase&); 307 308 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 309 void hideMediaPlayerProxyPlugin(Widget*); 310 void showMediaPlayerProxyPlugin(Widget*); 311 #endif 312 313 // FIXME: Should these really be public? 314 void completed(); 315 bool allAncestorsAreComplete() const; // including this 316 bool allChildrenAreComplete() const; // immediate children, not all descendants 317 void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList); 318 void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress); 319 void loadItem(HistoryItem*, FrameLoadType); 320 321 // FIXME: This is public because this asynchronous callback from the FrameLoaderClient 322 // uses the policy machinery (and therefore is called via the PolicyChecker). Once we 323 // introduce a proper callback type for this function, we should make it private again. 324 void continueLoadAfterWillSubmitForm(); 325 326 bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; } 327 328 static ObjectContentType defaultObjectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages); 329 330 void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true); 331 332 bool quickRedirectComing() const { return m_quickRedirectComing; } 333 334 bool shouldClose(); 335 336 void started(); 337 338 bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; } 339 340 NetworkingContext* networkingContext() const; 341 342 private: 343 void checkTimerFired(Timer<FrameLoader>*); 344 345 void loadSameDocumentItem(HistoryItem*); 346 void loadDifferentDocumentItem(HistoryItem*, FrameLoadType); 347 348 void loadProvisionalItemFromCachedPage(); 349 350 void receivedFirstData(); 351 352 void updateFirstPartyForCookies(); 353 void setFirstPartyForCookies(const KURL&); 354 355 void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType loadType, bool isMainResource, bool cookiePolicyURLFromRequest); 356 357 // Also not cool. 358 void stopLoadingSubframes(ClearProvisionalItemPolicy); 359 360 void clearProvisionalLoad(); 361 void markLoadComplete(); 362 void transitionToCommitted(PassRefPtr<CachedPage>); 363 void frameLoadCompleted(); 364 365 void mainReceivedError(const ResourceError&, bool isComplete); 366 367 static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 368 static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue); 369 static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 370 371 bool fireBeforeUnloadEvent(Chrome*); 372 373 void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 374 void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue); 375 void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue); 376 377 bool shouldScrollToAnchor(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&); 378 379 void checkLoadCompleteForThisFrame(); 380 381 void setDocumentLoader(DocumentLoader*); 382 void setPolicyDocumentLoader(DocumentLoader*); 383 void setProvisionalDocumentLoader(DocumentLoader*); 384 385 void setState(FrameState); 386 387 void closeOldDataSources(); 388 void prepareForCachedPageRestore(); 389 390 bool shouldReloadToHandleUnreachableURL(DocumentLoader*); 391 392 void dispatchDidCommitLoad(); 393 394 void urlSelected(const FrameLoadRequest&, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, ReferrerPolicy, ShouldReplaceDocumentIfJavaScriptURL); 395 396 void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy 397 void load(DocumentLoader*); // Calls loadWithDocumentLoader 398 399 void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, // Calls loadWithDocumentLoader 400 bool lockHistory, FrameLoadType, PassRefPtr<FormState>); 401 402 void loadPostRequest(const ResourceRequest&, const String& referrer, // Called by loadFrameRequest, calls loadWithNavigationAction 403 const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>); 404 void loadURL(const KURL&, const String& referrer, const String& frameName, // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate 405 bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>); 406 407 bool shouldReload(const KURL& currentURL, const KURL& destinationURL); 408 409 void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&); 410 411 void recursiveCheckLoadComplete(); 412 413 void detachChildren(); 414 void closeAndRemoveChild(Frame*); 415 416 void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation); 417 418 void provisionalLoadStarted(); 419 420 bool didOpenURL(const KURL&); 421 422 void scheduleCheckCompleted(); 423 void scheduleCheckLoadComplete(); 424 void startCheckCompleteTimer(); 425 426 KURL originalRequestURL() const; 427 428 bool shouldTreatURLAsSameAsCurrent(const KURL&) const; 429 430 void updateSandboxFlags(); 431 432 Frame* m_frame; 433 FrameLoaderClient* m_client; 434 435 mutable PolicyChecker m_policyChecker; 436 mutable HistoryController m_history; 437 mutable ResourceLoadNotifier m_notifer; 438 mutable SubframeLoader m_subframeLoader; 439 mutable FrameLoaderStateMachine m_stateMachine; 440 441 FrameState m_state; 442 FrameLoadType m_loadType; 443 444 // Document loaders for the three phases of frame loading. Note that while 445 // a new request is being loaded, the old document loader may still be referenced. 446 // E.g. while a new request is in the "policy" state, the old document loader may 447 // be consulted in particular as it makes sense to imply certain settings on the new loader. 448 RefPtr<DocumentLoader> m_documentLoader; 449 RefPtr<DocumentLoader> m_provisionalDocumentLoader; 450 RefPtr<DocumentLoader> m_policyDocumentLoader; 451 452 bool m_delegateIsHandlingProvisionalLoadError; 453 454 bool m_quickRedirectComing; 455 bool m_sentRedirectNotification; 456 bool m_inStopAllLoaders; 457 458 String m_outgoingReferrer; 459 460 bool m_isExecutingJavaScriptFormAction; 461 462 bool m_didCallImplicitClose; 463 bool m_wasUnloadEventEmitted; 464 bool m_pageDismissalEventBeingDispatched; 465 bool m_isComplete; 466 bool m_isLoadingMainResource; 467 468 RefPtr<SerializedScriptValue> m_pendingStateObject; 469 470 KURL m_workingURL; 471 472 OwnPtr<IconLoader> m_iconLoader; 473 bool m_mayLoadIconLater; 474 475 bool m_needsClear; 476 477 KURL m_submittedFormURL; 478 479 Timer<FrameLoader> m_checkTimer; 480 bool m_shouldCallCheckCompleted; 481 bool m_shouldCallCheckLoadComplete; 482 483 Frame* m_opener; 484 HashSet<Frame*> m_openedFrames; 485 486 bool m_didPerformFirstNavigation; 487 bool m_loadingFromCachedPage; 488 bool m_suppressOpenerInNewFrame; 489 490 SandboxFlags m_sandboxFlags; 491 SandboxFlags m_forcedSandboxFlags; 492 493 RefPtr<FrameNetworkingContext> m_networkingContext; 494 495 KURL m_previousUrl; 496 }; 497 498 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for 499 // modal dialog creation. The lookupFrame is for looking up the frame name in case 500 // the frame name references a frame different from the openerFrame, e.g. when it is 501 // "_self" or "_parent". 502 // 503 // FIXME: Consider making this function part of an appropriate class (not FrameLoader) 504 // and moving it to a more appropriate location. 505 Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created); 506 507 } // namespace WebCore 508 509 #endif // FrameLoader_h 510