Example #1
0
NS_IMETHODIMP
nsBaseChannel::GetOriginalURI(nsIURI **aURI)
{
  *aURI = OriginalURI();
  NS_ADDREF(*aURI);
  return NS_OK;
}
Example #2
0
nsresult
nsBaseChannel::ContinueRedirect()
{
  // Backwards compat for non-internal redirects from a HTTP channel.
  // XXX Is our http channel implementation going to derive from nsBaseChannel?
  //     If not, this code can be removed.
  if (!(mRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
    nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface();
    if (httpChannel) {
      nsCOMPtr<nsIHttpEventSink> httpEventSink;
      GetCallback(httpEventSink);
      if (httpEventSink) {
        nsresult rv = httpEventSink->OnRedirect(httpChannel, mRedirectChannel);
        if (NS_FAILED(rv)) {
          return rv;
        }
      }
    }
  }

  // Make sure to do this _after_ making all the OnChannelRedirect calls
  mRedirectChannel->SetOriginalURI(OriginalURI());

  // If we fail to open the new channel, then we want to leave this channel
  // unaffected, so we defer tearing down our channel until we have succeeded
  // with the redirect.

  if (mOpenRedirectChannel) {
    nsresult rv = NS_OK;
    if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
      MOZ_ASSERT(!mListenerContext, "mListenerContext should be null!");
      rv = mRedirectChannel->AsyncOpen2(mListener);
    }
    else {
      rv = mRedirectChannel->AsyncOpen(mListener, mListenerContext);
    }
    NS_ENSURE_SUCCESS(rv, rv);
  }

  mRedirectChannel = nullptr;

  // close down this channel
  Cancel(NS_BINDING_REDIRECTED);
  ChannelDone();

  return NS_OK;
}
nsresult
nsBaseChannel::Redirect(nsIChannel *newChannel, PRUint32 redirectFlags)
{
    SUSPEND_PUMP_FOR_SCOPE();

    // Transfer properties

    newChannel->SetOriginalURI(OriginalURI());
    newChannel->SetLoadGroup(mLoadGroup);
    newChannel->SetNotificationCallbacks(mCallbacks);
    newChannel->SetLoadFlags(mLoadFlags | LOAD_REPLACE);

    nsCOMPtr<nsIWritablePropertyBag> bag = ::do_QueryInterface(newChannel);
    if (bag)
        mPropertyHash.EnumerateRead(CopyProperties, bag.get());

    // Notify consumer, giving chance to cancel redirect.  For backwards compat,
    // we support nsIHttpEventSink if we are an HTTP channel and if this is not
    // an internal redirect.

    // Global observers. These come first so that other observers don't see
    // redirects that get aborted for security reasons anyway.
    NS_ASSERTION(gIOService, "Must have an IO service");
    nsresult rv = gIOService->OnChannelRedirect(this, newChannel, redirectFlags);
    if (NS_FAILED(rv))
        return rv;

    // Backwards compat for non-internal redirects from a HTTP channel.
    if (!(redirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
        nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface();
        if (httpChannel) {
            nsCOMPtr<nsIHttpEventSink> httpEventSink;
            GetCallback(httpEventSink);
            if (httpEventSink) {
                rv = httpEventSink->OnRedirect(httpChannel, newChannel);
                if (NS_FAILED(rv))
                    return rv;
            }
        }
    }

    nsCOMPtr<nsIChannelEventSink> channelEventSink;
    // Give our consumer a chance to observe/block this redirect.
    GetCallback(channelEventSink);
    if (channelEventSink) {
        rv = channelEventSink->OnChannelRedirect(this, newChannel, redirectFlags);
        if (NS_FAILED(rv))
            return rv;
    }

    // If we fail to open the new channel, then we want to leave this channel
    // unaffected, so we defer tearing down our channel until we have succeeded
    // with the redirect.

    rv = newChannel->AsyncOpen(mListener, mListenerContext);
    if (NS_FAILED(rv))
        return rv;

    // close down this channel
    Cancel(NS_BINDING_REDIRECTED);
    mListener = nsnull;
    mListenerContext = nsnull;

    return NS_OK;
}