void CacheStorageService::MemoryPool::PurgeExpired() { MOZ_ASSERT(IsOnManagementThread()); mExpirationArray.Sort(ExpirationComparator()); uint32_t now = NowInSeconds(); uint32_t const memoryLimit = Limit(); for (uint32_t i = 0; mMemorySize > memoryLimit && i < mExpirationArray.Length();) { if (CacheIOThread::YieldAndRerun()) return; nsRefPtr<CacheEntry> entry = mExpirationArray[i]; uint32_t expirationTime = entry->GetExpirationTime(); if (expirationTime > 0 && expirationTime <= now) { LOG((" dooming expired entry=%p, exptime=%u (now=%u)", entry.get(), entry->GetExpirationTime(), now)); entry->PurgeAndDoom(); continue; } // not purged, move to the next one ++i; } }
PRUint32 nsHttpConnection::TimeToLive() { PRInt32 tmp = mIdleTimeout - (NowInSeconds() - mLastReadTime); if (0 > tmp) tmp = 0; return tmp; }
nsresult nsHttpConnection::Init(nsHttpConnectionInfo *info, PRUint16 maxHangTime) { LOG(("nsHttpConnection::Init [this=%x]\n", this)); NS_ENSURE_ARG_POINTER(info); NS_ENSURE_TRUE(!mConnInfo, NS_ERROR_ALREADY_INITIALIZED); mConnInfo = info; NS_ADDREF(mConnInfo); mMaxHangTime = maxHangTime; mLastReadTime = NowInSeconds(); return NS_OK; }
// From section 13.2.4 of RFC2616, we compute the freshness lifetime of a cached // response as follows: // // freshnessLifetime = max_age_value // <or> // freshnessLifetime = expires_value - date_value // <or> // freshnessLifetime = (date_value - last_modified_value) * 0.10 // <or> // freshnessLifetime = 0 // nsresult nsHttpResponseHead::ComputeFreshnessLifetime(uint32_t *result) const { *result = 0; // Try HTTP/1.1 style max-age directive... if (NS_SUCCEEDED(GetMaxAgeValue(result))) return NS_OK; *result = 0; uint32_t date = 0, date2 = 0; if (NS_FAILED(GetDateValue(&date))) date = NowInSeconds(); // synthesize a date header if none exists // Try HTTP/1.0 style expires header... if (NS_SUCCEEDED(GetExpiresValue(&date2))) { if (date2 > date) *result = date2 - date; // the Expires header can specify a date in the past. return NS_OK; } // Fallback on heuristic using last modified header... if (NS_SUCCEEDED(GetLastModifiedValue(&date2))) { LOG(("using last-modified to determine freshness-lifetime\n")); LOG(("last-modified = %u, date = %u\n", date2, date)); if (date2 <= date) { // this only makes sense if last-modified is actually in the past *result = (date - date2) / 10; return NS_OK; } } // These responses can be cached indefinitely. if ((mStatus == 300) || nsHttp::IsPermanentRedirect(mStatus)) { *result = uint32_t(-1); return NS_OK; } LOG(("nsHttpResponseHead::ComputeFreshnessLifetime [this = %x] " "Insufficient information to compute a non-zero freshness " "lifetime!\n", this)); return NS_OK; }
~AltSvcTransaction() { LOG(("AltSvcTransaction dtor %p map %p running %d", this, mMapping.get(), mRunning)); if (mRunning) { MOZ_ASSERT(mMapping->IsRunning()); MaybeValidate(NS_OK); } if (!mMapping->Validated()) { // try again later mMapping->SetExpiresAt(NowInSeconds() + 2); } LOG(("AltSvcTransaction dtor %p map %p validated %d [%s]", this, mMapping.get(), mMapping->Validated(), mMapping->HashKey().get())); mMapping->SetRunning(false); }
NS_IMETHODIMP nsPrefetchNode::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) { nsresult rv; nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aRequest, &rv); if (NS_FAILED(rv)) return rv; // no need to prefetch a document that is already in the cache PRBool fromCache; if (NS_SUCCEEDED(cachingChannel->IsFromCache(&fromCache)) && fromCache) { LOG(("document is already in the cache; canceling prefetch\n")); return NS_BINDING_ABORTED; } // // no need to prefetch a document that must be requested fresh each // and every time. // nsCOMPtr<nsISupports> cacheToken; cachingChannel->GetCacheToken(getter_AddRefs(cacheToken)); if (!cacheToken) return NS_ERROR_ABORT; // bail, no cache entry nsCOMPtr<nsICacheEntryInfo> entryInfo = do_QueryInterface(cacheToken, &rv); if (NS_FAILED(rv)) return rv; PRUint32 expTime; if (NS_SUCCEEDED(entryInfo->GetExpirationTime(&expTime))) { if (NowInSeconds() >= expTime) { LOG(("document cannot be reused from cache; " "canceling prefetch\n")); return NS_BINDING_ABORTED; } } mState = nsIDOMLoadStatus::RECEIVING; return NS_OK; }
nsresult nsHttpConnection::OnSocketReadable() { LOG(("nsHttpConnection::OnSocketReadable [this=%x]\n", this)); PRUint32 now = NowInSeconds(); if (mKeepAliveMask && (now - mLastReadTime >= PRUint32(mMaxHangTime))) { LOG(("max hang time exceeded!\n")); // give the handler a chance to create a new persistent connection to // this host if we've been busy for too long. mKeepAliveMask = PR_FALSE; gHttpHandler->ProcessPendingQ(mConnInfo); } mLastReadTime = now; nsresult rv; PRUint32 n; PRBool again = PR_TRUE; do { rv = mTransaction->WriteSegments(this, nsIOService::gDefaultSegmentSize, &n); if (NS_FAILED(rv)) { // if the transaction didn't want to take any more data, then // wait for the transaction to call ResumeRecv. if (rv == NS_BASE_STREAM_WOULD_BLOCK) rv = NS_OK; again = PR_FALSE; } else if (NS_FAILED(mSocketInCondition)) { // continue waiting for the socket if necessary... if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK) rv = mSocketIn->AsyncWait(this, 0, 0, nsnull); else rv = mSocketInCondition; again = PR_FALSE; } // read more from the socket until error... } while (again); return rv; }
PRBool nsHttpConnection::CanReuse() { return IsKeepAlive() && (NowInSeconds() - mLastReadTime < mIdleTimeout) && IsAlive(); }