зеркало из https://github.com/mozilla/pjs.git
Bug 546581: e10s HTTP: create common base class for HttpChannelChild and nsHttpChannel. a=dwitte, r=jae-seong, r=jduell
This commit is contained in:
Родитель
85a5121437
Коммит
f979d2cab8
|
@ -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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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):
|
||||
* Jason Duell <jduell.mcbugs@gmail.com>
|
||||
* 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
|
||||
|
@ -47,146 +48,27 @@
|
|||
#include "nsMimeTypes.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 net {
|
||||
|
||||
// C++ file contents
|
||||
HttpChannelChild::HttpChannelChild()
|
||||
: 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));
|
||||
|
||||
// grab a reference to the handler to ensure that it doesn't go away.
|
||||
NS_ADDREF(gHttpHandler);
|
||||
}
|
||||
|
||||
HttpChannelChild::~HttpChannelChild()
|
||||
{
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(HttpChannelChild, nsHashPropertyBag)
|
||||
NS_IMPL_RELEASE_INHERITED(HttpChannelChild, nsHashPropertyBag)
|
||||
NS_IMPL_ADDREF_INHERITED(HttpChannelChild, HttpBaseChannel)
|
||||
NS_IMPL_RELEASE_INHERITED(HttpChannelChild, HttpBaseChannel)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||
|
@ -203,7 +85,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
|
|||
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
|
||||
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpChannelChild::PHttpChannelChild
|
||||
|
@ -218,7 +100,7 @@ HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead)
|
|||
|
||||
mResponseHead = new nsHttpResponseHead(responseHead);
|
||||
|
||||
nsresult rv = mChildListener->OnStartRequest(this, mChildListenerContext);
|
||||
nsresult rv = mListener->OnStartRequest(this, mListenerContext);
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
// TODO: Cancel request:
|
||||
// - 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.
|
||||
return false;
|
||||
}
|
||||
rv = mChildListener->OnDataAvailable(this, mChildListenerContext,
|
||||
stringStream, offset, count);
|
||||
rv = mListener->OnDataAvailable(this, mListenerContext,
|
||||
stringStream, offset, count);
|
||||
stringStream->Close();
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
// TODO: Cancel request: see notes in OnStartRequest
|
||||
|
@ -273,10 +155,9 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
|||
|
||||
mIsPending = PR_FALSE;
|
||||
mStatus = statusCode;
|
||||
nsresult rv = mChildListener->OnStopRequest(this, mChildListenerContext,
|
||||
statusCode);
|
||||
mChildListener = 0;
|
||||
mChildListenerContext = 0;
|
||||
nsresult rv = mListener->OnStopRequest(this, mListenerContext, statusCode);
|
||||
mListener = 0;
|
||||
mListenerContext = 0;
|
||||
if (!NS_SUCCEEDED(rv)) {
|
||||
// TODO: Cancel request: see notes in OnStartRequest
|
||||
return false;
|
||||
|
@ -289,35 +170,7 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetName(nsACString& aName)
|
||||
{
|
||||
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)
|
||||
HttpChannelChild::Cancel(nsresult status)
|
||||
{
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
@ -334,211 +187,27 @@ HttpChannelChild::Resume()
|
|||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
HttpChannelChild::GetOwner(nsISupports **aOwner)
|
||||
{
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::SetOwner(nsISupports *aOwner)
|
||||
{
|
||||
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
|
||||
HttpChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
|
||||
{
|
||||
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
|
||||
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
|
||||
DROP_DEAD();
|
||||
}
|
||||
mChildListener = listener;
|
||||
mChildListenerContext = aContext;
|
||||
mListener = listener;
|
||||
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?
|
||||
|
||||
|
@ -589,11 +264,13 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||
}
|
||||
|
||||
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
|
||||
// -- TODO: verify that that's the case :)
|
||||
mChildListener = 0;
|
||||
mChildListenerContext = 0;
|
||||
mListener = 0;
|
||||
mListenerContext = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -608,77 +285,12 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||
// 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
|
||||
HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
||||
const nsACString& aValue,
|
||||
PRBool aMerge)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||
|
||||
nsresult rv = BaseClassSetRequestHeader_HACK(aHeader, aValue, aMerge);
|
||||
nsresult rv = HttpBaseChannel::SetRequestHeader(aHeader, aValue, aMerge);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -692,229 +304,16 @@ HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
|||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
|
||||
{
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetForceAllowThirdPartyCookie(PRBool *force)
|
||||
{
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::SetForceAllowThirdPartyCookie(PRBool force)
|
||||
{
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpChannelChild::nsICachingChannel
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Jason Duell <jduell.mcbugs@gmail.com>
|
||||
* 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
|
||||
|
@ -41,15 +42,10 @@
|
|||
#ifndef mozilla_net_HttpChannelChild_h
|
||||
#define mozilla_net_HttpChannelChild_h
|
||||
|
||||
#include "mozilla/net/HttpBaseChannel.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 "nsIURI.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
@ -65,7 +61,6 @@
|
|||
#include "nsIProxiedChannel.h"
|
||||
#include "nsITraceableChannel.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -80,9 +75,7 @@ enum HttpChannelChildState {
|
|||
|
||||
// Header file contents
|
||||
class HttpChannelChild : public PHttpChannelChild
|
||||
, public nsIHttpChannel
|
||||
, public nsHashPropertyBag
|
||||
, public nsIHttpChannelInternal
|
||||
, public HttpBaseChannel
|
||||
, public nsICachingChannel
|
||||
, public nsIUploadChannel
|
||||
, public nsIUploadChannel2
|
||||
|
@ -95,10 +88,6 @@ class HttpChannelChild : public PHttpChannelChild
|
|||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIHTTPCHANNEL
|
||||
NS_DECL_NSIHTTPCHANNELINTERNAL
|
||||
NS_DECL_NSICACHINGCHANNEL
|
||||
NS_DECL_NSIUPLOADCHANNEL
|
||||
NS_DECL_NSIUPLOADCHANNEL2
|
||||
|
@ -115,6 +104,24 @@ public:
|
|||
|
||||
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:
|
||||
bool RecvOnStartRequest(const nsHttpResponseHead& responseHead);
|
||||
bool RecvOnDataAvailable(const nsCString& data,
|
||||
|
@ -123,54 +130,12 @@ protected:
|
|||
bool RecvOnStopRequest(const nsresult& statusCode);
|
||||
|
||||
private:
|
||||
nsresult BaseClassSetContentType_HACK(const nsACString &value);
|
||||
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;
|
||||
RequestHeaderTuples mRequestHeaders;
|
||||
|
||||
// FIXME: replace with IPDL states (bug 536319)
|
||||
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 mozilla
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHttp.h"
|
||||
#include "mozilla/net/HttpChannelParent.h"
|
||||
#include "nsHttpChannel.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -49,10 +49,15 @@ namespace net {
|
|||
// C++ file contents
|
||||
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()
|
||||
{
|
||||
NS_RELEASE(gHttpHandler);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -76,8 +81,15 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||
const nsCString& docUriSpec,
|
||||
const nsCString& docCharset,
|
||||
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;
|
||||
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
|
@ -89,16 +101,14 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||
if (NS_FAILED(rv))
|
||||
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;
|
||||
rv = NS_NewChannel(getter_AddRefs(chan), uri, ios, nsnull, nsnull, loadFlags);
|
||||
if (NS_FAILED(rv))
|
||||
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()) {
|
||||
nsCOMPtr<nsIURI> originalUri;
|
||||
rv = NS_NewURI(getter_AddRefs(originalUri), originalUriSpec,
|
||||
|
@ -111,15 +121,12 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||
rv = NS_NewURI(getter_AddRefs(docUri), docUriSpec,
|
||||
docCharset.get(), nsnull, ios);
|
||||
if (!NS_FAILED(rv)) {
|
||||
nsCOMPtr<nsIHttpChannelInternal> iChan(do_QueryInterface(chan));
|
||||
if (iChan)
|
||||
iChan->SetDocumentURI(docUri);
|
||||
httpChanInt->SetDocumentURI(docUri);
|
||||
}
|
||||
}
|
||||
if (loadFlags != nsIRequest::LOAD_NORMAL)
|
||||
chan->SetLoadFlags(loadFlags);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
|
||||
for (PRUint32 i = 0; i < requestHeaders.Length(); i++)
|
||||
httpChan->SetRequestHeader(requestHeaders[i].mHeader,
|
||||
requestHeaders[i].mValue,
|
||||
|
@ -129,6 +136,11 @@ HttpChannelParent::RecvAsyncOpen(const nsCString& uriSpec,
|
|||
// process, or rig up appropriate hacks.
|
||||
// chan->SetNotificationCallbacks(this);
|
||||
|
||||
httpChan->SetRequestMethod(nsDependentCString(requestMethod.get()));
|
||||
httpChan->SetRedirectionLimit(redirectionLimit);
|
||||
httpChan->SetAllowPipelining(allowPipelining);
|
||||
httpChanInt->SetForceAllowThirdPartyCookie(forceAllowThirdPartyCookie);
|
||||
|
||||
rv = chan->AsyncOpen(this, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
|
|
|
@ -72,7 +72,11 @@ protected:
|
|||
const nsCString& docUriSpec,
|
||||
const nsCString& docCharset,
|
||||
const PRUint32& loadFlags,
|
||||
const RequestHeaderTuples& requestHeaders);
|
||||
const RequestHeaderTuples& requestHeaders,
|
||||
const nsHttpAtom& requestMethod,
|
||||
const PRUint8& redirectionLimit,
|
||||
const PRBool& allowPipelining,
|
||||
const PRBool& forceAllowThirdPartyCookie);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -46,10 +46,14 @@ MODULE = necko
|
|||
LIBRARY_NAME = nkhttp_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
ifdef MOZ_IPC
|
||||
EXPORTS_NAMESPACES = mozilla/net
|
||||
|
||||
EXPORTS_mozilla/net = \
|
||||
HttpBaseChannel.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_IPC
|
||||
EXPORTS_mozilla/net += \
|
||||
HttpChannelParent.h \
|
||||
HttpChannelChild.h \
|
||||
PHttpChannelParams.h \
|
||||
|
@ -79,6 +83,7 @@ CPPSRCS = \
|
|||
nsHttpNTLMAuth.cpp \
|
||||
nsHttpTransaction.cpp \
|
||||
nsHttpHandler.cpp \
|
||||
HttpBaseChannel.cpp \
|
||||
nsHttpChannel.cpp \
|
||||
nsHttpPipeline.cpp \
|
||||
nsHttpActivityDistributor.cpp \
|
||||
|
|
|
@ -44,6 +44,7 @@ include "mozilla/net/PHttpChannelParams.h";
|
|||
|
||||
using RequestHeaderTuples;
|
||||
using nsHttpResponseHead;
|
||||
using nsHttpAtom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -67,7 +68,11 @@ parent:
|
|||
nsCString docUriSpec,
|
||||
nsCString docCharset,
|
||||
PRUint32 loadFlags,
|
||||
RequestHeaderTuples requestHeaders);
|
||||
RequestHeaderTuples requestHeaders,
|
||||
nsHttpAtom requestMethod,
|
||||
PRUint8 redirectionLimit,
|
||||
PRBool allowPipelining,
|
||||
PRBool forceAllowThirdPartyCookie);
|
||||
|
||||
child:
|
||||
OnStartRequest(nsHttpResponseHead responseHead);
|
||||
|
|
|
@ -108,6 +108,7 @@ struct ParamTraits<nsHttpAtom>
|
|||
return false;
|
||||
|
||||
*aResult = nsHttp::ResolveAtom(value.get());
|
||||
NS_ASSERTION(aResult->get(), "atom table not initialized");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,6 +23,7 @@
|
|||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com> (original author)
|
||||
* Christian Biesinger <cbiesinger@web.de>
|
||||
* 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
|
||||
|
@ -41,43 +42,23 @@
|
|||
#ifndef nsHttpChannel_h__
|
||||
#define nsHttpChannel_h__
|
||||
|
||||
#include "HttpBaseChannel.h"
|
||||
|
||||
#include "nsHttpTransaction.h"
|
||||
#include "nsHttpRequestHead.h"
|
||||
#include "nsHttpAuthCache.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
#include "nsInputStreamPump.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 "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 "nsICacheSession.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICacheListener.h"
|
||||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIEncodedChannel.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsIStringEnumerator.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIResumableChannel.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
|
@ -87,18 +68,16 @@
|
|||
#include "nsITraceableChannel.h"
|
||||
#include "nsIAuthPromptCallback.h"
|
||||
|
||||
class nsHttpResponseHead;
|
||||
class nsAHttpConnection;
|
||||
class nsIHttpAuthenticator;
|
||||
class nsProxyInfo;
|
||||
|
||||
using namespace mozilla::net;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsHttpChannel : public nsHashPropertyBag
|
||||
, public nsIHttpChannel
|
||||
, public nsIHttpChannelInternal
|
||||
class nsHttpChannel : public HttpBaseChannel
|
||||
, public nsIStreamListener
|
||||
, public nsICachingChannel
|
||||
, public nsIUploadChannel
|
||||
|
@ -116,9 +95,6 @@ class nsHttpChannel : public nsHashPropertyBag
|
|||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIHTTPCHANNEL
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSICACHINGCHANNEL
|
||||
|
@ -126,7 +102,6 @@ public:
|
|||
NS_DECL_NSIUPLOADCHANNEL2
|
||||
NS_DECL_NSICACHELISTENER
|
||||
NS_DECL_NSIENCODEDCHANNEL
|
||||
NS_DECL_NSIHTTPCHANNELINTERNAL
|
||||
NS_DECL_NSITRANSPORTEVENTSINK
|
||||
NS_DECL_NSIRESUMABLECHANNEL
|
||||
NS_DECL_NSISUPPORTSPRIORITY
|
||||
|
@ -140,11 +115,23 @@ public:
|
|||
nsHttpChannel();
|
||||
virtual ~nsHttpChannel();
|
||||
|
||||
nsresult Init(nsIURI *uri,
|
||||
PRUint8 capabilities,
|
||||
nsProxyInfo* proxyInfo);
|
||||
// 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);
|
||||
// nsIHttpChannelInternal
|
||||
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
|
||||
|
||||
public: /* internal; workaround lame compilers */
|
||||
|
||||
|
||||
public: /* internal necko use only */
|
||||
typedef void (nsHttpChannel:: *nsAsyncCallback)(void);
|
||||
nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
|
||||
private:
|
||||
|
@ -263,43 +250,23 @@ private:
|
|||
nsresult ContinueOnAuthAvailable(const nsCSubstring& creds);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
nsCOMPtr<nsISupports> mListenerContext;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||
|
||||
nsHttpRequestHead mRequestHead;
|
||||
nsHttpResponseHead *mResponseHead;
|
||||
|
||||
nsRefPtr<nsInputStreamPump> mTransactionPump;
|
||||
nsHttpTransaction *mTransaction; // hard ref
|
||||
nsHttpConnectionInfo *mConnectionInfo; // hard ref
|
||||
nsRefPtr<nsHttpTransaction> mTransaction;
|
||||
|
||||
nsCString mSpec; // ASCII encoded URL spec
|
||||
|
||||
PRUint32 mLoadFlags;
|
||||
PRUint32 mStatus;
|
||||
PRUint64 mLogicalOffset;
|
||||
PRUint8 mCaps;
|
||||
PRInt16 mPriority;
|
||||
|
||||
nsCString mContentTypeHint;
|
||||
nsCString mContentCharsetHint;
|
||||
nsCString mUserSetCookieHeader;
|
||||
|
||||
// cache specific data
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||
nsRefPtr<nsInputStreamPump> mCachePump;
|
||||
nsHttpResponseHead *mCachedResponseHead;
|
||||
nsAutoPtr<nsHttpResponseHead> mCachedResponseHead;
|
||||
nsCacheAccessMode mCacheAccess;
|
||||
PRUint32 mPostID;
|
||||
PRUint32 mRequestTime;
|
||||
|
@ -347,22 +314,15 @@ private:
|
|||
// before we have either a cache pump or a transaction pump.
|
||||
PRUint32 mSuspendCount;
|
||||
|
||||
// redirection specific data.
|
||||
PRUint8 mRedirectionLimit;
|
||||
|
||||
// If the channel is associated with a cache, and the URI matched
|
||||
// a fallback namespace, this will hold the key for the fallback
|
||||
// cache entry.
|
||||
nsCString mFallbackKey;
|
||||
|
||||
// state flags
|
||||
PRUint32 mIsPending : 1;
|
||||
PRUint32 mWasOpened : 1;
|
||||
PRUint32 mApplyConversion : 1;
|
||||
PRUint32 mAllowPipelining : 1;
|
||||
PRUint32 mCachedContentIsValid : 1;
|
||||
PRUint32 mCachedContentIsPartial : 1;
|
||||
PRUint32 mResponseHeadersModified : 1;
|
||||
PRUint32 mCanceled : 1;
|
||||
PRUint32 mTransactionReplaced : 1;
|
||||
PRUint32 mUploadStreamHasHeaders : 1;
|
||||
|
@ -386,7 +346,6 @@ private:
|
|||
PRUint32 mChooseApplicationCache : 1;
|
||||
PRUint32 mLoadedFromApplicationCache : 1;
|
||||
PRUint32 mTracingEnabled : 1;
|
||||
PRUint32 mForceAllowThirdPartyCookie : 1;
|
||||
// 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
|
||||
// and also we want to pass possible 304 code response through.
|
||||
|
|
|
@ -99,8 +99,8 @@
|
|||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef MOZ_IPC
|
||||
using namespace mozilla::net;
|
||||
#ifdef MOZ_IPC
|
||||
#include "mozilla/net/HttpChannelChild.h"
|
||||
#endif
|
||||
|
||||
|
@ -1524,7 +1524,7 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||
nsIProxyInfo* givenProxyInfo,
|
||||
nsIChannel **result)
|
||||
{
|
||||
nsHttpChannel *httpChannel = nsnull;
|
||||
nsRefPtr<HttpBaseChannel> httpChannel;
|
||||
|
||||
LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n",
|
||||
givenProxyInfo));
|
||||
|
@ -1540,36 +1540,22 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
#if MOZ_IPC
|
||||
#ifdef MOZ_IPC
|
||||
if (IsNeckoChild()) {
|
||||
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
|
||||
if (https)
|
||||
DROP_DEAD();
|
||||
if (givenProxyInfo)
|
||||
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);
|
||||
if (!httpChannel)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(httpChannel);
|
||||
httpChannel = new HttpChannelChild();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
httpChannel = new nsHttpChannel();
|
||||
}
|
||||
|
||||
// select proxy caps if using a non-transparent proxy. SSL tunneling
|
||||
// should not use proxy settings.
|
||||
|
@ -1594,13 +1580,10 @@ nsHttpHandler::NewProxiedChannel(nsIURI *uri,
|
|||
}
|
||||
|
||||
rv = httpChannel->Init(uri, caps, proxyInfo);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(httpChannel);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = httpChannel;
|
||||
httpChannel.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
function run_test() {
|
||||
run_test_in_child("../unit/test_bug528292.js");
|
||||
}
|
Загрузка…
Ссылка в новой задаче