mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 546581: e10s HTTP: create common base class for HttpChannelChild and nsHttpChannel. a=dwitte, r=jae-seong, r=jduell
This commit is contained in:
parent
a3e35da054
commit
70617ee7a8
816
netwerk/protocol/http/src/HttpBaseChannel.cpp
Normal file
816
netwerk/protocol/http/src/HttpBaseChannel.cpp
Normal file
@ -0,0 +1,816 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||||
|
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* The Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Daniel Witte <dwitte@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "mozilla/net/HttpBaseChannel.h"
|
||||||
|
|
||||||
|
#include "nsHttpHandler.h"
|
||||||
|
#include "nsMimeTypes.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
|
#define DROP_DEAD() \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"*&*&*&*&*&*&*&**&*&&*& FATAL ERROR: '%s' UNIMPLEMENTED: %s +%d", \
|
||||||
|
__FUNCTION__, __FILE__, __LINE__); \
|
||||||
|
NS_ABORT(); \
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
HttpBaseChannel::HttpBaseChannel()
|
||||||
|
: mStatus(NS_OK)
|
||||||
|
, mLoadFlags(LOAD_NORMAL)
|
||||||
|
, mCaps(0)
|
||||||
|
, mRedirectionLimit(gHttpHandler->RedirectionLimit())
|
||||||
|
, mIsPending(PR_FALSE)
|
||||||
|
, mWasOpened(PR_FALSE)
|
||||||
|
, mResponseHeadersModified(PR_FALSE)
|
||||||
|
, mAllowPipelining(PR_TRUE)
|
||||||
|
, mForceAllowThirdPartyCookie(PR_FALSE)
|
||||||
|
{
|
||||||
|
LOG(("Creating HttpBaseChannel @%x\n", this));
|
||||||
|
|
||||||
|
// grab a reference to the handler to ensure that it doesn't go away.
|
||||||
|
NS_ADDREF(gHttpHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpBaseChannel::~HttpBaseChannel()
|
||||||
|
{
|
||||||
|
LOG(("Destroying HttpBaseChannel @%x\n", this));
|
||||||
|
|
||||||
|
nsHttpHandler* handler = gHttpHandler;
|
||||||
|
NS_RELEASE(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
HttpBaseChannel::Init(nsIURI *aURI,
|
||||||
|
PRUint8 aCaps,
|
||||||
|
nsProxyInfo *aProxyInfo)
|
||||||
|
{
|
||||||
|
LOG(("HttpBaseChannel::Init [this=%p]\n", this));
|
||||||
|
|
||||||
|
NS_PRECONDITION(aURI, "null uri");
|
||||||
|
|
||||||
|
nsresult rv = nsHashPropertyBag::Init();
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
mURI = aURI;
|
||||||
|
mOriginalURI = aURI;
|
||||||
|
mDocumentURI = nsnull;
|
||||||
|
mCaps = aCaps;
|
||||||
|
|
||||||
|
// Construct connection info object
|
||||||
|
nsCAutoString host;
|
||||||
|
PRInt32 port = -1;
|
||||||
|
PRBool usingSSL = PR_FALSE;
|
||||||
|
|
||||||
|
rv = mURI->SchemeIs("https", &usingSSL);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = mURI->GetAsciiHost(host);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// Reject the URL if it doesn't specify a host
|
||||||
|
if (host.IsEmpty())
|
||||||
|
return NS_ERROR_MALFORMED_URI;
|
||||||
|
|
||||||
|
rv = mURI->GetPort(&port);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
LOG(("host=%s port=%d\n", host.get(), port));
|
||||||
|
|
||||||
|
rv = mURI->GetAsciiSpec(mSpec);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
LOG(("uri=%s\n", mSpec.get()));
|
||||||
|
|
||||||
|
mConnectionInfo = new nsHttpConnectionInfo(host, port,
|
||||||
|
aProxyInfo, usingSSL);
|
||||||
|
if (!mConnectionInfo)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
// Set default request method
|
||||||
|
mRequestHead.SetMethod(nsHttp::Get);
|
||||||
|
|
||||||
|
// Set request headers
|
||||||
|
nsCAutoString hostLine;
|
||||||
|
rv = nsHttpHandler::GenerateHostPort(host, port, hostLine);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = gHttpHandler->
|
||||||
|
AddStandardRequestHeaders(&mRequestHead.Headers(), aCaps,
|
||||||
|
!mConnectionInfo->UsingSSL() &&
|
||||||
|
mConnectionInfo->UsingHttpProxy());
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// HttpBaseChannel::nsISupports
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED4(HttpBaseChannel,
|
||||||
|
nsHashPropertyBag,
|
||||||
|
nsIRequest,
|
||||||
|
nsIChannel,
|
||||||
|
nsIHttpChannel,
|
||||||
|
nsIHttpChannelInternal)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// HttpBaseChannel::nsIRequest
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetName(nsACString& aName)
|
||||||
|
{
|
||||||
|
aName = mSpec;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::IsPending(PRBool *aIsPending)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aIsPending);
|
||||||
|
*aIsPending = mIsPending;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetStatus(nsresult *aStatus)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aStatus);
|
||||||
|
*aStatus = mStatus;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetLoadGroup(nsILoadGroup **aLoadGroup)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aLoadGroup);
|
||||||
|
*aLoadGroup = mLoadGroup;
|
||||||
|
NS_IF_ADDREF(*aLoadGroup);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||||
|
{
|
||||||
|
mLoadGroup = aLoadGroup;
|
||||||
|
mProgressSink = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aLoadFlags);
|
||||||
|
*aLoadFlags = mLoadFlags;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
|
||||||
|
{
|
||||||
|
mLoadFlags = aLoadFlags;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// HttpBaseChannel::nsIChannel
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetOriginalURI(nsIURI **aOriginalURI)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aOriginalURI);
|
||||||
|
*aOriginalURI = mOriginalURI;
|
||||||
|
NS_ADDREF(*aOriginalURI);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetOriginalURI(nsIURI *aOriginalURI)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
NS_ENSURE_ARG_POINTER(aOriginalURI);
|
||||||
|
mOriginalURI = aOriginalURI;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetURI(nsIURI **aURI)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aURI);
|
||||||
|
*aURI = mURI;
|
||||||
|
NS_ADDREF(*aURI);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks)
|
||||||
|
{
|
||||||
|
*aCallbacks = mCallbacks;
|
||||||
|
NS_IF_ADDREF(*aCallbacks);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
|
||||||
|
{
|
||||||
|
mCallbacks = aCallbacks;
|
||||||
|
mProgressSink = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetContentType(nsACString& aContentType)
|
||||||
|
{
|
||||||
|
if (!mResponseHead) {
|
||||||
|
aContentType.Truncate();
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mResponseHead->ContentType().IsEmpty()) {
|
||||||
|
aContentType = mResponseHead->ContentType();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
aContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetContentType(const nsACString& aContentType)
|
||||||
|
{
|
||||||
|
if (mListener || mWasOpened) {
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
nsCAutoString contentTypeBuf, charsetBuf;
|
||||||
|
PRBool hadCharset;
|
||||||
|
net_ParseContentType(aContentType, contentTypeBuf, charsetBuf, &hadCharset);
|
||||||
|
|
||||||
|
mResponseHead->SetContentType(contentTypeBuf);
|
||||||
|
|
||||||
|
// take care not to stomp on an existing charset
|
||||||
|
if (hadCharset)
|
||||||
|
mResponseHead->SetContentCharset(charsetBuf);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// We are being given a content-type hint.
|
||||||
|
PRBool dummy;
|
||||||
|
net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
|
||||||
|
&dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetContentCharset(nsACString& aContentCharset)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
aContentCharset = mResponseHead->ContentCharset();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetContentCharset(const nsACString& aContentCharset)
|
||||||
|
{
|
||||||
|
if (mListener) {
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
mResponseHead->SetContentCharset(aContentCharset);
|
||||||
|
} else {
|
||||||
|
// Charset hint
|
||||||
|
mContentCharsetHint = aContentCharset;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetContentLength(PRInt32 *aContentLength)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aContentLength);
|
||||||
|
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
// XXX truncates to 32 bit
|
||||||
|
*aContentLength = mResponseHead->ContentLength();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetContentLength(PRInt32 value)
|
||||||
|
{
|
||||||
|
NS_NOTYETIMPLEMENTED("nsHttpChannel::SetContentLength");
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::Open(nsIInputStream **aResult)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS);
|
||||||
|
return NS_ImplementChannelOpen(this, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// HttpBaseChannel::nsIHttpChannel
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetRequestMethod(nsACString& aMethod)
|
||||||
|
{
|
||||||
|
aMethod = mRequestHead.Method();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetRequestMethod(const nsACString& aMethod)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
const nsCString& flatMethod = PromiseFlatCString(aMethod);
|
||||||
|
|
||||||
|
// Method names are restricted to valid HTTP tokens.
|
||||||
|
if (!nsHttp::IsValidToken(flatMethod))
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
nsHttpAtom atom = nsHttp::ResolveAtom(flatMethod.get());
|
||||||
|
if (!atom)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
mRequestHead.SetMethod(atom);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetReferrer(nsIURI **referrer)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(referrer);
|
||||||
|
*referrer = mReferrer;
|
||||||
|
NS_IF_ADDREF(*referrer);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
// clear existing referrer, if any
|
||||||
|
mReferrer = nsnull;
|
||||||
|
mRequestHead.ClearHeader(nsHttp::Referer);
|
||||||
|
|
||||||
|
if (!referrer)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// check referrer blocking pref
|
||||||
|
PRUint32 referrerLevel;
|
||||||
|
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)
|
||||||
|
referrerLevel = 1; // user action
|
||||||
|
else
|
||||||
|
referrerLevel = 2; // inline content
|
||||||
|
if (gHttpHandler->ReferrerLevel() < referrerLevel)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> referrerGrip;
|
||||||
|
nsresult rv;
|
||||||
|
PRBool match;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Strip off "wyciwyg://123/" from wyciwyg referrers.
|
||||||
|
//
|
||||||
|
// XXX this really belongs elsewhere since wyciwyg URLs aren't part of necko.
|
||||||
|
// perhaps some sort of generic nsINestedURI could be used. then, if an URI
|
||||||
|
// fails the whitelist test, then we could check for an inner URI and try
|
||||||
|
// that instead. though, that might be too automatic.
|
||||||
|
//
|
||||||
|
rv = referrer->SchemeIs("wyciwyg", &match);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
if (match) {
|
||||||
|
nsCAutoString path;
|
||||||
|
rv = referrer->GetPath(path);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
PRUint32 pathLength = path.Length();
|
||||||
|
if (pathLength <= 2) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Path is of the form "//123/http://foo/bar", with a variable number of digits.
|
||||||
|
// To figure out where the "real" URL starts, search path for a '/', starting at
|
||||||
|
// the third character.
|
||||||
|
PRInt32 slashIndex = path.FindChar('/', 2);
|
||||||
|
if (slashIndex == kNotFound) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Get the charset of the original URI so we can pass it to our fixed up URI.
|
||||||
|
nsCAutoString charset;
|
||||||
|
referrer->GetOriginCharset(charset);
|
||||||
|
|
||||||
|
// Replace |referrer| with a URI without wyciwyg://123/.
|
||||||
|
rv = NS_NewURI(getter_AddRefs(referrerGrip),
|
||||||
|
Substring(path, slashIndex + 1, pathLength - slashIndex - 1),
|
||||||
|
charset.get());
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
referrer = referrerGrip.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// block referrer if not on our white list...
|
||||||
|
//
|
||||||
|
static const char *const referrerWhiteList[] = {
|
||||||
|
"http",
|
||||||
|
"https",
|
||||||
|
"ftp",
|
||||||
|
"gopher",
|
||||||
|
nsnull
|
||||||
|
};
|
||||||
|
match = PR_FALSE;
|
||||||
|
const char *const *scheme = referrerWhiteList;
|
||||||
|
for (; *scheme && !match; ++scheme) {
|
||||||
|
rv = referrer->SchemeIs(*scheme, &match);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
|
return NS_OK; // kick out....
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle secure referrals.
|
||||||
|
//
|
||||||
|
// Support referrals from a secure server if this is a secure site
|
||||||
|
// and (optionally) if the host names are the same.
|
||||||
|
//
|
||||||
|
rv = referrer->SchemeIs("https", &match);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
if (match) {
|
||||||
|
rv = mURI->SchemeIs("https", &match);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
if (!match)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (!gHttpHandler->SendSecureXSiteReferrer()) {
|
||||||
|
nsCAutoString referrerHost;
|
||||||
|
nsCAutoString host;
|
||||||
|
|
||||||
|
rv = referrer->GetAsciiHost(referrerHost);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = mURI->GetAsciiHost(host);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// GetAsciiHost returns lowercase hostname.
|
||||||
|
if (!referrerHost.Equals(host))
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> clone;
|
||||||
|
//
|
||||||
|
// we need to clone the referrer, so we can:
|
||||||
|
// (1) modify it
|
||||||
|
// (2) keep a reference to it after returning from this function
|
||||||
|
//
|
||||||
|
rv = referrer->Clone(getter_AddRefs(clone));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// strip away any userpass; we don't want to be giving out passwords ;-)
|
||||||
|
clone->SetUserPass(EmptyCString());
|
||||||
|
|
||||||
|
// strip away any fragment per RFC 2616 section 14.36
|
||||||
|
nsCOMPtr<nsIURL> url = do_QueryInterface(clone);
|
||||||
|
if (url)
|
||||||
|
url->SetRef(EmptyCString());
|
||||||
|
|
||||||
|
nsCAutoString spec;
|
||||||
|
rv = clone->GetAsciiSpec(spec);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// finally, remember the referrer URI and set the Referer header.
|
||||||
|
mReferrer = clone;
|
||||||
|
mRequestHead.SetHeader(nsHttp::Referer, spec);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
|
||||||
|
nsACString& aValue)
|
||||||
|
{
|
||||||
|
// XXX might be better to search the header list directly instead of
|
||||||
|
// hitting the http atom hash table.
|
||||||
|
nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
|
||||||
|
if (!atom)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
return mRequestHead.GetHeader(atom, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue,
|
||||||
|
PRBool aMerge)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
const nsCString &flatHeader = PromiseFlatCString(aHeader);
|
||||||
|
const nsCString &flatValue = PromiseFlatCString(aValue);
|
||||||
|
|
||||||
|
LOG(("HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||||
|
this, flatHeader.get(), flatValue.get(), aMerge));
|
||||||
|
|
||||||
|
// Header names are restricted to valid HTTP tokens.
|
||||||
|
if (!nsHttp::IsValidToken(flatHeader))
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
||||||
|
// permits CTL characters, including CR and LF, in header values provided
|
||||||
|
// they are quoted. However, this can lead to problems if servers do not
|
||||||
|
// interpret quoted strings properly. Disallowing CR and LF here seems
|
||||||
|
// reasonable and keeps things simple. We also disallow a null byte.
|
||||||
|
if (flatValue.FindCharInSet("\r\n") != kNotFound ||
|
||||||
|
flatValue.Length() != strlen(flatValue.get()))
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
|
nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get());
|
||||||
|
if (!atom) {
|
||||||
|
NS_WARNING("failed to resolve atom");
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mRequestHead.SetHeader(atom, flatValue, aMerge);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *visitor)
|
||||||
|
{
|
||||||
|
return mRequestHead.Headers().VisitHeaders(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
||||||
|
if (!atom)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
return mResponseHead->GetHeader(atom, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetResponseHeader(const nsACString& header,
|
||||||
|
const nsACString& value,
|
||||||
|
PRBool merge)
|
||||||
|
{
|
||||||
|
LOG(("HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||||
|
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get(), merge));
|
||||||
|
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
||||||
|
if (!atom)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
// these response headers must not be changed
|
||||||
|
if (atom == nsHttp::Content_Type ||
|
||||||
|
atom == nsHttp::Content_Length ||
|
||||||
|
atom == nsHttp::Content_Encoding ||
|
||||||
|
atom == nsHttp::Trailer ||
|
||||||
|
atom == nsHttp::Transfer_Encoding)
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
|
||||||
|
mResponseHeadersModified = PR_TRUE;
|
||||||
|
|
||||||
|
return mResponseHead->SetHeader(atom, value, merge);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *visitor)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
return mResponseHead->Headers().VisitHeaders(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetAllowPipelining(PRBool *value)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(value);
|
||||||
|
*value = mAllowPipelining;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetAllowPipelining(PRBool value)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
mAllowPipelining = value;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetRedirectionLimit(PRUint32 *value)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(value);
|
||||||
|
*value = mRedirectionLimit;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetRedirectionLimit(PRUint32 value)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
mRedirectionLimit = PR_MIN(value, 0xff);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::IsNoStoreResponse(PRBool *value)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
*value = mResponseHead->NoStore();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::IsNoCacheResponse(PRBool *value)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
*value = mResponseHead->NoCache();
|
||||||
|
if (!*value)
|
||||||
|
*value = mResponseHead->ExpiresInPast();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetResponseStatus(PRUint32 *aValue)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
*aValue = mResponseHead->Status();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetResponseStatusText(nsACString& aValue)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
aValue = mResponseHead->StatusText();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetRequestSucceeded(PRBool *aValue)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
PRUint32 status = mResponseHead->Status();
|
||||||
|
*aValue = (status / 100 == 2);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// HttpBaseChannel::nsIHttpChannelInternal
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetDocumentURI(nsIURI **aDocumentURI)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aDocumentURI);
|
||||||
|
*aDocumentURI = mDocumentURI;
|
||||||
|
NS_IF_ADDREF(*aDocumentURI);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetDocumentURI(nsIURI *aDocumentURI)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
mDocumentURI = aDocumentURI;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetRequestVersion(PRUint32 *major, PRUint32 *minor)
|
||||||
|
{
|
||||||
|
nsHttpVersion version = mRequestHead.Version();
|
||||||
|
|
||||||
|
if (major) { *major = version / 10; }
|
||||||
|
if (minor) { *minor = version % 10; }
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetResponseVersion(PRUint32 *major, PRUint32 *minor)
|
||||||
|
{
|
||||||
|
if (!mResponseHead)
|
||||||
|
{
|
||||||
|
*major = *minor = 0; // we should at least be kind about it
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsHttpVersion version = mResponseHead->Version();
|
||||||
|
|
||||||
|
if (major) { *major = version / 10; }
|
||||||
|
if (minor) { *minor = version % 10; }
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetCookie(const char *aCookieHeader)
|
||||||
|
{
|
||||||
|
if (mLoadFlags & LOAD_ANONYMOUS)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// empty header isn't an error
|
||||||
|
if (!(aCookieHeader && *aCookieHeader))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsICookieService *cs = gHttpHandler->GetCookieService();
|
||||||
|
NS_ENSURE_TRUE(cs, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
return cs->SetCookieStringFromHttp(mURI,
|
||||||
|
nsnull,
|
||||||
|
nsnull,
|
||||||
|
aCookieHeader,
|
||||||
|
mResponseHead->PeekHeader(nsHttp::Date),
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetForceAllowThirdPartyCookie(PRBool *aForce)
|
||||||
|
{
|
||||||
|
*aForce = mForceAllowThirdPartyCookie;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetForceAllowThirdPartyCookie(PRBool aForce)
|
||||||
|
{
|
||||||
|
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||||
|
|
||||||
|
mForceAllowThirdPartyCookie = aForce;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
186
netwerk/protocol/http/src/HttpBaseChannel.h
Normal file
186
netwerk/protocol/http/src/HttpBaseChannel.h
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||||
|
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* The Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Daniel Witte <dwitte@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef mozilla_net_HttpBaseChannel_h
|
||||||
|
#define mozilla_net_HttpBaseChannel_h
|
||||||
|
|
||||||
|
#include "nsHttp.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsHashPropertyBag.h"
|
||||||
|
#include "nsProxyInfo.h"
|
||||||
|
#include "nsHttpRequestHead.h"
|
||||||
|
#include "nsHttpResponseHead.h"
|
||||||
|
#include "nsHttpConnectionInfo.h"
|
||||||
|
#include "nsIHttpChannel.h"
|
||||||
|
#include "nsIHttpChannelInternal.h"
|
||||||
|
#include "nsIProgressEventSink.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
|
||||||
|
#define DIE_WITH_ASYNC_OPEN_MSG() \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"*&*&*&*&*&*&*&**&*&&*& FATAL ERROR: '%s' " \
|
||||||
|
"called after AsyncOpen: %s +%d", \
|
||||||
|
__FUNCTION__, __FILE__, __LINE__); \
|
||||||
|
NS_ABORT(); \
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ENSURE_CALLED_BEFORE_ASYNC_OPEN() \
|
||||||
|
if (mIsPending) \
|
||||||
|
DIE_WITH_ASYNC_OPEN_MSG(); \
|
||||||
|
if (mWasOpened) \
|
||||||
|
DIE_WITH_ASYNC_OPEN_MSG(); \
|
||||||
|
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); \
|
||||||
|
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class is a partial implementation of nsIHttpChannel. It contains code
|
||||||
|
* shared by nsHttpChannel and HttpChannelChild.
|
||||||
|
* - Note that this class has nothing to do with nsBaseChannel, which is an
|
||||||
|
* earlier effort at a base class for channels that somehow never made it all
|
||||||
|
* the way to the HTTP channel.
|
||||||
|
*/
|
||||||
|
class HttpBaseChannel : public nsHashPropertyBag
|
||||||
|
, public nsIHttpChannel
|
||||||
|
, public nsIHttpChannelInternal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
HttpBaseChannel();
|
||||||
|
virtual ~HttpBaseChannel();
|
||||||
|
|
||||||
|
nsresult Init(nsIURI *aURI, PRUint8 aCaps, nsProxyInfo *aProxyInfo);
|
||||||
|
|
||||||
|
// nsIRequest
|
||||||
|
NS_IMETHOD GetName(nsACString& aName);
|
||||||
|
NS_IMETHOD IsPending(PRBool *aIsPending);
|
||||||
|
NS_IMETHOD GetStatus(nsresult *aStatus);
|
||||||
|
NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup);
|
||||||
|
NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
|
||||||
|
NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags);
|
||||||
|
NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags);
|
||||||
|
|
||||||
|
// nsIChannel
|
||||||
|
NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI);
|
||||||
|
NS_IMETHOD SetOriginalURI(nsIURI *aOriginalURI);
|
||||||
|
NS_IMETHOD GetURI(nsIURI **aURI);
|
||||||
|
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks);
|
||||||
|
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
|
||||||
|
NS_IMETHOD GetContentType(nsACString& aContentType);
|
||||||
|
NS_IMETHOD SetContentType(const nsACString& aContentType);
|
||||||
|
NS_IMETHOD GetContentCharset(nsACString& aContentCharset);
|
||||||
|
NS_IMETHOD SetContentCharset(const nsACString& aContentCharset);
|
||||||
|
NS_IMETHOD GetContentLength(PRInt32 *aContentLength);
|
||||||
|
NS_IMETHOD SetContentLength(PRInt32 aContentLength);
|
||||||
|
NS_IMETHOD Open(nsIInputStream **aResult);
|
||||||
|
|
||||||
|
// HttpBaseChannel::nsIHttpChannel
|
||||||
|
NS_IMETHOD GetRequestMethod(nsACString& aMethod);
|
||||||
|
NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
|
||||||
|
NS_IMETHOD GetReferrer(nsIURI **referrer);
|
||||||
|
NS_IMETHOD SetReferrer(nsIURI *referrer);
|
||||||
|
NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
|
||||||
|
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue, PRBool aMerge);
|
||||||
|
NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor);
|
||||||
|
NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value);
|
||||||
|
NS_IMETHOD SetResponseHeader(const nsACString& header,
|
||||||
|
const nsACString& value, PRBool merge);
|
||||||
|
NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor);
|
||||||
|
NS_IMETHOD GetAllowPipelining(PRBool *value);
|
||||||
|
NS_IMETHOD SetAllowPipelining(PRBool value);
|
||||||
|
NS_IMETHOD GetRedirectionLimit(PRUint32 *value);
|
||||||
|
NS_IMETHOD SetRedirectionLimit(PRUint32 value);
|
||||||
|
NS_IMETHOD IsNoStoreResponse(PRBool *value);
|
||||||
|
NS_IMETHOD IsNoCacheResponse(PRBool *value);
|
||||||
|
NS_IMETHOD GetResponseStatus(PRUint32 *aValue);
|
||||||
|
NS_IMETHOD GetResponseStatusText(nsACString& aValue);
|
||||||
|
NS_IMETHOD GetRequestSucceeded(PRBool *aValue);
|
||||||
|
|
||||||
|
// nsIHttpChannelInternal
|
||||||
|
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI);
|
||||||
|
NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI);
|
||||||
|
NS_IMETHOD GetRequestVersion(PRUint32 *major, PRUint32 *minor);
|
||||||
|
NS_IMETHOD GetResponseVersion(PRUint32 *major, PRUint32 *minor);
|
||||||
|
NS_IMETHOD SetCookie(const char *aCookieHeader);
|
||||||
|
NS_IMETHOD GetForceAllowThirdPartyCookie(PRBool *aForce);
|
||||||
|
NS_IMETHOD SetForceAllowThirdPartyCookie(PRBool aForce);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIURI> mURI;
|
||||||
|
nsCOMPtr<nsIURI> mOriginalURI;
|
||||||
|
nsCOMPtr<nsIURI> mDocumentURI;
|
||||||
|
nsCOMPtr<nsIStreamListener> mListener;
|
||||||
|
nsCOMPtr<nsISupports> mListenerContext;
|
||||||
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||||
|
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||||
|
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||||
|
nsCOMPtr<nsIURI> mReferrer;
|
||||||
|
|
||||||
|
nsHttpRequestHead mRequestHead;
|
||||||
|
nsAutoPtr<nsHttpResponseHead> mResponseHead;
|
||||||
|
nsRefPtr<nsHttpConnectionInfo> mConnectionInfo;
|
||||||
|
|
||||||
|
nsCString mSpec; // ASCII encoded URL spec
|
||||||
|
nsCString mContentTypeHint;
|
||||||
|
nsCString mContentCharsetHint;
|
||||||
|
|
||||||
|
nsresult mStatus;
|
||||||
|
PRUint32 mLoadFlags;
|
||||||
|
PRUint8 mCaps;
|
||||||
|
PRUint8 mRedirectionLimit;
|
||||||
|
|
||||||
|
PRUint8 mIsPending : 1;
|
||||||
|
PRUint8 mWasOpened : 1;
|
||||||
|
PRUint8 mResponseHeadersModified : 1;
|
||||||
|
PRUint8 mAllowPipelining : 1;
|
||||||
|
PRUint8 mForceAllowThirdPartyCookie : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace net
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_net_HttpBaseChannel_h
|
@ -23,6 +23,7 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Jason Duell <jduell.mcbugs@gmail.com>
|
* Jason Duell <jduell.mcbugs@gmail.com>
|
||||||
|
* Daniel Witte <dwitte@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@ -47,146 +48,27 @@
|
|||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
// - TODO: Can we add these checks to nsHttpChannel.cpp too?
|
|
||||||
#define ENSURE_CALLED_BEFORE_ASYNC_OPEN() \
|
|
||||||
if (mIsPending) \
|
|
||||||
DROP_DEAD(); \
|
|
||||||
if (mWasOpened) \
|
|
||||||
DROP_DEAD(); \
|
|
||||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); \
|
|
||||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
|
||||||
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
// C++ file contents
|
// C++ file contents
|
||||||
HttpChannelChild::HttpChannelChild()
|
HttpChannelChild::HttpChannelChild()
|
||||||
: mState(HCC_NEW)
|
: mState(HCC_NEW)
|
||||||
// FIELDS COPIED FROM nsHttpChannel.h
|
|
||||||
, mLoadFlags(LOAD_NORMAL)
|
|
||||||
, mStatus(NS_OK)
|
|
||||||
, mIsPending(PR_FALSE)
|
|
||||||
, mWasOpened(PR_FALSE)
|
|
||||||
{
|
{
|
||||||
LOG(("Creating HttpChannelChild @%x\n", this));
|
LOG(("Creating HttpChannelChild @%x\n", this));
|
||||||
|
|
||||||
// grab a reference to the handler to ensure that it doesn't go away.
|
|
||||||
NS_ADDREF(gHttpHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpChannelChild::~HttpChannelChild()
|
HttpChannelChild::~HttpChannelChild()
|
||||||
{
|
{
|
||||||
LOG(("Destroying HttpChannelChild @%x\n", this));
|
LOG(("Destroying HttpChannelChild @%x\n", this));
|
||||||
|
|
||||||
// release our reference to the handler
|
|
||||||
NS_RELEASE(gHttpHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::Init(nsIURI *uri)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel and tweaked: merge into base class?
|
|
||||||
*/
|
|
||||||
LOG(("HttpChannelChild::Init [this=%x]\n", this));
|
|
||||||
|
|
||||||
NS_PRECONDITION(uri, "null uri");
|
|
||||||
|
|
||||||
nsresult rv = nsHashPropertyBag::Init();
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
mURI = uri;
|
|
||||||
mOriginalURI = uri;
|
|
||||||
mDocumentURI = nsnull;
|
|
||||||
// mCaps = caps;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Construct connection info object
|
|
||||||
//
|
|
||||||
nsCAutoString host;
|
|
||||||
PRInt32 port = -1;
|
|
||||||
PRBool usingSSL = PR_FALSE;
|
|
||||||
|
|
||||||
rv = mURI->SchemeIs("https", &usingSSL);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = mURI->GetAsciiHost(host);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// reject the URL if it doesn't specify a host
|
|
||||||
if (host.IsEmpty())
|
|
||||||
return NS_ERROR_MALFORMED_URI;
|
|
||||||
|
|
||||||
rv = mURI->GetPort(&port);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
LOG(("host=%s port=%d\n", host.get(), port));
|
|
||||||
|
|
||||||
rv = mURI->GetAsciiSpec(mSpec);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
LOG(("uri=%s\n", mSpec.get()));
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Not yet clear that we need this in child
|
|
||||||
mConnectionInfo = new nsHttpConnectionInfo(host, port,
|
|
||||||
proxyInfo, usingSSL);
|
|
||||||
if (!mConnectionInfo)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
NS_ADDREF(mConnectionInfo);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set default request method
|
|
||||||
mRequestHead.SetMethod(nsHttp::Get);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// FIXME (bug 541017): split this out into a separate function so we can share
|
|
||||||
// with nsHttpChannel.
|
|
||||||
// - Make sure not to set any headers twice on parent.
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set request headers
|
|
||||||
//
|
|
||||||
nsCAutoString hostLine;
|
|
||||||
if (strchr(host.get(), ':')) {
|
|
||||||
// host is an IPv6 address literal and must be encapsulated in []'s
|
|
||||||
hostLine.Assign('[');
|
|
||||||
// scope id is not needed for Host header.
|
|
||||||
int scopeIdPos = host.FindChar('%');
|
|
||||||
if (scopeIdPos == kNotFound)
|
|
||||||
hostLine.Append(host);
|
|
||||||
else if (scopeIdPos > 0)
|
|
||||||
hostLine.Append(Substring(host, 0, scopeIdPos));
|
|
||||||
else
|
|
||||||
return NS_ERROR_MALFORMED_URI;
|
|
||||||
hostLine.Append(']');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hostLine.Assign(host);
|
|
||||||
if (port != -1) {
|
|
||||||
hostLine.Append(':');
|
|
||||||
hostLine.AppendInt(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = gHttpHandler->
|
|
||||||
AddStandardRequestHeaders(&mRequestHead.Headers(), caps,
|
|
||||||
!mConnectionInfo->UsingSSL() &&
|
|
||||||
mConnectionInfo->UsingHttpProxy());
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HttpChannelChild::nsISupports
|
// HttpChannelChild::nsISupports
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(HttpChannelChild, nsHashPropertyBag)
|
NS_IMPL_ADDREF_INHERITED(HttpChannelChild, HttpBaseChannel)
|
||||||
NS_IMPL_RELEASE_INHERITED(HttpChannelChild, nsHashPropertyBag)
|
NS_IMPL_RELEASE_INHERITED(HttpChannelChild, HttpBaseChannel)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
|
NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||||
@ -203,7 +85,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
|
|||||||
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
|
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
|
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
|
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
|
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HttpChannelChild::PHttpChannelChild
|
// HttpChannelChild::PHttpChannelChild
|
||||||
@ -218,7 +100,7 @@ HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead)
|
|||||||
|
|
||||||
mResponseHead = new nsHttpResponseHead(responseHead);
|
mResponseHead = new nsHttpResponseHead(responseHead);
|
||||||
|
|
||||||
nsresult rv = mChildListener->OnStartRequest(this, mChildListenerContext);
|
nsresult rv = mListener->OnStartRequest(this, mListenerContext);
|
||||||
if (!NS_SUCCEEDED(rv)) {
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
// TODO: Cancel request:
|
// TODO: Cancel request:
|
||||||
// - Send Cancel msg to parent
|
// - Send Cancel msg to parent
|
||||||
@ -253,8 +135,8 @@ HttpChannelChild::RecvOnDataAvailable(const nsCString& data,
|
|||||||
// TODO: what to do here? Cancel request? Very unlikely to fail.
|
// TODO: what to do here? Cancel request? Very unlikely to fail.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rv = mChildListener->OnDataAvailable(this, mChildListenerContext,
|
rv = mListener->OnDataAvailable(this, mListenerContext,
|
||||||
stringStream, offset, count);
|
stringStream, offset, count);
|
||||||
stringStream->Close();
|
stringStream->Close();
|
||||||
if (!NS_SUCCEEDED(rv)) {
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
// TODO: Cancel request: see notes in OnStartRequest
|
// TODO: Cancel request: see notes in OnStartRequest
|
||||||
@ -273,10 +155,9 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
|||||||
|
|
||||||
mIsPending = PR_FALSE;
|
mIsPending = PR_FALSE;
|
||||||
mStatus = statusCode;
|
mStatus = statusCode;
|
||||||
nsresult rv = mChildListener->OnStopRequest(this, mChildListenerContext,
|
nsresult rv = mListener->OnStopRequest(this, mListenerContext, statusCode);
|
||||||
statusCode);
|
mListener = 0;
|
||||||
mChildListener = 0;
|
mListenerContext = 0;
|
||||||
mChildListenerContext = 0;
|
|
||||||
if (!NS_SUCCEEDED(rv)) {
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
// TODO: Cancel request: see notes in OnStartRequest
|
// TODO: Cancel request: see notes in OnStartRequest
|
||||||
return false;
|
return false;
|
||||||
@ -289,35 +170,7 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::GetName(nsACString& aName)
|
HttpChannelChild::Cancel(nsresult status)
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::IsPending(PRBool *retval)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(retval);
|
|
||||||
*retval = mIsPending;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetStatus(nsresult *aStatus)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(aStatus);
|
|
||||||
*aStatus = mStatus;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::Cancel(nsresult aStatus)
|
|
||||||
{
|
{
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
@ -334,211 +187,27 @@ HttpChannelChild::Resume()
|
|||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetLoadGroup(nsILoadGroup **aLoadGroup)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetLoadFlags(nsLoadFlags *aLoadFlags)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(aLoadFlags);
|
|
||||||
*aLoadFlags = mLoadFlags;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetLoadFlags(nsLoadFlags aLoadFlags)
|
|
||||||
{
|
|
||||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
mLoadFlags = aLoadFlags;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HttpChannelChild::nsIChannel
|
// HttpChannelChild::nsIChannel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetOriginalURI(nsIURI **originalURI)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(originalURI);
|
|
||||||
*originalURI = mOriginalURI;
|
|
||||||
NS_ADDREF(*originalURI);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetOriginalURI(nsIURI *originalURI)
|
|
||||||
{
|
|
||||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(originalURI);
|
|
||||||
mOriginalURI = originalURI;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetURI(nsIURI **URI)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(URI);
|
|
||||||
*URI = mURI;
|
|
||||||
NS_IF_ADDREF(*URI);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::GetOwner(nsISupports **aOwner)
|
HttpChannelChild::GetOwner(nsISupports **aOwner)
|
||||||
{
|
{
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::SetOwner(nsISupports *aOwner)
|
HttpChannelChild::SetOwner(nsISupports *aOwner)
|
||||||
{
|
{
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetNotificationCallbacks(nsIInterfaceRequestor **callbacks)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_IF_ADDREF(*callbacks = mCallbacks);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetNotificationCallbacks(nsIInterfaceRequestor *callbacks)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
mCallbacks = callbacks;
|
|
||||||
mProgressSink = nsnull;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
|
HttpChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
|
||||||
{
|
{
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetContentType(nsACString& value)
|
|
||||||
{
|
|
||||||
if (!mResponseHead) {
|
|
||||||
value.Truncate();
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
if (mResponseHead->ContentType().IsEmpty()) {
|
|
||||||
value.AssignLiteral(UNKNOWN_CONTENT_TYPE);
|
|
||||||
} else {
|
|
||||||
value = mResponseHead->ContentType();
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetContentType(const nsACString& aContentType)
|
|
||||||
{
|
|
||||||
return BaseClassSetContentType_HACK(aContentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassSetContentType_HACK(const nsACString &value)
|
|
||||||
{
|
|
||||||
if (mChildListener || mWasOpened) {
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
nsCAutoString contentTypeBuf, charsetBuf;
|
|
||||||
PRBool hadCharset;
|
|
||||||
net_ParseContentType(value, contentTypeBuf, charsetBuf, &hadCharset);
|
|
||||||
|
|
||||||
mResponseHead->SetContentType(contentTypeBuf);
|
|
||||||
|
|
||||||
// take care not to stomp on an existing charset
|
|
||||||
if (hadCharset)
|
|
||||||
mResponseHead->SetContentCharset(charsetBuf);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetContentCharset(nsACString& aContentCharset)
|
|
||||||
{
|
|
||||||
return BaseClassGetContentCharset_HACK(aContentCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassGetContentCharset_HACK(nsACString &value)
|
|
||||||
{
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
value = mResponseHead->ContentCharset();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetContentCharset(const nsACString& aContentCharset)
|
|
||||||
{
|
|
||||||
return BaseClassSetContentCharset_HACK(aContentCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassSetContentCharset_HACK(const nsACString &value)
|
|
||||||
{
|
|
||||||
if (mChildListener) {
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
mResponseHead->SetContentCharset(value);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetContentLength(PRInt32 *aContentLength)
|
|
||||||
{
|
|
||||||
*aContentLength = mResponseHead->ContentLength();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetContentLength(PRInt32 aContentLength)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::Open(nsIInputStream **retval)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS);
|
|
||||||
return NS_ImplementChannelOpen(this, retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
||||||
{
|
{
|
||||||
@ -564,8 +233,14 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||||||
// TODO: currently means "this" has been deleted! bug 529693
|
// TODO: currently means "this" has been deleted! bug 529693
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
mChildListener = listener;
|
mListener = listener;
|
||||||
mChildListenerContext = aContext;
|
mListenerContext = aContext;
|
||||||
|
|
||||||
|
// TODO: serialize mConnectionInfo across to the parent, and set it on
|
||||||
|
// the new channel somehow?
|
||||||
|
|
||||||
|
// TODO: serialize mCaps across to the parent, and set it on
|
||||||
|
// the new channel somehow?
|
||||||
|
|
||||||
// TODO: need to dupe cookies logic from nsHttpChannel.cpp?
|
// TODO: need to dupe cookies logic from nsHttpChannel.cpp?
|
||||||
|
|
||||||
@ -589,11 +264,13 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!SendAsyncOpen(mSpec, charset, originalSpec, originalCharset,
|
if (!SendAsyncOpen(mSpec, charset, originalSpec, originalCharset,
|
||||||
docSpec, docCharset, mLoadFlags, mRequestHeaders)) {
|
docSpec, docCharset, mLoadFlags, mRequestHeaders,
|
||||||
|
mRequestHead.Method(), mRedirectionLimit, mAllowPipelining,
|
||||||
|
mForceAllowThirdPartyCookie)) {
|
||||||
// IPDL error: our destructor will be called automatically
|
// IPDL error: our destructor will be called automatically
|
||||||
// -- TODO: verify that that's the case :)
|
// -- TODO: verify that that's the case :)
|
||||||
mChildListener = 0;
|
mListener = 0;
|
||||||
mChildListenerContext = 0;
|
mListenerContext = 0;
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,77 +285,12 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||||||
// HttpChannelChild::nsIHttpChannel
|
// HttpChannelChild::nsIHttpChannel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetRequestMethod(nsACString& method)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
method = mRequestHead.Method();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetRequestMethod(const nsACString& method)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
* - TODO: pass along to parent in AsyncOpen
|
|
||||||
*/
|
|
||||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
|
||||||
|
|
||||||
const nsCString& flatMethod = PromiseFlatCString(method);
|
|
||||||
|
|
||||||
// Method names are restricted to valid HTTP tokens.
|
|
||||||
if (!nsHttp::IsValidToken(flatMethod))
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(flatMethod.get());
|
|
||||||
if (!atom)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
mRequestHead.SetMethod(atom);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetReferrer(nsIURI **aReferrer)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetReferrer(nsIURI *aReferrer)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetRequestHeader(const nsACString& hdr, nsACString& val)
|
|
||||||
{
|
|
||||||
return BaseClassGetRequestHeader_HACK(hdr, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassGetRequestHeader_HACK(const nsACString &header,
|
|
||||||
nsACString &value)
|
|
||||||
{
|
|
||||||
// XXX might be better to search the header list directly instead of
|
|
||||||
// hitting the http atom hash table.
|
|
||||||
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
|
||||||
if (!atom)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
return mRequestHead.GetHeader(atom, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
||||||
const nsACString& aValue,
|
const nsACString& aValue,
|
||||||
PRBool aMerge)
|
PRBool aMerge)
|
||||||
{
|
{
|
||||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
nsresult rv = HttpBaseChannel::SetRequestHeader(aHeader, aValue, aMerge);
|
||||||
|
|
||||||
nsresult rv = BaseClassSetRequestHeader_HACK(aHeader, aValue, aMerge);
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
@ -692,229 +304,16 @@ HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassSetRequestHeader_HACK(const nsACString &header,
|
|
||||||
const nsACString &value,
|
|
||||||
PRBool merge)
|
|
||||||
{
|
|
||||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
|
||||||
|
|
||||||
const nsCString &flatHeader = PromiseFlatCString(header);
|
|
||||||
const nsCString &flatValue = PromiseFlatCString(value);
|
|
||||||
|
|
||||||
LOG(("nsHttpChannel::SetRequestHeader [this=%x header=\"%s\" value=\"%s\" merge=%u]\n",
|
|
||||||
this, flatHeader.get(), flatValue.get(), merge));
|
|
||||||
|
|
||||||
// Header names are restricted to valid HTTP tokens.
|
|
||||||
if (!nsHttp::IsValidToken(flatHeader))
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
|
||||||
// permits CTL characters, including CR and LF, in header values provided
|
|
||||||
// they are quoted. However, this can lead to problems if servers do not
|
|
||||||
// interpret quoted strings properly. Disallowing CR and LF here seems
|
|
||||||
// reasonable and keeps things simple. We also disallow a null byte.
|
|
||||||
if (flatValue.FindCharInSet("\r\n") != kNotFound ||
|
|
||||||
flatValue.Length() != strlen(flatValue.get()))
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get());
|
|
||||||
if (!atom) {
|
|
||||||
NS_WARNING("failed to resolve atom");
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mRequestHead.SetHeader(atom, flatValue, merge);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetAllowPipelining(PRBool *aAllowPipelining)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetAllowPipelining(PRBool aAllowPipelining)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetRedirectionLimit(PRUint32 *aRedirectionLimit)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetRedirectionLimit(PRUint32 aRedirectionLimit)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetResponseStatus(PRUint32 *value)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(value);
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
*value = mResponseHead->Status();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetResponseStatusText(nsACString& value)
|
|
||||||
{
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
value = mResponseHead->StatusText();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetRequestSucceeded(PRBool *value)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(value, "Don't ever pass a null arg to this function");
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
PRUint32 status = mResponseHead->Status();
|
|
||||||
*value = (status / 100 == 2);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetResponseHeader(const nsACString& header, nsACString& val)
|
|
||||||
{
|
|
||||||
return BaseClassGetResponseHeader_HACK(header, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassGetResponseHeader_HACK(const nsACString &header,
|
|
||||||
nsACString &value)
|
|
||||||
{
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
|
||||||
if (!atom)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
return mResponseHead->GetHeader(atom, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetResponseHeader(const nsACString& header,
|
|
||||||
const nsACString& value,
|
|
||||||
PRBool merge)
|
|
||||||
{
|
|
||||||
return BaseClassSetResponseHeader_HACK(header, value, merge);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HttpChannelChild::BaseClassSetResponseHeader_HACK(const nsACString &header,
|
|
||||||
const nsACString &value,
|
|
||||||
PRBool merge)
|
|
||||||
{
|
|
||||||
LOG(("nsHttpChannel::SetResponseHeader [this=%x header=\"%s\" value=\"%s\" merge=%u]\n",
|
|
||||||
this, PromiseFlatCString(header).get(), PromiseFlatCString(value).get(), merge));
|
|
||||||
|
|
||||||
if (!mResponseHead)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(header);
|
|
||||||
if (!atom)
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
|
|
||||||
// these response headers must not be changed
|
|
||||||
if (atom == nsHttp::Content_Type ||
|
|
||||||
atom == nsHttp::Content_Length ||
|
|
||||||
atom == nsHttp::Content_Encoding ||
|
|
||||||
atom == nsHttp::Trailer ||
|
|
||||||
atom == nsHttp::Transfer_Encoding)
|
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
|
||||||
|
|
||||||
return mResponseHead->SetHeader(atom, value, merge);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::IsNoStoreResponse(PRBool *retval)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::IsNoCacheResponse(PRBool *retval)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HttpChannelChild::nsIHttpChannelInternal
|
// HttpChannelChild::nsIHttpChannelInternal
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetDocumentURI(nsIURI **aDocumentURI)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
NS_ENSURE_ARG_POINTER(aDocumentURI);
|
|
||||||
*aDocumentURI = mDocumentURI;
|
|
||||||
NS_IF_ADDREF(*aDocumentURI);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetDocumentURI(nsIURI *aDocumentURI)
|
|
||||||
{
|
|
||||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
|
||||||
/**
|
|
||||||
* COPIED from nsHttpChannel.cpp: move to shared base class?
|
|
||||||
*/
|
|
||||||
mDocumentURI = aDocumentURI;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetRequestVersion(PRUint32 *major, PRUint32 *minor)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetResponseVersion(PRUint32 *major, PRUint32 *minor)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetCookie(const char *aCookieHeader)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
|
HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
|
||||||
{
|
{
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::GetForceAllowThirdPartyCookie(PRBool *force)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpChannelChild::SetForceAllowThirdPartyCookie(PRBool force)
|
|
||||||
{
|
|
||||||
DROP_DEAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HttpChannelChild::nsICachingChannel
|
// HttpChannelChild::nsICachingChannel
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Jason Duell <jduell.mcbugs@gmail.com>
|
* Jason Duell <jduell.mcbugs@gmail.com>
|
||||||
|
* Daniel Witte <dwitte@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@ -41,15 +42,10 @@
|
|||||||
#ifndef mozilla_net_HttpChannelChild_h
|
#ifndef mozilla_net_HttpChannelChild_h
|
||||||
#define mozilla_net_HttpChannelChild_h
|
#define mozilla_net_HttpChannelChild_h
|
||||||
|
|
||||||
|
#include "mozilla/net/HttpBaseChannel.h"
|
||||||
#include "mozilla/net/PHttpChannelChild.h"
|
#include "mozilla/net/PHttpChannelChild.h"
|
||||||
#include "mozilla/net/NeckoCommon.h"
|
|
||||||
|
|
||||||
#include "nsHttpRequestHead.h"
|
|
||||||
#include "nsHashPropertyBag.h"
|
|
||||||
#include "nsIHttpChannel.h"
|
|
||||||
#include "nsIHttpChannelInternal.h"
|
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
#include "nsIURI.h"
|
|
||||||
#include "nsILoadGroup.h"
|
#include "nsILoadGroup.h"
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
@ -65,7 +61,6 @@
|
|||||||
#include "nsIProxiedChannel.h"
|
#include "nsIProxiedChannel.h"
|
||||||
#include "nsITraceableChannel.h"
|
#include "nsITraceableChannel.h"
|
||||||
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
@ -80,9 +75,7 @@ enum HttpChannelChildState {
|
|||||||
|
|
||||||
// Header file contents
|
// Header file contents
|
||||||
class HttpChannelChild : public PHttpChannelChild
|
class HttpChannelChild : public PHttpChannelChild
|
||||||
, public nsIHttpChannel
|
, public HttpBaseChannel
|
||||||
, public nsHashPropertyBag
|
|
||||||
, public nsIHttpChannelInternal
|
|
||||||
, public nsICachingChannel
|
, public nsICachingChannel
|
||||||
, public nsIUploadChannel
|
, public nsIUploadChannel
|
||||||
, public nsIUploadChannel2
|
, public nsIUploadChannel2
|
||||||
@ -95,10 +88,6 @@ class HttpChannelChild : public PHttpChannelChild
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSIREQUEST
|
|
||||||
NS_DECL_NSICHANNEL
|
|
||||||
NS_DECL_NSIHTTPCHANNEL
|
|
||||||
NS_DECL_NSIHTTPCHANNELINTERNAL
|
|
||||||
NS_DECL_NSICACHINGCHANNEL
|
NS_DECL_NSICACHINGCHANNEL
|
||||||
NS_DECL_NSIUPLOADCHANNEL
|
NS_DECL_NSIUPLOADCHANNEL
|
||||||
NS_DECL_NSIUPLOADCHANNEL2
|
NS_DECL_NSIUPLOADCHANNEL2
|
||||||
@ -115,6 +104,24 @@ public:
|
|||||||
|
|
||||||
nsresult Init(nsIURI *uri);
|
nsresult Init(nsIURI *uri);
|
||||||
|
|
||||||
|
// Methods HttpBaseChannel didn't implement for us or that we override.
|
||||||
|
//
|
||||||
|
// nsIRequest
|
||||||
|
NS_IMETHOD Cancel(nsresult status);
|
||||||
|
NS_IMETHOD Suspend();
|
||||||
|
NS_IMETHOD Resume();
|
||||||
|
// nsIChannel
|
||||||
|
NS_IMETHOD GetOwner(nsISupports **aOwner);
|
||||||
|
NS_IMETHOD SetOwner(nsISupports *aOwner);
|
||||||
|
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
|
||||||
|
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
|
||||||
|
// HttpBaseChannel::nsIHttpChannel
|
||||||
|
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue,
|
||||||
|
PRBool aMerge);
|
||||||
|
// nsIHttpChannelInternal
|
||||||
|
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool RecvOnStartRequest(const nsHttpResponseHead& responseHead);
|
bool RecvOnStartRequest(const nsHttpResponseHead& responseHead);
|
||||||
bool RecvOnDataAvailable(const nsCString& data,
|
bool RecvOnDataAvailable(const nsCString& data,
|
||||||
@ -123,54 +130,12 @@ protected:
|
|||||||
bool RecvOnStopRequest(const nsresult& statusCode);
|
bool RecvOnStopRequest(const nsresult& statusCode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult BaseClassSetContentType_HACK(const nsACString &value);
|
RequestHeaderTuples mRequestHeaders;
|
||||||
nsresult BaseClassGetContentCharset_HACK(nsACString &value);
|
|
||||||
nsresult BaseClassSetContentCharset_HACK(const nsACString &value);
|
|
||||||
nsresult BaseClassSetRequestHeader_HACK(const nsACString &header,
|
|
||||||
const nsACString &value,
|
|
||||||
PRBool merge);
|
|
||||||
nsresult BaseClassGetRequestHeader_HACK(const nsACString &header,
|
|
||||||
nsACString &value);
|
|
||||||
nsresult BaseClassGetResponseHeader_HACK(const nsACString &header,
|
|
||||||
nsACString &value);
|
|
||||||
nsresult BaseClassSetResponseHeader_HACK(const nsACString &header,
|
|
||||||
const nsACString &value,
|
|
||||||
PRBool merge);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIStreamListener> mChildListener;
|
|
||||||
nsCOMPtr<nsISupports> mChildListenerContext;
|
|
||||||
|
|
||||||
RequestHeaderTuples mRequestHeaders;
|
|
||||||
|
|
||||||
nsAutoPtr<nsHttpResponseHead> mResponseHead;
|
|
||||||
|
|
||||||
// FIXME: replace with IPDL states (bug 536319)
|
// FIXME: replace with IPDL states (bug 536319)
|
||||||
enum HttpChannelChildState mState;
|
enum HttpChannelChildState mState;
|
||||||
|
|
||||||
/**
|
|
||||||
* fields copied from nsHttpChannel.h
|
|
||||||
*/
|
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
|
||||||
nsCOMPtr<nsIURI> mURI;
|
|
||||||
nsCOMPtr<nsIURI> mDocumentURI;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
|
||||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
|
||||||
|
|
||||||
nsHttpRequestHead mRequestHead;
|
|
||||||
|
|
||||||
nsCString mSpec; // ASCII encoded URL spec
|
|
||||||
|
|
||||||
PRUint32 mLoadFlags;
|
|
||||||
PRUint32 mStatus;
|
|
||||||
|
|
||||||
// state flags
|
|
||||||
PRUint32 mIsPending : 1;
|
|
||||||
PRUint32 mWasOpened : 1;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#include "nsHttp.h"
|
|
||||||
#include "mozilla/net/HttpChannelParent.h"
|
#include "mozilla/net/HttpChannelParent.h"
|
||||||
#include "nsHttpChannel.h"
|
#include "nsHttpChannel.h"
|
||||||
|
#include "nsHttpHandler.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -49,10 +49,15 @@ namespace net {
|
|||||||
// C++ file contents
|
// C++ file contents
|
||||||
HttpChannelParent::HttpChannelParent()
|
HttpChannelParent::HttpChannelParent()
|
||||||
{
|
{
|
||||||
|
// Ensure gHttpHandler is initialized: we need the atom table up and running.
|
||||||
|
nsIHttpProtocolHandler* handler;
|
||||||
|
CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &handler);
|
||||||
|
NS_ASSERTION(handler, "no http handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpChannelParent::~HttpChannelParent()
|
HttpChannelParent::~HttpChannelParent()
|
||||||
{
|
{
|
||||||
|
NS_RELEASE(gHttpHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -76,8 +81,15 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||||||
const nsCString& docUriSpec,
|
const nsCString& docUriSpec,
|
||||||
const nsCString& docCharset,
|
const nsCString& docCharset,
|
||||||
const PRUint32& loadFlags,
|
const PRUint32& loadFlags,
|
||||||
const RequestHeaderTuples& requestHeaders)
|
const RequestHeaderTuples& requestHeaders,
|
||||||
|
const nsHttpAtom& requestMethod,
|
||||||
|
const PRUint8& redirectionLimit,
|
||||||
|
const PRBool& allowPipelining,
|
||||||
|
const PRBool& forceAllowThirdPartyCookie)
|
||||||
{
|
{
|
||||||
|
LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s (%s)]\n",
|
||||||
|
this, uriSpec.get(), charset.get()));
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||||
@ -89,16 +101,14 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return false; // TODO: send fail msg to child, return true
|
return false; // TODO: send fail msg to child, return true
|
||||||
|
|
||||||
// Delay log to here, as gHttpLog may not exist in parent until we init
|
|
||||||
// gHttpHandler via above call to NS_NewURI. Avoids segfault :)
|
|
||||||
LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s (%s)]\n",
|
|
||||||
this, uriSpec.get(), charset.get()));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> chan;
|
nsCOMPtr<nsIChannel> chan;
|
||||||
rv = NS_NewChannel(getter_AddRefs(chan), uri, ios, nsnull, nsnull, loadFlags);
|
rv = NS_NewChannel(getter_AddRefs(chan), uri, ios, nsnull, nsnull, loadFlags);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return false; // TODO: send fail msg to child, return true
|
return false; // TODO: send fail msg to child, return true
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
|
||||||
|
nsCOMPtr<nsIHttpChannelInternal> httpChanInt(do_QueryInterface(chan));
|
||||||
|
|
||||||
if (!originalUriSpec.IsEmpty()) {
|
if (!originalUriSpec.IsEmpty()) {
|
||||||
nsCOMPtr<nsIURI> originalUri;
|
nsCOMPtr<nsIURI> originalUri;
|
||||||
rv = NS_NewURI(getter_AddRefs(originalUri), originalUriSpec,
|
rv = NS_NewURI(getter_AddRefs(originalUri), originalUriSpec,
|
||||||
@ -111,15 +121,12 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||||||
rv = NS_NewURI(getter_AddRefs(docUri), docUriSpec,
|
rv = NS_NewURI(getter_AddRefs(docUri), docUriSpec,
|
||||||
docCharset.get(), nsnull, ios);
|
docCharset.get(), nsnull, ios);
|
||||||
if (!NS_FAILED(rv)) {
|
if (!NS_FAILED(rv)) {
|
||||||
nsCOMPtr<nsIHttpChannelInternal> iChan(do_QueryInterface(chan));
|
httpChanInt->SetDocumentURI(docUri);
|
||||||
if (iChan)
|
|
||||||
iChan->SetDocumentURI(docUri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loadFlags != nsIRequest::LOAD_NORMAL)
|
if (loadFlags != nsIRequest::LOAD_NORMAL)
|
||||||
chan->SetLoadFlags(loadFlags);
|
chan->SetLoadFlags(loadFlags);
|
||||||
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
|
|
||||||
for (PRUint32 i = 0; i < requestHeaders.Length(); i++)
|
for (PRUint32 i = 0; i < requestHeaders.Length(); i++)
|
||||||
httpChan->SetRequestHeader(requestHeaders[i].mHeader,
|
httpChan->SetRequestHeader(requestHeaders[i].mHeader,
|
||||||
requestHeaders[i].mValue,
|
requestHeaders[i].mValue,
|
||||||
@ -129,6 +136,11 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||||||
// process, or rig up appropriate hacks.
|
// process, or rig up appropriate hacks.
|
||||||
// chan->SetNotificationCallbacks(this);
|
// chan->SetNotificationCallbacks(this);
|
||||||
|
|
||||||
|
httpChan->SetRequestMethod(nsDependentCString(requestMethod.get()));
|
||||||
|
httpChan->SetRedirectionLimit(redirectionLimit);
|
||||||
|
httpChan->SetAllowPipelining(allowPipelining);
|
||||||
|
httpChanInt->SetForceAllowThirdPartyCookie(forceAllowThirdPartyCookie);
|
||||||
|
|
||||||
rv = chan->AsyncOpen(this, nsnull);
|
rv = chan->AsyncOpen(this, nsnull);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return false; // TODO: send fail msg to child, return true
|
return false; // TODO: send fail msg to child, return true
|
||||||
|
@ -72,7 +72,11 @@ protected:
|
|||||||
const nsCString& docUriSpec,
|
const nsCString& docUriSpec,
|
||||||
const nsCString& docCharset,
|
const nsCString& docCharset,
|
||||||
const PRUint32& loadFlags,
|
const PRUint32& loadFlags,
|
||||||
const RequestHeaderTuples& requestHeaders);
|
const RequestHeaderTuples& requestHeaders,
|
||||||
|
const nsHttpAtom& requestMethod,
|
||||||
|
const PRUint8& redirectionLimit,
|
||||||
|
const PRBool& allowPipelining,
|
||||||
|
const PRBool& forceAllowThirdPartyCookie);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
@ -46,10 +46,14 @@ MODULE = necko
|
|||||||
LIBRARY_NAME = nkhttp_s
|
LIBRARY_NAME = nkhttp_s
|
||||||
LIBXUL_LIBRARY = 1
|
LIBXUL_LIBRARY = 1
|
||||||
|
|
||||||
ifdef MOZ_IPC
|
|
||||||
EXPORTS_NAMESPACES = mozilla/net
|
EXPORTS_NAMESPACES = mozilla/net
|
||||||
|
|
||||||
EXPORTS_mozilla/net = \
|
EXPORTS_mozilla/net = \
|
||||||
|
HttpBaseChannel.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
ifdef MOZ_IPC
|
||||||
|
EXPORTS_mozilla/net += \
|
||||||
HttpChannelParent.h \
|
HttpChannelParent.h \
|
||||||
HttpChannelChild.h \
|
HttpChannelChild.h \
|
||||||
PHttpChannelParams.h \
|
PHttpChannelParams.h \
|
||||||
@ -79,6 +83,7 @@ CPPSRCS = \
|
|||||||
nsHttpNTLMAuth.cpp \
|
nsHttpNTLMAuth.cpp \
|
||||||
nsHttpTransaction.cpp \
|
nsHttpTransaction.cpp \
|
||||||
nsHttpHandler.cpp \
|
nsHttpHandler.cpp \
|
||||||
|
HttpBaseChannel.cpp \
|
||||||
nsHttpChannel.cpp \
|
nsHttpChannel.cpp \
|
||||||
nsHttpPipeline.cpp \
|
nsHttpPipeline.cpp \
|
||||||
nsHttpActivityDistributor.cpp \
|
nsHttpActivityDistributor.cpp \
|
||||||
|
@ -44,6 +44,7 @@ include "mozilla/net/PHttpChannelParams.h";
|
|||||||
|
|
||||||
using RequestHeaderTuples;
|
using RequestHeaderTuples;
|
||||||
using nsHttpResponseHead;
|
using nsHttpResponseHead;
|
||||||
|
using nsHttpAtom;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -67,7 +68,11 @@ parent:
|
|||||||
nsCString docUriSpec,
|
nsCString docUriSpec,
|
||||||
nsCString docCharset,
|
nsCString docCharset,
|
||||||
PRUint32 loadFlags,
|
PRUint32 loadFlags,
|
||||||
RequestHeaderTuples requestHeaders);
|
RequestHeaderTuples requestHeaders,
|
||||||
|
nsHttpAtom requestMethod,
|
||||||
|
PRUint8 redirectionLimit,
|
||||||
|
PRBool allowPipelining,
|
||||||
|
PRBool forceAllowThirdPartyCookie);
|
||||||
|
|
||||||
child:
|
child:
|
||||||
OnStartRequest(nsHttpResponseHead responseHead);
|
OnStartRequest(nsHttpResponseHead responseHead);
|
||||||
|
@ -108,6 +108,7 @@ struct ParamTraits<nsHttpAtom>
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
*aResult = nsHttp::ResolveAtom(value.get());
|
*aResult = nsHttp::ResolveAtom(value.get());
|
||||||
|
NS_ASSERTION(aResult->get(), "atom table not initialized");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
|||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Darin Fisher <darin@netscape.com> (original author)
|
* Darin Fisher <darin@netscape.com> (original author)
|
||||||
* Christian Biesinger <cbiesinger@web.de>
|
* Christian Biesinger <cbiesinger@web.de>
|
||||||
|
* Daniel Witte <dwitte@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@ -41,43 +42,23 @@
|
|||||||
#ifndef nsHttpChannel_h__
|
#ifndef nsHttpChannel_h__
|
||||||
#define nsHttpChannel_h__
|
#define nsHttpChannel_h__
|
||||||
|
|
||||||
|
#include "HttpBaseChannel.h"
|
||||||
|
|
||||||
#include "nsHttpTransaction.h"
|
#include "nsHttpTransaction.h"
|
||||||
#include "nsHttpRequestHead.h"
|
|
||||||
#include "nsHttpAuthCache.h"
|
#include "nsHttpAuthCache.h"
|
||||||
#include "nsHashPropertyBag.h"
|
|
||||||
#include "nsInputStreamPump.h"
|
#include "nsInputStreamPump.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsInt64.h"
|
|
||||||
|
|
||||||
#include "nsIHttpChannel.h"
|
|
||||||
#include "nsIHttpChannelInternal.h"
|
|
||||||
#include "nsIHttpHeaderVisitor.h"
|
|
||||||
#include "nsIHttpEventSink.h"
|
#include "nsIHttpEventSink.h"
|
||||||
#include "nsIChannelEventSink.h"
|
|
||||||
#include "nsIStreamListener.h"
|
|
||||||
#include "nsIIOService.h"
|
|
||||||
#include "nsIURI.h"
|
|
||||||
#include "nsILoadGroup.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
|
||||||
#include "nsIInputStream.h"
|
|
||||||
#include "nsIProgressEventSink.h"
|
|
||||||
#include "nsICachingChannel.h"
|
#include "nsICachingChannel.h"
|
||||||
#include "nsICacheSession.h"
|
|
||||||
#include "nsICacheEntryDescriptor.h"
|
#include "nsICacheEntryDescriptor.h"
|
||||||
#include "nsICacheListener.h"
|
#include "nsICacheListener.h"
|
||||||
#include "nsIApplicationCache.h"
|
#include "nsIApplicationCache.h"
|
||||||
#include "nsIApplicationCacheChannel.h"
|
#include "nsIApplicationCacheChannel.h"
|
||||||
#include "nsIEncodedChannel.h"
|
#include "nsIEncodedChannel.h"
|
||||||
#include "nsITransport.h"
|
|
||||||
#include "nsIUploadChannel.h"
|
#include "nsIUploadChannel.h"
|
||||||
#include "nsIUploadChannel2.h"
|
#include "nsIUploadChannel2.h"
|
||||||
#include "nsIStringEnumerator.h"
|
#include "nsIStringEnumerator.h"
|
||||||
#include "nsIOutputStream.h"
|
|
||||||
#include "nsIAsyncInputStream.h"
|
|
||||||
#include "nsIPrompt.h"
|
#include "nsIPrompt.h"
|
||||||
#include "nsIResumableChannel.h"
|
#include "nsIResumableChannel.h"
|
||||||
#include "nsISupportsPriority.h"
|
#include "nsISupportsPriority.h"
|
||||||
@ -87,18 +68,16 @@
|
|||||||
#include "nsITraceableChannel.h"
|
#include "nsITraceableChannel.h"
|
||||||
#include "nsIAuthPromptCallback.h"
|
#include "nsIAuthPromptCallback.h"
|
||||||
|
|
||||||
class nsHttpResponseHead;
|
|
||||||
class nsAHttpConnection;
|
class nsAHttpConnection;
|
||||||
class nsIHttpAuthenticator;
|
class nsIHttpAuthenticator;
|
||||||
class nsProxyInfo;
|
|
||||||
|
using namespace mozilla::net;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsHttpChannel
|
// nsHttpChannel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class nsHttpChannel : public nsHashPropertyBag
|
class nsHttpChannel : public HttpBaseChannel
|
||||||
, public nsIHttpChannel
|
|
||||||
, public nsIHttpChannelInternal
|
|
||||||
, public nsIStreamListener
|
, public nsIStreamListener
|
||||||
, public nsICachingChannel
|
, public nsICachingChannel
|
||||||
, public nsIUploadChannel
|
, public nsIUploadChannel
|
||||||
@ -116,9 +95,6 @@ class nsHttpChannel : public nsHashPropertyBag
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSIREQUEST
|
|
||||||
NS_DECL_NSICHANNEL
|
|
||||||
NS_DECL_NSIHTTPCHANNEL
|
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSICACHINGCHANNEL
|
NS_DECL_NSICACHINGCHANNEL
|
||||||
@ -126,7 +102,6 @@ public:
|
|||||||
NS_DECL_NSIUPLOADCHANNEL2
|
NS_DECL_NSIUPLOADCHANNEL2
|
||||||
NS_DECL_NSICACHELISTENER
|
NS_DECL_NSICACHELISTENER
|
||||||
NS_DECL_NSIENCODEDCHANNEL
|
NS_DECL_NSIENCODEDCHANNEL
|
||||||
NS_DECL_NSIHTTPCHANNELINTERNAL
|
|
||||||
NS_DECL_NSITRANSPORTEVENTSINK
|
NS_DECL_NSITRANSPORTEVENTSINK
|
||||||
NS_DECL_NSIRESUMABLECHANNEL
|
NS_DECL_NSIRESUMABLECHANNEL
|
||||||
NS_DECL_NSISUPPORTSPRIORITY
|
NS_DECL_NSISUPPORTSPRIORITY
|
||||||
@ -140,11 +115,23 @@ public:
|
|||||||
nsHttpChannel();
|
nsHttpChannel();
|
||||||
virtual ~nsHttpChannel();
|
virtual ~nsHttpChannel();
|
||||||
|
|
||||||
nsresult Init(nsIURI *uri,
|
// Methods HttpBaseChannel didn't implement for us or that we override.
|
||||||
PRUint8 capabilities,
|
//
|
||||||
nsProxyInfo* proxyInfo);
|
// nsIRequest
|
||||||
|
NS_IMETHOD Cancel(nsresult status);
|
||||||
|
NS_IMETHOD Suspend();
|
||||||
|
NS_IMETHOD Resume();
|
||||||
|
// nsIChannel
|
||||||
|
NS_IMETHOD GetOwner(nsISupports **aOwner);
|
||||||
|
NS_IMETHOD SetOwner(nsISupports *aOwner);
|
||||||
|
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
|
||||||
|
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
|
||||||
|
// nsIHttpChannelInternal
|
||||||
|
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
|
||||||
|
|
||||||
public: /* internal; workaround lame compilers */
|
|
||||||
|
|
||||||
|
public: /* internal necko use only */
|
||||||
typedef void (nsHttpChannel:: *nsAsyncCallback)(void);
|
typedef void (nsHttpChannel:: *nsAsyncCallback)(void);
|
||||||
nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
|
nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
|
||||||
private:
|
private:
|
||||||
@ -263,43 +250,23 @@ private:
|
|||||||
nsresult ContinueOnAuthAvailable(const nsCSubstring& creds);
|
nsresult ContinueOnAuthAvailable(const nsCSubstring& creds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
|
||||||
nsCOMPtr<nsIURI> mURI;
|
|
||||||
nsCOMPtr<nsIURI> mDocumentURI;
|
|
||||||
nsCOMPtr<nsIStreamListener> mListener;
|
|
||||||
nsCOMPtr<nsISupports> mListenerContext;
|
|
||||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
|
||||||
nsCOMPtr<nsISupports> mOwner;
|
nsCOMPtr<nsISupports> mOwner;
|
||||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
|
||||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
|
||||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||||
nsCOMPtr<nsIURI> mReferrer;
|
|
||||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||||
|
|
||||||
nsHttpRequestHead mRequestHead;
|
|
||||||
nsHttpResponseHead *mResponseHead;
|
|
||||||
|
|
||||||
nsRefPtr<nsInputStreamPump> mTransactionPump;
|
nsRefPtr<nsInputStreamPump> mTransactionPump;
|
||||||
nsHttpTransaction *mTransaction; // hard ref
|
nsRefPtr<nsHttpTransaction> mTransaction;
|
||||||
nsHttpConnectionInfo *mConnectionInfo; // hard ref
|
|
||||||
|
|
||||||
nsCString mSpec; // ASCII encoded URL spec
|
|
||||||
|
|
||||||
PRUint32 mLoadFlags;
|
|
||||||
PRUint32 mStatus;
|
|
||||||
PRUint64 mLogicalOffset;
|
PRUint64 mLogicalOffset;
|
||||||
PRUint8 mCaps;
|
|
||||||
PRInt16 mPriority;
|
PRInt16 mPriority;
|
||||||
|
|
||||||
nsCString mContentTypeHint;
|
|
||||||
nsCString mContentCharsetHint;
|
|
||||||
nsCString mUserSetCookieHeader;
|
nsCString mUserSetCookieHeader;
|
||||||
|
|
||||||
// cache specific data
|
// cache specific data
|
||||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||||
nsRefPtr<nsInputStreamPump> mCachePump;
|
nsRefPtr<nsInputStreamPump> mCachePump;
|
||||||
nsHttpResponseHead *mCachedResponseHead;
|
nsAutoPtr<nsHttpResponseHead> mCachedResponseHead;
|
||||||
nsCacheAccessMode mCacheAccess;
|
nsCacheAccessMode mCacheAccess;
|
||||||
PRUint32 mPostID;
|
PRUint32 mPostID;
|
||||||
PRUint32 mRequestTime;
|
PRUint32 mRequestTime;
|
||||||
@ -347,22 +314,15 @@ private:
|
|||||||
// before we have either a cache pump or a transaction pump.
|
// before we have either a cache pump or a transaction pump.
|
||||||
PRUint32 mSuspendCount;
|
PRUint32 mSuspendCount;
|
||||||
|
|
||||||
// redirection specific data.
|
|
||||||
PRUint8 mRedirectionLimit;
|
|
||||||
|
|
||||||
// If the channel is associated with a cache, and the URI matched
|
// If the channel is associated with a cache, and the URI matched
|
||||||
// a fallback namespace, this will hold the key for the fallback
|
// a fallback namespace, this will hold the key for the fallback
|
||||||
// cache entry.
|
// cache entry.
|
||||||
nsCString mFallbackKey;
|
nsCString mFallbackKey;
|
||||||
|
|
||||||
// state flags
|
// state flags
|
||||||
PRUint32 mIsPending : 1;
|
|
||||||
PRUint32 mWasOpened : 1;
|
|
||||||
PRUint32 mApplyConversion : 1;
|
PRUint32 mApplyConversion : 1;
|
||||||
PRUint32 mAllowPipelining : 1;
|
|
||||||
PRUint32 mCachedContentIsValid : 1;
|
PRUint32 mCachedContentIsValid : 1;
|
||||||
PRUint32 mCachedContentIsPartial : 1;
|
PRUint32 mCachedContentIsPartial : 1;
|
||||||
PRUint32 mResponseHeadersModified : 1;
|
|
||||||
PRUint32 mCanceled : 1;
|
PRUint32 mCanceled : 1;
|
||||||
PRUint32 mTransactionReplaced : 1;
|
PRUint32 mTransactionReplaced : 1;
|
||||||
PRUint32 mUploadStreamHasHeaders : 1;
|
PRUint32 mUploadStreamHasHeaders : 1;
|
||||||
@ -386,7 +346,6 @@ private:
|
|||||||
PRUint32 mChooseApplicationCache : 1;
|
PRUint32 mChooseApplicationCache : 1;
|
||||||
PRUint32 mLoadedFromApplicationCache : 1;
|
PRUint32 mLoadedFromApplicationCache : 1;
|
||||||
PRUint32 mTracingEnabled : 1;
|
PRUint32 mTracingEnabled : 1;
|
||||||
PRUint32 mForceAllowThirdPartyCookie : 1;
|
|
||||||
// True if consumer added its own If-None-Match or If-Modified-Since
|
// True if consumer added its own If-None-Match or If-Modified-Since
|
||||||
// headers. In such a case we must not override them in the cache code
|
// headers. In such a case we must not override them in the cache code
|
||||||
// and also we want to pass possible 304 code response through.
|
// and also we want to pass possible 304 code response through.
|
||||||
|
@ -99,8 +99,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifdef MOZ_IPC
|
|
||||||
using namespace mozilla::net;
|
using namespace mozilla::net;
|
||||||
|
#ifdef MOZ_IPC
|
||||||
#include "mozilla/net/HttpChannelChild.h"
|
#include "mozilla/net/HttpChannelChild.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1524,7 +1524,7 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||||||
nsIProxyInfo* givenProxyInfo,
|
nsIProxyInfo* givenProxyInfo,
|
||||||
nsIChannel **result)
|
nsIChannel **result)
|
||||||
{
|
{
|
||||||
nsHttpChannel *httpChannel = nsnull;
|
nsRefPtr<HttpBaseChannel> httpChannel;
|
||||||
|
|
||||||
LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n",
|
LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n",
|
||||||
givenProxyInfo));
|
givenProxyInfo));
|
||||||
@ -1540,36 +1540,22 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
#if MOZ_IPC
|
#ifdef MOZ_IPC
|
||||||
if (IsNeckoChild()) {
|
if (IsNeckoChild()) {
|
||||||
LOG(("NECKO_E10S_HTTP set: using experimental interprocess HTTP\n"));
|
LOG(("NECKO_E10S_HTTP set: using experimental interprocess HTTP\n"));
|
||||||
// TODO_JCD:
|
|
||||||
// - Create a common BaseHttpChannel so can share logic?
|
|
||||||
HttpChannelChild *childChannel = nsnull;
|
|
||||||
NS_NEWXPCOM(childChannel, HttpChannelChild);
|
|
||||||
if (!childChannel)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
NS_ADDREF(childChannel);
|
|
||||||
// TODO: Just ignore HTTPS and proxying for now
|
// TODO: Just ignore HTTPS and proxying for now
|
||||||
if (https)
|
if (https)
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
if (givenProxyInfo)
|
if (givenProxyInfo)
|
||||||
DROP_DEAD();
|
DROP_DEAD();
|
||||||
// TODO: Init caps, etc, as below?
|
|
||||||
rv = childChannel->Init(uri);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_RELEASE(childChannel);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
*result = childChannel;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_NEWXPCOM(httpChannel, nsHttpChannel);
|
httpChannel = new HttpChannelChild();
|
||||||
if (!httpChannel)
|
} else
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
#endif
|
||||||
NS_ADDREF(httpChannel);
|
{
|
||||||
|
httpChannel = new nsHttpChannel();
|
||||||
|
}
|
||||||
|
|
||||||
// select proxy caps if using a non-transparent proxy. SSL tunneling
|
// select proxy caps if using a non-transparent proxy. SSL tunneling
|
||||||
// should not use proxy settings.
|
// should not use proxy settings.
|
||||||
@ -1594,13 +1580,10 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rv = httpChannel->Init(uri, caps, proxyInfo);
|
rv = httpChannel->Init(uri, caps, proxyInfo);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_RELEASE(httpChannel);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
|
|
||||||
*result = httpChannel;
|
httpChannel.forget(result);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
netwerk/test/unit_ipc/test_bug528292_wrap.js
Normal file
3
netwerk/test/unit_ipc/test_bug528292_wrap.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function run_test() {
|
||||||
|
run_test_in_child("../unit/test_bug528292.js");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user