1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009 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 "FrameLoaderTypes.h" 36 #include "HistoryController.h" 37 #include "PolicyCallback.h" 38 #include "PolicyChecker.h" 39 #include "RedirectScheduler.h" 40 #include "ResourceLoadNotifier.h" 41 #include "ResourceRequest.h" 42 #include "ThreadableLoader.h" 43 #include "Timer.h" 44 #include <wtf/Forward.h> 45 46 namespace WebCore { 47 48 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size 49 class Archive; 50 #endif 51 class AuthenticationChallenge; 52 class CachedFrameBase; 53 class CachedPage; 54 class CachedResource; 55 class DOMWrapperWorld; 56 class Document; 57 class DocumentLoader; 58 class Event; 59 class FormData; 60 class FormState; 61 class Frame; 62 class FrameLoaderClient; 63 class HistoryItem; 64 class HTMLAppletElement; 65 class HTMLFormElement; 66 class HTMLFrameOwnerElement; 67 class IconLoader; 68 class IntSize; 69 class NavigationAction; 70 class RenderPart; 71 class ResourceError; 72 class ResourceLoader; 73 class ResourceResponse; 74 class ScriptSourceCode; 75 class ScriptString; 76 class ScriptValue; 77 class SecurityOrigin; 78 class SerializedScriptValue; 79 class SharedBuffer; 80 class SubstituteData; 81 class TextResourceDecoder; 82 class Widget; 83 84 struct FrameLoadRequest; 85 struct WindowFeatures; 86 87 bool isBackForwardLoadType(FrameLoadType); 88 89 class FrameLoader : public Noncopyable { 90 public: 91 FrameLoader(Frame*, FrameLoaderClient*); 92 ~FrameLoader(); 93 94 void init(); 95 frame()96 Frame* frame() const { return m_frame; } 97 policyChecker()98 PolicyChecker* policyChecker() const { return &m_policyChecker; } history()99 HistoryController* history() const { return &m_history; } notifier()100 ResourceLoadNotifier* notifier() const { return &m_notifer; } 101 102 // FIXME: This is not cool, people. There are too many different functions that all start loads. 103 // We should aim to consolidate these into a smaller set of functions, and try to reuse more of 104 // the logic by extracting common code paths. 105 106 void prepareForLoadStart(); 107 void setupForReplace(); 108 void setupForReplaceByMIMEType(const String& newMIMEType); 109 110 void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*); 111 112 void loadFrameRequest(const FrameLoadRequest&, bool lockHistory, bool lockBackForwardList, // Called by submitForm, calls loadPostRequest and loadURL. 113 PassRefPtr<Event>, PassRefPtr<FormState>, ReferrerPolicy); 114 115 void load(const ResourceRequest&, bool lockHistory); // Called by WebFrame, calls load(ResourceRequest, SubstituteData). 116 void load(const ResourceRequest&, const SubstituteData&, bool lockHistory); // Called both by WebFrame and internally, calls load(DocumentLoader*). 117 void load(const ResourceRequest&, const String& frameName, bool lockHistory); // Called by WebPluginController. 118 119 #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size 120 void loadArchive(PassRefPtr<Archive>); 121 #endif 122 123 static void reportLocalLoadFailed(Frame*, const String& url); 124 125 // Called by createWindow in JSDOMWindowBase.cpp, e.g. to fulfill a modal dialog creation 126 Frame* createWindow(FrameLoader* frameLoaderForFrameLookup, const FrameLoadRequest&, const WindowFeatures&, bool& created); 127 128 unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data); 129 130 bool canHandleRequest(const ResourceRequest&); 131 132 // Also not cool. 133 void stopAllLoaders(DatabasePolicy = DatabasePolicyStop); 134 void stopForUserCancel(bool deferCheckLoadComplete = false); 135 isLoadingMainResource()136 bool isLoadingMainResource() const { return m_isLoadingMainResource; } 137 bool isLoading() const; 138 bool frameHasLoaded() const; 139 140 int numPendingOrLoadingRequests(bool recurse) const; 141 String referrer() const; 142 String outgoingReferrer() const; 143 String outgoingOrigin() const; 144 145 DocumentLoader* activeDocumentLoader() const; documentLoader()146 DocumentLoader* documentLoader() const { return m_documentLoader.get(); } policyDocumentLoader()147 DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); } provisionalDocumentLoader()148 DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); } state()149 FrameState state() const { return m_state; } 150 static double timeOfLastCompletedLoad(); 151 152 bool shouldUseCredentialStorage(ResourceLoader*); 153 const ResourceRequest& originalRequest() const; 154 const ResourceRequest& initialRequest() const; 155 void receivedMainResourceError(const ResourceError&, bool isComplete); 156 void receivedData(const char*, int); 157 158 bool willLoadMediaElementURL(KURL&); 159 160 void handleFallbackContent(); 161 bool isStopping() const; 162 163 void finishedLoading(); 164 165 ResourceError cancelledError(const ResourceRequest&) const; 166 ResourceError fileDoesNotExistError(const ResourceResponse&) const; 167 ResourceError blockedError(const ResourceRequest&) const; 168 ResourceError cannotShowURLError(const ResourceRequest&) const; 169 ResourceError interruptionForPolicyChangeError(const ResourceRequest&); 170 171 bool isHostedByObjectElement() const; 172 bool isLoadingMainFrame() const; 173 bool canShowMIMEType(const String& MIMEType) const; 174 bool representationExistsForURLScheme(const String& URLScheme); 175 String generatedMIMETypeForURLScheme(const String& URLScheme); 176 177 void reload(bool endToEndReload = false); 178 void reloadWithOverrideEncoding(const String& overrideEncoding); 179 180 void didReceiveServerRedirectForProvisionalLoadForFrame(); 181 void finishedLoadingDocument(DocumentLoader*); 182 void committedLoad(DocumentLoader*, const char*, int); 183 bool isReplacing() const; 184 void setReplacing(); 185 void revertToProvisional(DocumentLoader*); 186 void setMainDocumentError(DocumentLoader*, const ResourceError&); 187 void mainReceivedCompleteError(DocumentLoader*, const ResourceError&); 188 bool subframeIsLoading() const; 189 void willChangeTitle(DocumentLoader*); 190 void didChangeTitle(DocumentLoader*); 191 192 FrameLoadType loadType() const; 193 CachePolicy subresourceCachePolicy() const; 194 195 void didFirstLayout(); 196 bool firstLayoutDone() const; 197 198 void didFirstVisuallyNonEmptyLayout(); 199 200 void loadedResourceFromMemoryCache(const CachedResource*); 201 void tellClientAboutPastMemoryCacheLoads(); 202 203 void checkLoadComplete(); 204 void detachFromParent(); 205 void detachViewsAndDocumentLoader(); 206 207 void addExtraFieldsToSubresourceRequest(ResourceRequest&); 208 void addExtraFieldsToMainResourceRequest(ResourceRequest&); 209 210 static void addHTTPOriginIfNeeded(ResourceRequest&, String origin); 211 client()212 FrameLoaderClient* client() const { return m_client; } 213 214 void setDefersLoading(bool); 215 216 void changeLocation(const KURL&, const String& referrer, bool lockHistory = true, bool lockBackForwardList = true, bool userGesture = false, bool refresh = false); 217 void urlSelected(const ResourceRequest&, const String& target, PassRefPtr<Event>, bool lockHistory, bool lockBackForwardList, bool userGesture, ReferrerPolicy); 218 bool requestFrame(HTMLFrameOwnerElement*, const String& url, const AtomicString& frameName); 219 220 void submitForm(const char* action, const String& url, 221 PassRefPtr<FormData>, const String& target, const String& contentType, const String& boundary, 222 bool lockHistory, PassRefPtr<Event>, PassRefPtr<FormState>); 223 224 void stop(); 225 void stopLoading(UnloadEventPolicy, DatabasePolicy = DatabasePolicyStop); 226 bool closeURL(); 227 228 void didExplicitOpen(); 229 230 KURL iconURL(); 231 void commitIconURLToIconDatabase(const KURL&); 232 233 KURL baseURL() const; 234 235 void replaceDocument(const String&); 236 237 void begin(); 238 void begin(const KURL&, bool dispatchWindowObjectAvailable = true, SecurityOrigin* forcedSecurityOrigin = 0); 239 240 void write(const char* string, int length = -1, bool flush = false); 241 void write(const String&); 242 void end(); 243 void endIfNotLoadingMainResource(); 244 245 void setEncoding(const String& encoding, bool userChosen); 246 String encoding() const; 247 248 void tokenizerProcessedData(); 249 250 void handledOnloadEvents(); 251 String userAgent(const KURL&) const; 252 253 PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const HashMap<String, String>& args); 254 255 void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); 256 void dispatchDidClearWindowObjectsInAllWorlds(); 257 void dispatchDocumentElementAvailable(); 258 ownerElementSandboxFlagsChanged()259 void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); } 260 isSandboxed(SandboxFlags mask)261 bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } sandboxFlags()262 SandboxFlags sandboxFlags() const { return m_sandboxFlags; } 263 264 // Mixed content related functions. 265 static bool isMixedContent(SecurityOrigin* context, const KURL&); 266 void checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&); 267 void checkIfRunInsecureContent(SecurityOrigin* context, const KURL&); 268 269 Frame* opener(); 270 void setOpener(Frame*); 271 272 bool isProcessingUserGesture(); 273 274 void resetMultipleFormSubmissionProtection(); 275 276 void addData(const char* bytes, int length); 277 278 void checkCallImplicitClose(); 279 280 void frameDetached(); 281 url()282 const KURL& url() const { return m_URL; } 283 284 void setResponseMIMEType(const String&); 285 const String& responseMIMEType() const; 286 287 bool containsPlugins() const; 288 289 void loadDone(); 290 void finishedParsing(); 291 void checkCompleted(); 292 293 void checkDidPerformFirstNavigation(); 294 295 bool isComplete() const; 296 297 bool requestObject(RenderPart* frame, const String& url, const AtomicString& frameName, 298 const String& serviceType, const Vector<String>& paramNames, const Vector<String>& paramValues); 299 300 KURL completeURL(const String& url); 301 302 void cancelAndClear(); 303 304 void setTitle(const String&); 305 306 void commitProvisionalLoad(PassRefPtr<CachedPage>); isLoadingFromCachedPage()307 bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; } 308 committingFirstRealLoad()309 bool committingFirstRealLoad() const { return !m_creatingInitialEmptyDocument && !m_committedFirstRealDocumentLoad; } committedFirstRealDocumentLoad()310 bool committedFirstRealDocumentLoad() const { return m_committedFirstRealDocumentLoad; } creatingInitialEmptyDocument()311 bool creatingInitialEmptyDocument() const { return m_creatingInitialEmptyDocument; } 312 313 void iconLoadDecisionAvailable(); 314 315 bool shouldAllowNavigation(Frame* targetFrame) const; 316 Frame* findFrameForNavigation(const AtomicString& name); 317 318 void startIconLoader(); 319 320 void applyUserAgent(ResourceRequest& request); 321 322 bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&); 323 324 void open(CachedFrameBase&); 325 326 // FIXME: Should these really be public? 327 void completed(); 328 bool allAncestorsAreComplete() const; // including this 329 bool allChildrenAreComplete() const; // immediate children, not all descendants 330 void clientRedirected(const KURL&, double delay, double fireDate, bool lockBackForwardList); 331 void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress); 332 void loadItem(HistoryItem*, FrameLoadType); 333 334 // FIXME: This is public because this asynchronous callback from the FrameLoaderClient 335 // uses the policy machinery (and therefore is called via the PolicyChecker). Once we 336 // introduce a proper callback type for this function, we should make it private again. 337 void continueLoadAfterWillSubmitForm(); 338 suppressOpenerInNewFrame()339 bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; } 340 341 static ObjectContentType defaultObjectContentType(const KURL& url, const String& mimeType); 342 343 private: 344 bool canCachePageContainingThisFrame(); 345 #ifndef NDEBUG 346 void logCanCachePageDecision(); 347 bool logCanCacheFrameDecision(int indentLevel); 348 #endif 349 350 void checkTimerFired(Timer<FrameLoader>*); 351 352 void started(); 353 354 bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback); 355 bool loadPlugin(RenderPart*, const KURL&, const String& mimeType, 356 const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback); 357 358 void navigateWithinDocument(HistoryItem*); 359 void navigateToDifferentDocument(HistoryItem*, FrameLoadType); 360 361 bool loadProvisionalItemFromCachedPage(); 362 void cachePageForHistoryItem(HistoryItem*); 363 void pageHidden(); 364 365 void receivedFirstData(); 366 367 void updateFirstPartyForCookies(); 368 void setFirstPartyForCookies(const KURL&); 369 370 void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType loadType, bool isMainResource, bool cookiePolicyURLFromRequest); 371 372 // Also not cool. 373 void stopLoadingSubframes(); 374 375 void clearProvisionalLoad(); 376 void markLoadComplete(); 377 void transitionToCommitted(PassRefPtr<CachedPage>); 378 void frameLoadCompleted(); 379 380 void mainReceivedError(const ResourceError&, bool isComplete); 381 382 void setLoadType(FrameLoadType); 383 384 static void callContinueLoadAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 385 static void callContinueLoadAfterNewWindowPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, bool shouldContinue); 386 static void callContinueFragmentScrollAfterNavigationPolicy(void*, const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 387 388 void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue); 389 void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, bool shouldContinue); 390 void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue); 391 392 bool shouldScrollToAnchor(bool isFormSubmission, FrameLoadType, const KURL&); 393 394 void checkLoadCompleteForThisFrame(); 395 396 void setDocumentLoader(DocumentLoader*); 397 void setPolicyDocumentLoader(DocumentLoader*); 398 void setProvisionalDocumentLoader(DocumentLoader*); 399 400 void setState(FrameState); 401 402 void closeOldDataSources(); 403 void open(CachedPage&); 404 405 void updateHistoryAfterClientRedirect(); 406 407 void clear(bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true); 408 409 bool shouldReloadToHandleUnreachableURL(DocumentLoader*); 410 411 void dispatchDidCommitLoad(); 412 413 void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); // Calls continueLoadAfterNavigationPolicy 414 void load(DocumentLoader*); // Calls loadWithDocumentLoader 415 416 void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, // Calls loadWithDocumentLoader 417 bool lockHistory, FrameLoadType, PassRefPtr<FormState>); 418 419 #ifdef ANDROID_USER_GESTURE 420 void loadPostRequest(const ResourceRequest&, const String& referrer, // Called by loadFrameRequest, calls loadWithNavigationAction 421 const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, bool); 422 void loadURL(const KURL&, const String& referrer, const String& frameName, // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate 423 bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, bool); 424 #else 425 void loadPostRequest(const ResourceRequest&, const String& referrer, // Called by loadFrameRequest, calls loadWithNavigationAction 426 const String& frameName, bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>); 427 void loadURL(const KURL&, const String& referrer, const String& frameName, // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate 428 bool lockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>); 429 #endif 430 431 bool shouldReload(const KURL& currentURL, const KURL& destinationURL); 432 433 void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&); 434 435 void recursiveCheckLoadComplete(); 436 437 void detachChildren(); 438 void closeAndRemoveChild(Frame*); 439 440 Frame* loadSubframe(HTMLFrameOwnerElement*, const KURL&, const String& name, const String& referrer); 441 442 void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation); 443 444 void provisionalLoadStarted(); 445 446 bool canCachePage(); 447 448 bool didOpenURL(const KURL&); 449 450 void scheduleCheckCompleted(); 451 void scheduleCheckLoadComplete(); 452 void startCheckCompleteTimer(); 453 454 KURL originalRequestURL() const; 455 456 bool shouldTreatURLAsSameAsCurrent(const KURL&) const; 457 458 void updateSandboxFlags(); 459 // FIXME: isDocumentSandboxed should eventually replace isSandboxed. 460 bool isDocumentSandboxed(SandboxFlags) const; 461 462 Frame* m_frame; 463 FrameLoaderClient* m_client; 464 465 mutable PolicyChecker m_policyChecker; 466 mutable HistoryController m_history; 467 mutable ResourceLoadNotifier m_notifer; 468 469 FrameState m_state; 470 FrameLoadType m_loadType; 471 472 // Document loaders for the three phases of frame loading. Note that while 473 // a new request is being loaded, the old document loader may still be referenced. 474 // E.g. while a new request is in the "policy" state, the old document loader may 475 // be consulted in particular as it makes sense to imply certain settings on the new loader. 476 RefPtr<DocumentLoader> m_documentLoader; 477 RefPtr<DocumentLoader> m_provisionalDocumentLoader; 478 RefPtr<DocumentLoader> m_policyDocumentLoader; 479 480 bool m_delegateIsHandlingProvisionalLoadError; 481 482 bool m_firstLayoutDone; 483 bool m_quickRedirectComing; 484 bool m_sentRedirectNotification; 485 bool m_inStopAllLoaders; 486 487 String m_outgoingReferrer; 488 489 bool m_isExecutingJavaScriptFormAction; 490 491 String m_responseMIMEType; 492 493 bool m_didCallImplicitClose; 494 bool m_wasUnloadEventEmitted; 495 bool m_unloadEventBeingDispatched; 496 bool m_isComplete; 497 bool m_isLoadingMainResource; 498 499 RefPtr<SerializedScriptValue> m_pendingStateObject; 500 501 KURL m_URL; 502 KURL m_workingURL; 503 504 OwnPtr<IconLoader> m_iconLoader; 505 bool m_mayLoadIconLater; 506 507 bool m_cancellingWithLoadInProgress; 508 509 bool m_needsClear; 510 bool m_receivedData; 511 512 bool m_encodingWasChosenByUser; 513 String m_encoding; 514 RefPtr<TextResourceDecoder> m_decoder; 515 516 bool m_containsPlugIns; 517 518 KURL m_submittedFormURL; 519 520 Timer<FrameLoader> m_checkTimer; 521 bool m_shouldCallCheckCompleted; 522 bool m_shouldCallCheckLoadComplete; 523 524 Frame* m_opener; 525 HashSet<Frame*> m_openedFrames; 526 527 bool m_creatingInitialEmptyDocument; 528 bool m_isDisplayingInitialEmptyDocument; 529 bool m_committedFirstRealDocumentLoad; 530 531 bool m_didPerformFirstNavigation; 532 bool m_loadingFromCachedPage; 533 bool m_suppressOpenerInNewFrame; 534 535 SandboxFlags m_sandboxFlags; 536 537 #ifndef NDEBUG 538 bool m_didDispatchDidCommitLoad; 539 #endif 540 }; 541 542 } // namespace WebCore 543 544 #endif // FrameLoader_h 545