NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt){  nsresult rv;  LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");  NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder");  /* if mChannel isn't set here, use aRequest.     Having mChannel set is important for Canceling the load, and since we set     mChannel to null in OnStopRequest.  Since with multipart/x-mixed-replace, you     can get multiple OnStartRequests, we need to reinstance mChannel so that when/if     Cancel() gets called, we have a channel to cancel and we don't leave the channel     open forever.   */  if (!mChannel) {    nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));    if (mpchan)      mpchan->GetBaseChannel(getter_AddRefs(mChannel));    else      mChannel = do_QueryInterface(aRequest);  }  nsCAutoString contentType;  mChannel->GetContentType(contentType);  if (contentType.Equals(NS_LITERAL_CSTRING("multipart/x-mixed-replace"),                         nsCaseInsensitiveCStringComparator()))      mIsMultiPartChannel = PR_TRUE;  /* set our state variables to their initial values. */  mImageStatus = imgIRequest::STATUS_NONE;  mState = 0;  /* set our loading flag to true */  mLoading = PR_TRUE;  /* notify our kids */  PRInt32 count = mObservers.Count();  for (PRInt32 i = 0; i < count; i++) {    imgRequestProxy *proxy = NS_STATIC_CAST(imgRequestProxy*, mObservers[i]);    if (proxy) proxy->OnStartRequest(aRequest, ctxt);    // If this assertion fires, it means that imgRequest notifications could    // be dropped!    NS_ASSERTION(count == mObservers.Count(),                  "The observer list changed while being iterated over!");  }  nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));  /* get the expires info */  if (mCacheEntry) {    nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest));    if (cacheChannel) {      nsCOMPtr<nsISupports> cacheToken;      cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));      if (cacheToken) {        nsCOMPtr<nsICacheEntryInfo> entryDesc(do_QueryInterface(cacheToken));        if (entryDesc) {          PRUint32 expiration;          /* get the expiration time from the caching channel's token */          entryDesc->GetExpirationTime(&expiration);          /* set the expiration time on our entry */          mCacheEntry->SetExpirationTime(expiration);        }      }    }    //    // Determine whether the cache entry must be revalidated when it expires.    // If so, then the cache entry must *not* be used during HISTORY loads if    // it has expired.    //    // Currently, only HTTP specifies this information...    //    nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));    if (httpChannel) {      PRBool bMustRevalidate = PR_FALSE;      rv = httpChannel->IsNoStoreResponse(&bMustRevalidate);      if (!bMustRevalidate) {        rv = httpChannel->IsNoCacheResponse(&bMustRevalidate);      }      if (!bMustRevalidate) {        nsCAutoString cacheHeader;        rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"),                                            cacheHeader);        if (PL_strcasestr(cacheHeader.get(), "must-revalidate")) {          bMustRevalidate = PR_TRUE;        }      }      if (bMustRevalidate) {        mCacheEntry->SetMetaDataElement("MustValidateIfExpired", "true");      }    }  }  // Shouldn't we be dead already if this gets hit?  Probably multipart/x-mixed-replace...  if (mObservers.Count() == 0) {    this->Cancel(NS_IMAGELIB_ERROR_FAILURE);  }  return NS_OK;}