Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsPrefetchService.cpp File Reference
#include "nsPrefetchService.h"
#include "nsIServiceManager.h"
#include "nsICategoryManager.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch2.h"
#include "nsIDocCharset.h"
#include "nsIWebProgress.h"
#include "nsCURILoader.h"
#include "nsICachingChannel.h"
#include "nsICacheVisitor.h"
#include "nsIHttpChannel.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsAutoPtr.h"
#include "prtime.h"
#include "prlog.h"
#include "plstr.h"

Go to the source code of this file.


#define LOG(args)   PR_LOG(gPrefetchLog, 4, args)
#define LOG_ENABLED()   PR_LOG_TEST(gPrefetchLog, 4)
#define PREFETCH_PREF   "network.prefetch-next"
#define NowInSeconds()   PRTimeToSeconds(PR_Now())


static PRUint32 PRTimeToSeconds (PRTime t_usec)
 NS_IMPL_ISUPPORTS4 (nsPrefetchListener, nsIRequestObserver, nsIStreamListener, nsIInterfaceRequestor, nsIChannelEventSink) NS_IMETHODIMP nsPrefetchListener
 NS_IMPL_ISUPPORTS4 (nsPrefetchService, nsIPrefetchService, nsIWebProgressListener, nsIObserver, nsISupportsWeakReference) NS_IMETHODIMP nsPrefetchService

Define Documentation

#define LOG (   args)    PR_LOG(gPrefetchLog, 4, args)

Definition at line 72 of file nsPrefetchService.cpp.

#define LOG_ENABLED ( )    PR_LOG_TEST(gPrefetchLog, 4)

Definition at line 73 of file nsPrefetchService.cpp.

Definition at line 95 of file nsPrefetchService.cpp.

#define PREFETCH_PREF   "network.prefetch-next"

Definition at line 78 of file nsPrefetchService.cpp.

Function Documentation

static NS_DEFINE_IID ( kDocLoaderServiceCID  ,
) [static]
static NS_DEFINE_IID ( kPrefServiceCID  ,
) [static]

Definition at line 131 of file nsPrefetchService.cpp.

    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;
    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;
    return NS_OK;

Here is the call graph for this function:

Definition at line 465 of file nsPrefetchService.cpp.

    nsresult rv;


#if defined(PR_LOGGING)
    if (LOG_ENABLED()) {
        nsCAutoString spec;
        LOG(("PrefetchURI [%s]\n", spec.get()));

    if (mDisabled) {
        LOG(("rejected: prefetch service is disabled\n"));
        return NS_ERROR_ABORT;

    // XXX we should really be asking the protocol handler if it supports
    // caching, so we can determine if there is any value to prefetching.
    // for now, we'll only prefetch http links since we know that's the 
    // most common case.  ignore https links since https content only goes
    // into the memory cache.
    // XXX we might want to either leverage nsIProtocolHandler::protocolFlags
    // or possibly nsIRequest::loadFlags to determine if this URI should be
    // prefetched.
    PRBool match;
    rv = aURI->SchemeIs("http", &match); 
    if (NS_FAILED(rv) || !match) {
        LOG(("rejected: URL is not of type http\n"));
        return NS_ERROR_ABORT;

    // the referrer URI must be http:
    rv = aReferrerURI->SchemeIs("http", &match);
    if (NS_FAILED(rv) || !match) {
        LOG(("rejected: referrer URL is not of type http\n"));
        return NS_ERROR_ABORT;

    // skip URLs that contain query strings, except URLs for which prefetching
    // has been explicitly requested.
    if (!aExplicit) {
        nsCOMPtr<nsIURL> url(do_QueryInterface(aURI, &rv));
        if (NS_FAILED(rv)) return rv;
        nsCAutoString query;
        rv = url->GetQuery(query);
        if (NS_FAILED(rv) || !query.IsEmpty()) {
            LOG(("rejected: URL has a query string\n"));
            return NS_ERROR_ABORT;

    // cancel if being prefetched
    if (mCurrentChannel) {
        nsCOMPtr<nsIURI> currentURI;
        if (currentURI) {
            PRBool equals;
            if (NS_SUCCEEDED(currentURI->Equals(aURI, &equals)) && equals) {
                LOG(("rejected: URL is already being prefetched\n"));
                return NS_ERROR_ABORT;

    // cancel if already on the prefetch queue
    nsPrefetchNode *node = mQueueHead;
    for (; node; node = node->mNext) {
        PRBool equals;
        if (NS_SUCCEEDED(node->mURI->Equals(aURI, &equals)) && equals) {
            LOG(("rejected: URL is already on prefetch queue\n"));
            return NS_ERROR_ABORT;

    return EnqueueURI(aURI, aReferrerURI);

Here is the call graph for this function:

static PRUint32 PRTimeToSeconds ( PRTime  t_usec) [inline, static]

Definition at line 85 of file nsPrefetchService.cpp.

    PRTime usec_per_sec;
    PRUint32 t_sec;
    LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
    LL_DIV(t_usec, t_usec, usec_per_sec);
    LL_L2I(t_sec, t_usec);
    return t_sec;