NS_IMETHODIMP
nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
        nsISupports* aContext)
{
    mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(aRequest, PR_FALSE));
    if (!mRequestApproved) {
        if (nsXMLHttpRequest::sAccessControlCache) {
            nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
            if (channel) {
                nsCOMPtr<nsIURI> uri;
                channel->GetURI(getter_AddRefs(uri));
                if (uri) {
                    nsXMLHttpRequest::sAccessControlCache->
                    RemoveEntries(uri, mRequestingPrincipal);
                }
            }
        }

        aRequest->Cancel(NS_ERROR_DOM_BAD_URI);
        mOuterListener->OnStartRequest(aRequest, aContext);

        return NS_ERROR_DOM_BAD_URI;
    }

    return mOuterListener->OnStartRequest(aRequest, aContext);
}
NS_IMETHODIMP
nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
                                    nsISupports* aContext)
{
  mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(aRequest));
  if (!mRequestApproved) {
    if (sPreflightCache) {
      nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
      if (channel) {
        nsCOMPtr<nsIURI> uri;
        NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
        if (uri) {
          sPreflightCache->RemoveEntries(uri, mRequestingPrincipal);
        }
      }
    }

    aRequest->Cancel(NS_ERROR_DOM_BAD_URI);
    mOuterListener->OnStartRequest(aRequest, aContext);

    return NS_ERROR_DOM_BAD_URI;
  }

  return mOuterListener->OnStartRequest(aRequest, aContext);
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
                                                 nsIChannel *aNewChannel,
                                                 PRUint32 aFlags,
                                                 nsIAsyncVerifyRedirectCallback *cb)
{
  nsresult rv;
  if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
    rv = CheckRequestApproved(aOldChannel, PR_TRUE);
    if (NS_FAILED(rv)) {
      if (nsXMLHttpRequest::sAccessControlCache) {
        nsCOMPtr<nsIURI> oldURI;
        NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
        if (oldURI) {
          nsXMLHttpRequest::sAccessControlCache->
            RemoveEntries(oldURI, mRequestingPrincipal);
        }
      }
      aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
      return NS_ERROR_DOM_BAD_URI;
    }
  }

  // Prepare to receive callback
  mRedirectCallback = cb;
  mOldRedirectChannel = aOldChannel;
  mNewRedirectChannel = aNewChannel;

  nsCOMPtr<nsIChannelEventSink> outer =
    do_GetInterface(mOuterNotificationCallbacks);
  if (outer) {
    rv = outer->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, this);
    if (NS_FAILED(rv)) {
        aOldChannel->Cancel(rv); // is this necessary...?
        mRedirectCallback = nsnull;
        mOldRedirectChannel = nsnull;
        mNewRedirectChannel = nsnull;
    }
    return rv;  
  }

  (void) OnRedirectVerifyCallback(NS_OK);
  return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
        nsIChannel *aNewChannel,
        PRUint32    aFlags)
{
    nsChannelCanceller canceller(aOldChannel);
    nsresult rv;
    if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
        rv = CheckRequestApproved(aOldChannel, PR_TRUE);
        if (NS_FAILED(rv)) {
            if (nsXMLHttpRequest::sAccessControlCache) {
                nsCOMPtr<nsIURI> oldURI;
                aOldChannel->GetURI(getter_AddRefs(oldURI));
                if (oldURI) {
                    nsXMLHttpRequest::sAccessControlCache->
                    RemoveEntries(oldURI, mRequestingPrincipal);
                }
            }
            return NS_ERROR_DOM_BAD_URI;
        }
    }

    nsCOMPtr<nsIChannelEventSink> outer =
        do_GetInterface(mOuterNotificationCallbacks);
    if (outer) {
        rv = outer->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    rv = UpdateChannel(aNewChannel);
    NS_ENSURE_SUCCESS(rv, rv);

    canceller.DontCancel();

    return NS_OK;
}