diff options
Diffstat (limited to 'WebCore/loader')
-rw-r--r-- | WebCore/loader/DocumentLoadTiming.h | 2 | ||||
-rw-r--r-- | WebCore/loader/EmptyClients.h | 4 | ||||
-rw-r--r-- | WebCore/loader/FTPDirectoryParser.cpp | 6 | ||||
-rw-r--r-- | WebCore/loader/FrameLoader.cpp | 20 | ||||
-rw-r--r-- | WebCore/loader/HistoryController.cpp | 26 | ||||
-rw-r--r-- | WebCore/loader/HistoryController.h | 2 | ||||
-rw-r--r-- | WebCore/loader/NavigationScheduler.h | 6 | ||||
-rw-r--r-- | WebCore/loader/ResourceLoadScheduler.cpp | 5 | ||||
-rw-r--r-- | WebCore/loader/cache/CachePolicy.h | 2 | ||||
-rw-r--r-- | WebCore/loader/cache/CachedImage.cpp | 4 | ||||
-rw-r--r-- | WebCore/loader/cache/CachedImage.h | 5 | ||||
-rw-r--r-- | WebCore/loader/cache/CachedResource.cpp | 7 | ||||
-rw-r--r-- | WebCore/loader/cache/CachedResource.h | 3 | ||||
-rw-r--r-- | WebCore/loader/cache/CachedResourceLoader.cpp | 5 | ||||
-rw-r--r-- | WebCore/loader/cache/MemoryCache.cpp | 26 | ||||
-rw-r--r-- | WebCore/loader/cache/MemoryCache.h | 2 | ||||
-rw-r--r-- | WebCore/loader/loader.cpp | 5 |
17 files changed, 79 insertions, 51 deletions
diff --git a/WebCore/loader/DocumentLoadTiming.h b/WebCore/loader/DocumentLoadTiming.h index 2d4b0fa..368004b 100644 --- a/WebCore/loader/DocumentLoadTiming.h +++ b/WebCore/loader/DocumentLoadTiming.h @@ -31,6 +31,7 @@ namespace WebCore { struct DocumentLoadTiming { DocumentLoadTiming() : navigationStart(0.0) + , unloadEventStart(0.0) , unloadEventEnd(0.0) , redirectStart(0.0) , redirectEnd(0.0) @@ -43,6 +44,7 @@ struct DocumentLoadTiming { } double navigationStart; + double unloadEventStart; double unloadEventEnd; double redirectStart; double redirectEnd; diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h index 3a5e0e9..19dbf35 100644 --- a/WebCore/loader/EmptyClients.h +++ b/WebCore/loader/EmptyClients.h @@ -488,7 +488,7 @@ public: virtual void checkTextOfParagraph(const UChar*, int, uint64_t, Vector<TextCheckingResult>&) { }; #endif #if SUPPORT_AUTOCORRECTION_PANEL - virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect&, const String&, const String&, Editor*) { } + virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect&, const String&, const String&, const Vector<String>&, Editor*) { } virtual void dismissCorrectionPanel(CorrectionWasRejectedOrNot) { } virtual bool isShowingCorrectionPanel() { return false; } #endif @@ -496,7 +496,7 @@ public: virtual void updateSpellingUIWithMisspelledWord(const String&) { } virtual void showSpellingUI(bool) { } virtual bool spellingUIIsShowing() { return false; } - virtual void getGuessesForWord(const String&, Vector<String>&) { } + virtual void getGuessesForWord(const String&, const String&, Vector<String>&) { } virtual void willSetInputMethodState() { } virtual void setInputMethodState(bool) { } diff --git a/WebCore/loader/FTPDirectoryParser.cpp b/WebCore/loader/FTPDirectoryParser.cpp index f6a74de..6a05c4c 100644 --- a/WebCore/loader/FTPDirectoryParser.cpp +++ b/WebCore/loader/FTPDirectoryParser.cpp @@ -117,7 +117,7 @@ FTPEntryType parseOneFTPLine(const char* line, ListState& state, ListResult& res { static const char *month_names = "JanFebMarAprMayJunJulAugSepOctNovDec"; const char *tokens[16]; /* 16 is more than enough */ - unsigned int toklen[(sizeof(tokens)/sizeof(tokens[0]))]; + unsigned int toklen[WTF_ARRAY_LENGTH(tokens)]; unsigned int linelen_sans_wsp; // line length sans whitespace unsigned int numtoks = 0; unsigned int tokmarker = 0; /* extra info for lstyle handler */ @@ -133,7 +133,7 @@ FTPEntryType parseOneFTPLine(const char* line, ListState& state, ListResult& res } unsigned int pos = 0; - while (pos < linelen && numtoks < (sizeof(tokens)/sizeof(tokens[0])) ) + while (pos < linelen && numtoks < WTF_ARRAY_LENGTH(tokens)) { while (pos < linelen && (line[pos] == ' ' || line[pos] == '\t' || line[pos] == '\r')) @@ -156,7 +156,7 @@ FTPEntryType parseOneFTPLine(const char* line, ListState& state, ListResult& res return ParsingFailed(state); linelen_sans_wsp = &(tokens[numtoks-1][toklen[numtoks-1]]) - tokens[0]; - if (numtoks == (sizeof(tokens)/sizeof(tokens[0])) ) + if (numtoks == WTF_ARRAY_LENGTH(tokens)) { pos = linelen; while (pos > 0 && (line[pos-1] == ' ' || line[pos-1] == '\t')) diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index 6eb9830..9ef13d2 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -388,15 +388,19 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document()); if (!m_frame->document()->inPageCache()) { - m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document()); - - if (m_provisionalDocumentLoader) { - DocumentLoadTiming* timing = m_provisionalDocumentLoader->timing(); + RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent, false, false)); + // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed + // while dispatching the event, so protect it to prevent writing the end + // time into freed memory. + if (RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader) { + DocumentLoadTiming* timing = documentLoader->timing(); ASSERT(timing->navigationStart); + ASSERT(!timing->unloadEventStart); ASSERT(!timing->unloadEventEnd); - timing->unloadEventEnd = currentTime(); - ASSERT(timing->unloadEventEnd >= timing->navigationStart); - } + m_frame->domWindow()->dispatchTimedEvent(unloadEvent, m_frame->domWindow()->document(), &timing->unloadEventStart, &timing->unloadEventEnd); + ASSERT(timing->unloadEventStart >= timing->navigationStart); + } else + m_frame->domWindow()->dispatchEvent(unloadEvent, m_frame->domWindow()->document()); } } m_pageDismissalEventBeingDispatched = false; @@ -2343,7 +2347,7 @@ CachePolicy FrameLoader::subresourceCachePolicy() const return CachePolicyRevalidate; if (request.cachePolicy() == ReturnCacheDataElseLoad) - return CachePolicyAllowStale; + return CachePolicyHistoryBuffer; return CachePolicyVerify; } diff --git a/WebCore/loader/HistoryController.cpp b/WebCore/loader/HistoryController.cpp index 07bece7..ff733a9 100644 --- a/WebCore/loader/HistoryController.cpp +++ b/WebCore/loader/HistoryController.cpp @@ -66,6 +66,7 @@ static inline void addVisitedLink(Page* page, const KURL& url) HistoryController::HistoryController(Frame* frame) : m_frame(frame) + , m_frameLoadComplete(true) { } @@ -138,10 +139,10 @@ void HistoryController::saveDocumentState() // target of the current navigation (if we even decide to save with that granularity). // Because of previousItem's "masking" of currentItem for this purpose, it's important - // that previousItem be cleared at the end of a page transition. We leverage the - // checkLoadComplete recursion to achieve this goal. + // that we keep track of the end of a page transition with m_frameLoadComplete. We + // leverage the checkLoadComplete recursion to achieve this goal. - HistoryItem* item = m_previousItem ? m_previousItem.get() : m_currentItem.get(); + HistoryItem* item = m_frameLoadComplete ? m_currentItem.get() : m_previousItem.get(); if (!item) return; @@ -245,7 +246,8 @@ void HistoryController::updateForBackForwardNavigation() #endif // Must grab the current scroll position before disturbing it - saveScrollPositionAndViewStateToItem(m_previousItem.get()); + if (!m_frameLoadComplete) + saveScrollPositionAndViewStateToItem(m_previousItem.get()); } void HistoryController::updateForReload() @@ -392,6 +394,7 @@ void HistoryController::updateForCommit() // the provisional item for restoring state. // Note previousItem must be set before we close the URL, which will // happen when the data source is made non-provisional below + m_frameLoadComplete = false; m_previousItem = m_currentItem; ASSERT(m_provisionalItem); m_currentItem = m_provisionalItem; @@ -418,12 +421,15 @@ void HistoryController::updateForSameDocumentNavigation() void HistoryController::updateForFrameLoadCompleted() { // Even if already complete, we might have set a previous item on a frame that - // didn't do any data loading on the past transaction. Make sure to clear these out. - m_previousItem = 0; + // didn't do any data loading on the past transaction. Make sure to track that + // the load is complete so that we use the current item instead. + m_frameLoadComplete = true; } void HistoryController::setCurrentItem(HistoryItem* item) { + m_frameLoadComplete = false; + m_previousItem = m_currentItem; m_currentItem = item; } @@ -498,6 +504,7 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal) } // Set the item for which we will save document state + m_frameLoadComplete = false; m_previousItem = m_currentItem; m_currentItem = item; @@ -507,7 +514,7 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal) PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bool clipAtTarget) { RefPtr<HistoryItem> bfItem = createItem(m_frame->tree()->parent() ? true : false); - if (m_previousItem) + if (!m_frameLoadComplete) saveScrollPositionAndViewStateToItem(m_previousItem.get()); if (!clipAtTarget || m_frame != targetFrame) { @@ -563,14 +570,15 @@ void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromIt && fromItem->hasSameFrames(item)) { // This content is good, so leave it alone and look for children that need reloading - // Save form state (works from currentItem, since prevItem is nil) - ASSERT(!m_previousItem); + // Save form state (works from currentItem, since m_frameLoadComplete is true) + ASSERT(m_frameLoadComplete); saveDocumentState(); saveScrollPositionAndViewStateToItem(m_currentItem.get()); if (FrameView* view = m_frame->view()) view->setWasScrolledByUser(false); + m_previousItem = m_currentItem; m_currentItem = item; // Restore form state (works from currentItem) diff --git a/WebCore/loader/HistoryController.h b/WebCore/loader/HistoryController.h index 1002dbc..1bf5072 100644 --- a/WebCore/loader/HistoryController.h +++ b/WebCore/loader/HistoryController.h @@ -96,6 +96,8 @@ private: RefPtr<HistoryItem> m_currentItem; RefPtr<HistoryItem> m_previousItem; RefPtr<HistoryItem> m_provisionalItem; + + bool m_frameLoadComplete; }; } // namespace WebCore diff --git a/WebCore/loader/NavigationScheduler.h b/WebCore/loader/NavigationScheduler.h index 3bf5010..1400c25 100644 --- a/WebCore/loader/NavigationScheduler.h +++ b/WebCore/loader/NavigationScheduler.h @@ -28,8 +28,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RedirectScheduler_h -#define RedirectScheduler_h +#ifndef NavigationScheduler_h +#define NavigationScheduler_h #include "Event.h" #include "Timer.h" @@ -79,4 +79,4 @@ private: } // namespace WebCore -#endif // RedirectScheduler_h +#endif // NavigationScheduler_h diff --git a/WebCore/loader/ResourceLoadScheduler.cpp b/WebCore/loader/ResourceLoadScheduler.cpp index ca85ff4..7c50dc1 100644 --- a/WebCore/loader/ResourceLoadScheduler.cpp +++ b/WebCore/loader/ResourceLoadScheduler.cpp @@ -192,10 +192,9 @@ void ResourceLoadScheduler::servePendingRequests(HostInformation* host, Priority if (shouldLimitRequests && host->limitRequests()) return; - resourceLoader->start(); - if (!resourceLoader->reachedTerminalState()) - host->addLoadInProgress(resourceLoader.get()); requestsPending.removeFirst(); + host->addLoadInProgress(resourceLoader.get()); + resourceLoader->start(); } } } diff --git a/WebCore/loader/cache/CachePolicy.h b/WebCore/loader/cache/CachePolicy.h index 2639caa..0b9010b 100644 --- a/WebCore/loader/cache/CachePolicy.h +++ b/WebCore/loader/cache/CachePolicy.h @@ -33,7 +33,7 @@ namespace WebCore { CachePolicyVerify, CachePolicyRevalidate, CachePolicyReload, - CachePolicyAllowStale + CachePolicyHistoryBuffer }; } diff --git a/WebCore/loader/cache/CachedImage.cpp b/WebCore/loader/cache/CachedImage.cpp index c610b0b..eb5fb1c 100644 --- a/WebCore/loader/cache/CachedImage.cpp +++ b/WebCore/loader/cache/CachedImage.cpp @@ -55,7 +55,6 @@ CachedImage::CachedImage(const String& url) : CachedResource(url, ImageResource) , m_image(0) , m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired) - , m_httpStatusCodeErrorOccurred(false) { setStatus(Unknown); } @@ -64,7 +63,6 @@ CachedImage::CachedImage(Image* image) : CachedResource(String(), ImageResource) , m_image(image) , m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired) - , m_httpStatusCodeErrorOccurred(false) { setStatus(Cached); setLoading(false); @@ -314,7 +312,7 @@ void CachedImage::error(CachedResource::Status status) { clear(); setStatus(status); - ASSERT(errorOccurred() || httpStatusCodeErrorOccurred()); + ASSERT(errorOccurred()); m_data.clear(); notifyObservers(); setLoading(false); diff --git a/WebCore/loader/cache/CachedImage.h b/WebCore/loader/cache/CachedImage.h index af36534..e889ea0 100644 --- a/WebCore/loader/cache/CachedImage.h +++ b/WebCore/loader/cache/CachedImage.h @@ -67,8 +67,8 @@ public: virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived); virtual void error(CachedResource::Status); - virtual void httpStatusCodeError() { m_httpStatusCodeErrorOccurred = true; } - bool httpStatusCodeErrorOccurred() const { return m_httpStatusCodeErrorOccurred; } + // For compatibility, images keep loading even if there are HTTP errors. + virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return true; } void checkNotify(); @@ -97,7 +97,6 @@ private: RefPtr<Image> m_image; Timer<CachedImage> m_decodedDataDeletionTimer; - bool m_httpStatusCodeErrorOccurred; }; } diff --git a/WebCore/loader/cache/CachedResource.cpp b/WebCore/loader/cache/CachedResource.cpp index d4eac2e..844065d 100644 --- a/WebCore/loader/cache/CachedResource.cpp +++ b/WebCore/loader/cache/CachedResource.cpp @@ -252,8 +252,11 @@ void CachedResource::removeClient(CachedResourceClient* client) allClientsRemoved(); if (response().cacheControlContainsNoStore()) { // RFC2616 14.9.2: - // "no-store: ...MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible" - cache()->remove(this); + // "no-store: ... MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible" + // "... History buffers MAY store such responses as part of their normal operation." + // We allow non-secure content to be reused in history, but we do not allow secure content to be reused. + if (protocolIs(url(), "https")) + cache()->remove(this); } else cache()->prune(); } diff --git a/WebCore/loader/cache/CachedResource.h b/WebCore/loader/cache/CachedResource.h index ed60f84..9a54c53 100644 --- a/WebCore/loader/cache/CachedResource.h +++ b/WebCore/loader/cache/CachedResource.h @@ -85,7 +85,8 @@ public: virtual String encoding() const { return String(); } virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived); virtual void error(CachedResource::Status) { } - virtual void httpStatusCodeError() { error(LoadError); } // Images keep loading in spite of HTTP errors (for legacy compat with <img>, etc.). + + virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; } const String &url() const { return m_url; } Type type() const { return static_cast<Type>(m_type); } diff --git a/WebCore/loader/cache/CachedResourceLoader.cpp b/WebCore/loader/cache/CachedResourceLoader.cpp index 3cca206..992e1b5 100644 --- a/WebCore/loader/cache/CachedResourceLoader.cpp +++ b/WebCore/loader/cache/CachedResourceLoader.cpp @@ -116,7 +116,7 @@ void CachedResourceLoader::checkForReload(const KURL& fullURL) case CachePolicyRevalidate: cache()->revalidateResource(existing, this); break; - case CachePolicyAllowStale: + case CachePolicyHistoryBuffer: return; } @@ -271,7 +271,8 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, checkForReload(fullURL); - CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, isPreload); + bool allowForHistoryOnlyResources = cachePolicy() == CachePolicyHistoryBuffer; + CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, isPreload, allowForHistoryOnlyResources); if (resource) { // Check final URL of resource to catch redirects. // See <https://bugs.webkit.org/show_bug.cgi?id=21963>. diff --git a/WebCore/loader/cache/MemoryCache.cpp b/WebCore/loader/cache/MemoryCache.cpp index bd42e5f..ae8e53a 100644 --- a/WebCore/loader/cache/MemoryCache.cpp +++ b/WebCore/loader/cache/MemoryCache.cpp @@ -95,9 +95,9 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url return 0; } -CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload) +CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload, bool forHistory) { - LOG(ResourceLoading, "MemoryCache::requestResource '%s', charset '%s', preload=%u", url.string().latin1().data(), charset.latin1().data(), requestIsPreload); + LOG(ResourceLoading, "MemoryCache::requestResource '%s', charset '%s', preload=%u, forHistory=%u", url.string().latin1().data(), charset.latin1().data(), requestIsPreload, forHistory); // FIXME: Do we really need to special-case an empty URL? // Would it be better to just go on with the cache code and let it fail later? @@ -107,6 +107,15 @@ CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourc // Look up the resource in our map. CachedResource* resource = resourceForURL(url.string()); + // Non https "no-store" resources are left in the cache to be used for back/forward navigation only. + // If this is not a request forHistory and the resource was served with "no-store" we should evict + // it here and make a fresh request. + if (!forHistory && resource && resource->response().cacheControlContainsNoStore()) { + LOG(ResourceLoading, "MemoryCache::requestResource cleared a for history only resource due to a non-history request for the resource"); + evict(resource); + resource = 0; + } + if (resource && requestIsPreload && !resource->isPreloaded()) { LOG(ResourceLoading, "MemoryCache::requestResource already has a preload request for this request, and it hasn't been preloaded yet"); return 0; @@ -118,7 +127,13 @@ CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourc FrameLoader::reportLocalLoadFailed(cachedResourceLoader->document()->frame(), url.string()); return 0; } - + + if (resource && resource->type() != type) { + LOG(ResourceLoading, "Cache::requestResource found a cache resource with matching url but different type, evicting and loading with new type."); + evict(resource); + resource = 0; + } + if (!resource) { LOG(ResourceLoading, "CachedResource for '%s' wasn't found in cache. Creating it", url.string().latin1().data()); // The resource does not exist. Create it. @@ -149,11 +164,6 @@ CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourc } } - if (resource->type() != type) { - LOG(ResourceLoading, "MemoryCache::requestResource cannot use cached resource for '%s' due to type mismatch", url.string().latin1().data()); - return 0; - } - if (!disabled()) { // This will move the resource to the front of its LRU list and increase its access count. resourceAccessed(resource); diff --git a/WebCore/loader/cache/MemoryCache.h b/WebCore/loader/cache/MemoryCache.h index a40f85e..6b94eda 100644 --- a/WebCore/loader/cache/MemoryCache.h +++ b/WebCore/loader/cache/MemoryCache.h @@ -109,7 +109,7 @@ public: // Request resources from the cache. A load will be initiated and a cache object created if the object is not // found in the cache. - CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false); + CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false, bool forHistory = false); CachedCSSStyleSheet* requestUserCSSStyleSheet(CachedResourceLoader*, const String& url, const String& charset); diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp index e1313d6..1f2ced3 100644 --- a/WebCore/loader/loader.cpp +++ b/WebCore/loader/loader.cpp @@ -324,7 +324,8 @@ void Loader::didReceiveData(SubresourceLoader* loader, const char* data, int siz return; if (resource->response().httpStatusCode() >= 400) { - resource->httpStatusCodeError(); + if (!resource->shouldIgnoreHTTPStatusCodeErrors()) + resource->error(CachedResource::LoadError); return; } @@ -337,7 +338,7 @@ void Loader::didReceiveData(SubresourceLoader* loader, const char* data, int siz } else if (request->isIncremental()) resource->data(loader->resourceData(), false); } - + void Loader::didReceiveCachedMetadata(SubresourceLoader* loader, const char* data, int size) { Request* request = m_requestsLoading.get(loader); |