/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// We never care to fully open the entry, since we won't actually use it. // We just want to be able to do all our checks to see if a future channel can // use this entry, or if we need to accept the push.
*result = nsICacheEntryOpenCallback::ENTRY_NOT_WANTED;
nsresult rv =
nsHttp::GetHttpResponseHeadFromCacheEntry(entry, &cachedResponseHead); if (NS_FAILED(rv)) { // Couldn't make sense of what's in the cache entry, go ahead and accept // the push. return NS_OK;
}
if ((cachedResponseHead.Status() / 100) != 2) { // Assume the push is sending us a success, while we don't have one in the // cache, so we'll accept the push. return NS_OK;
}
// Get the method that was used to generate the cached response
nsCString buf;
rv = entry->GetMetaDataElement("request-method", getter_Copies(buf)); if (NS_FAILED(rv)) { // Can't check request method, accept the push return NS_OK;
}
nsAutoCString pushedMethod;
requestHead.Method(pushedMethod); if (!buf.Equals(pushedMethod)) { // Methods don't match, accept the push return NS_OK;
}
int64_t size, contentLength;
rv = nsHttp::CheckPartial(entry, &size, &contentLength, &cachedResponseHead); if (NS_FAILED(rv)) { // Couldn't figure out if this was partial or not, accept the push. return NS_OK;
}
if (size == int64_t(-1) || contentLength != size) { // This is partial content in the cache, accept the push. return NS_OK;
}
nsAutoCString requestedETag; if (NS_FAILED(requestHead.GetHeader(nsHttp::If_Match, requestedETag))) { // Can't check etag return NS_OK;
} if (!requestedETag.IsEmpty()) {
nsAutoCString cachedETag; if (NS_FAILED(cachedResponseHead.GetHeader(nsHttp::ETag, cachedETag))) { // Can't check etag return NS_OK;
} if (!requestedETag.Equals(cachedETag)) { // ETags don't match, accept the push. return NS_OK;
}
}
nsAutoCString imsString;
Unused << requestHead.GetHeader(nsHttp::If_Modified_Since, imsString); if (!buf.IsEmpty()) {
uint32_t ims = buf.ToInteger(&rv);
uint32_t lm;
rv = cachedResponseHead.GetLastModifiedValue(&lm); if (NS_SUCCEEDED(rv) && lm && lm < ims) { // The push appears to be newer than what's in our cache, accept it. return NS_OK;
}
}
nsAutoCString cacheControlRequestHeader;
Unused << requestHead.GetHeader(nsHttp::Cache_Control,
cacheControlRequestHeader);
CacheControlParser cacheControlRequest(cacheControlRequestHeader); if (cacheControlRequest.NoStore()) { // Don't use a no-store cache entry, accept the push. return NS_OK;
}
nsCString cachedAuth;
rv = entry->GetMetaDataElement("auth", getter_Copies(cachedAuth)); if (NS_SUCCEEDED(rv)) {
uint32_t lastModifiedTime;
rv = entry->GetLastModified(&lastModifiedTime); if (NS_SUCCEEDED(rv)) { if ((gHttpHandler->SessionStartTime() > lastModifiedTime) &&
!cachedAuth.IsEmpty()) { // Need to revalidate this, as the auth is old. Accept the push. return NS_OK;
}
if (cachedAuth.IsEmpty() &&
requestHead.HasHeader(nsHttp::Authorization)) { // They're pushing us something with auth, but we didn't cache anything // with auth. Accept the push. return NS_OK;
}
}
}
// We'll need this value in later computations...
uint32_t lastModifiedTime;
rv = entry->GetLastModified(&lastModifiedTime); if (NS_FAILED(rv)) { // Ugh, this really sucks. OK, accept the push. return NS_OK;
}
// Determine if this is the first time that this cache entry // has been accessed during this session. bool fromPreviousSession =
(gHttpHandler->SessionStartTime() > lastModifiedTime);
if (validationRequired) { // A real channel would most likely hit the net at this point, so let's // accept the push. return NS_OK;
}
// If we get here, then we would be able to use this cache entry. Cancel the // push so as not to waste any more bandwidth.
acceptPush = false; return NS_OK;
}
NS_IMETHODIMP
CachePushChecker::OnCacheEntryAvailable(nsICacheEntry* entry, bool isNew,
nsresult result) { // Nothing to do here, all the work is in OnCacheEntryCheck. return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.