--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -1141,16 +1141,43 @@ NS_NewPostDataStream(nsIInputStream **r
if (NS_FAILED(rv))
return rv;
NS_ADDREF(*result = stream);
return NS_OK;
}
inline nsresult
+NS_ReadInputStreamToString(nsIInputStream *aInputStream,
+ nsACString &aDest,
+ PRUint32 aCount)
+{
+ nsresult rv;
+
+ aDest.SetLength(aCount);
+ if (aDest.Length() != aCount)
+ return NS_ERROR_OUT_OF_MEMORY;
+ char * p = aDest.BeginWriting();
+ PRUint32 bytesRead;
+ PRUint32 totalRead = 0;
+ while (1) {
+ rv = aInputStream->Read(p + totalRead, aCount - totalRead, &bytesRead);
+ if (!NS_SUCCEEDED(rv))
+ return rv;
+ totalRead += bytesRead;
+ if (totalRead == aCount)
+ break;
+ // if Read reads 0 bytes, we've hit EOF
+ if (bytesRead == 0)
+ return NS_ERROR_UNEXPECTED;
+ }
+ return rv;
+}
+
+inline nsresult
NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties **result,
nsIURI *uri,
nsIIOService *ioService = nsnull)
{
nsCOMPtr<nsIInputStream> in;
nsresult rv = NS_OpenURI(getter_AddRefs(in), uri, ioService);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPersistentProperties> properties =
--- a/netwerk/protocol/http/src/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/src/HttpBaseChannel.cpp
@@ -18,16 +18,18 @@
*
* 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>
+ * Frederic Plourde <bugzillaFred@gmail.com>
+ * Jason Duell <jduell.mcbugs@gmail.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
@@ -53,16 +55,17 @@ HttpBaseChannel::HttpBaseChannel()
, mPriority(PRIORITY_NORMAL)
, mCaps(0)
, mRedirectionLimit(gHttpHandler->RedirectionLimit())
, mIsPending(PR_FALSE)
, mWasOpened(PR_FALSE)
, mResponseHeadersModified(PR_FALSE)
, mAllowPipelining(PR_TRUE)
, mForceAllowThirdPartyCookie(PR_FALSE)
+ , mUploadStreamHasHeaders(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()
@@ -136,22 +139,24 @@ HttpBaseChannel::Init(nsIURI *aURI,
return rv;
}
//-----------------------------------------------------------------------------
// HttpBaseChannel::nsISupports
//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED5(HttpBaseChannel,
+NS_IMPL_ISUPPORTS_INHERITED7(HttpBaseChannel,
nsHashPropertyBag,
nsIRequest,
nsIChannel,
nsIHttpChannel,
nsIHttpChannelInternal,
+ nsIUploadChannel,
+ nsIUploadChannel2,
nsISupportsPriority)
//-----------------------------------------------------------------------------
// HttpBaseChannel::nsIRequest
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpBaseChannel::GetName(nsACString& aName)
@@ -364,16 +369,115 @@ HttpBaseChannel::SetContentLength(PRInt3
NS_IMETHODIMP
HttpBaseChannel::Open(nsIInputStream **aResult)
{
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS);
return NS_ImplementChannelOpen(this, aResult);
}
//-----------------------------------------------------------------------------
+// HttpBaseChannel::nsIUploadChannel
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+HttpBaseChannel::GetUploadStream(nsIInputStream **stream)
+{
+ NS_ENSURE_ARG_POINTER(stream);
+ *stream = mUploadStream;
+ NS_IF_ADDREF(*stream);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpBaseChannel::SetUploadStream(nsIInputStream *stream,
+ const nsACString &contentType,
+ PRInt32 contentLength)
+{
+ // NOTE: for backwards compatibility and for compatibility with old style
+ // plugins, |stream| may include headers, specifically Content-Type and
+ // Content-Length headers. in this case, |contentType| and |contentLength|
+ // would be unspecified. this is traditionally the case of a POST request,
+ // and so we select POST as the request method if contentType and
+ // contentLength are unspecified.
+
+ if (stream) {
+ if (contentType.IsEmpty()) {
+ mUploadStreamHasHeaders = PR_TRUE;
+ mRequestHead.SetMethod(nsHttp::Post); // POST request
+ } else {
+ if (contentLength < 0) {
+ // Not really kosher to assume Available == total length of
+ // stream, but apparently works for the streams we see here.
+ stream->Available((PRUint32 *) &contentLength);
+ if (contentLength < 0) {
+ NS_ERROR("unable to determine content length");
+ return NS_ERROR_FAILURE;
+ }
+ }
+ // SetRequestHeader propagates headers to chrome if HttpChannelChild
+ nsCAutoString contentLengthStr;
+ contentLengthStr.AppendInt(PRInt64(contentLength));
+ SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthStr,
+ PR_FALSE);
+ SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), contentType,
+ PR_FALSE);
+ mUploadStreamHasHeaders = PR_FALSE;
+ mRequestHead.SetMethod(nsHttp::Put); // PUT request
+ }
+ } else {
+ mUploadStreamHasHeaders = PR_FALSE;
+ mRequestHead.SetMethod(nsHttp::Get); // revert to GET request
+ }
+ mUploadStream = stream;
+ return NS_OK;
+}
+
+//-----------------------------------------------------------------------------
+// HttpBaseChannel::nsIUploadChannel2
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
+ const nsACString &aContentType,
+ PRInt64 aContentLength,
+ const nsACString &aMethod,
+ PRBool aStreamHasHeaders)
+{
+ // Ensure stream is set and method is valid
+ NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
+
+ if (aContentLength < 0 && !aStreamHasHeaders) {
+ PRUint32 streamLength;
+ aStream->Available(&streamLength);
+ aContentLength = streamLength;
+ if (aContentLength < 0) {
+ NS_ERROR("unable to determine content length");
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ nsresult rv = SetRequestMethod(aMethod);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!aStreamHasHeaders) {
+ // SetRequestHeader propagates headers to chrome if HttpChannelChild
+ nsCAutoString contentLengthStr;
+ contentLengthStr.AppendInt(aContentLength);
+ SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthStr,
+ PR_FALSE);
+ SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), aContentType,
+ PR_FALSE);
+ }
+
+ mUploadStreamHasHeaders = aStreamHasHeaders;
+ mUploadStream = aStream;
+ return NS_OK;
+}
+
+//-----------------------------------------------------------------------------
// HttpBaseChannel::nsIHttpChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpBaseChannel::GetRequestMethod(nsACString& aMethod)
{
aMethod = mRequestHead.Method();
return NS_OK;
--- a/netwerk/protocol/http/src/HttpBaseChannel.h
+++ b/netwerk/protocol/http/src/HttpBaseChannel.h
@@ -45,16 +45,18 @@
#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 "nsIUploadChannel.h"
+#include "nsIUploadChannel2.h"
#include "nsIProgressEventSink.h"
#include "nsIURI.h"
#include "nsISupportsPriority.h"
#define DIE_WITH_ASYNC_OPEN_MSG() \
do { \
fprintf(stderr, \
"*&*&*&*&*&*&*&**&*&&*& FATAL ERROR: '%s' " \
@@ -70,30 +72,38 @@
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 {
+typedef enum { eUploadStream_null = -1,
+ eUploadStream_hasNoHeaders = 0,
+ eUploadStream_hasHeaders = 1 } UploadStreamInfoType;
+
/*
* 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 nsIUploadChannel
+ , public nsIUploadChannel2
, public nsISupportsPriority
{
public:
NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIUPLOADCHANNEL
+ NS_DECL_NSIUPLOADCHANNEL2
HttpBaseChannel();
virtual ~HttpBaseChannel();
nsresult Init(nsIURI *aURI, PRUint8 aCaps, nsProxyInfo *aProxyInfo);
// nsIRequest
NS_IMETHOD GetName(nsACString& aName);
@@ -173,16 +183,17 @@ protected:
nsCOMPtr<nsISupports> mListenerContext;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIURI> mReferrer;
nsHttpRequestHead mRequestHead;
+ nsCOMPtr<nsIInputStream> mUploadStream;
nsAutoPtr<nsHttpResponseHead> mResponseHead;
nsRefPtr<nsHttpConnectionInfo> mConnectionInfo;
nsCString mSpec; // ASCII encoded URL spec
nsCString mContentTypeHint;
nsCString mContentCharsetHint;
nsresult mStatus;
@@ -191,15 +202,16 @@ protected:
PRUint8 mCaps;
PRUint8 mRedirectionLimit;
PRUint8 mIsPending : 1;
PRUint8 mWasOpened : 1;
PRUint8 mResponseHeadersModified : 1;
PRUint8 mAllowPipelining : 1;
PRUint8 mForceAllowThirdPartyCookie : 1;
+ PRUint32 mUploadStreamHasHeaders : 1;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_HttpBaseChannel_h
--- a/netwerk/protocol/http/src/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/src/HttpChannelChild.cpp
@@ -83,18 +83,16 @@ HttpChannelChild::RefcountHitZero()
}
NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
NS_INTERFACE_MAP_ENTRY(nsICachingChannel)
- NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)
- NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)
NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)
NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)
NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel)
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
@@ -276,18 +274,46 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
// Port checked in parent, but duplicate here so we can return with error
// immediately
nsresult rv;
rv = NS_CheckPortSafety(mURI);
if (NS_FAILED(rv))
return rv;
+ // Prepare uploadStream for POST data
+ nsCAutoString uploadStreamData;
+ PRInt32 uploadStreamInfo;
+
+ if (mUploadStream) {
+ // Read entire POST stream into string:
+ // This is a temporary measure until bug 564553 is implemented: we're doing
+ // a blocking read of a potentially arbitrarily large stream, so this isn't
+ // performant/safe for large file uploads.
+ PRUint32 bytes;
+ mUploadStream->Available(&bytes);
+ if (bytes > 0) {
+ rv = NS_ReadInputStreamToString(mUploadStream, uploadStreamData, bytes);
+ if (!NS_SUCCEEDED(rv))
+ return rv;
+ }
+
+ uploadStreamInfo = mUploadStreamHasHeaders ?
+ eUploadStream_hasHeaders : eUploadStream_hasNoHeaders;
+ } else {
+ uploadStreamInfo = eUploadStream_null;
+ }
+
// FIXME bug 562587: need to dupe nsHttpChannel::AsyncOpen cookies logic
+ //
+ // NOTE: From now on we must return NS_OK; all errors must be handled via
+ // OnStart/OnStopRequest
+ //
+
// notify "http-on-modify-request" observers
gHttpHandler->OnModifyRequest(this);
mIsPending = PR_TRUE;
mWasOpened = PR_TRUE;
mListener = listener;
mListenerContext = aContext;
@@ -312,18 +338,19 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
//
// Send request to the chrome process...
//
// FIXME: bug 558623: Combine constructor and SendAsyncOpen into one IPC msg
gNeckoChild->SendPHttpChannelConstructor(this);
SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI), IPC::URI(mDocumentURI),
- IPC::URI(mReferrer), mLoadFlags, mRequestHeaders,
- mRequestHead.Method(), mPriority, mRedirectionLimit,
+ IPC::URI(mReferrer), mLoadFlags, mRequestHeaders,
+ mRequestHead.Method(), uploadStreamData,
+ uploadStreamInfo, mPriority, mRedirectionLimit,
mAllowPipelining, mForceAllowThirdPartyCookie);
// The socket transport layer in the chrome process now has a logical ref to
// us, until either OnStopRequest or OnRedirect is called.
this->AddRef();
mState = HCC_OPENED;
return NS_OK;
@@ -450,51 +477,16 @@ HttpChannelChild::IsFromCache(PRBool *va
return NS_ERROR_NOT_AVAILABLE;
// FIXME: stub for bug 537164
*value = false;
return NS_OK;
}
//-----------------------------------------------------------------------------
-// HttpChannelChild::nsIUploadChannel
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-HttpChannelChild::SetUploadStream(nsIInputStream *aStream,
- const nsACString& aContentType,
- PRInt32 aContentLength)
-{
- DROP_DEAD();
-}
-
-NS_IMETHODIMP
-HttpChannelChild::GetUploadStream(nsIInputStream **stream)
-{
- // FIXME: stub for bug 536273
- NS_ENSURE_ARG_POINTER(stream);
- *stream = 0;
- return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// HttpChannelChild::nsIUploadChannel2
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-HttpChannelChild::ExplicitSetUploadStream(nsIInputStream *aStream,
- const nsACString& aContentType,
- PRInt64 aContentLength,
- const nsACString& aMethod,
- PRBool aStreamHasHeaders)
-{
- DROP_DEAD();
-}
-
-//-----------------------------------------------------------------------------
// HttpChannelChild::nsIEncodedChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpChannelChild::GetContentEncodings(nsIUTF8StringEnumerator **result)
{
DROP_DEAD();
}
--- a/netwerk/protocol/http/src/HttpChannelChild.h
+++ b/netwerk/protocol/http/src/HttpChannelChild.h
@@ -49,17 +49,16 @@
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIProgressEventSink.h"
#include "nsICachingChannel.h"
#include "nsIApplicationCache.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIEncodedChannel.h"
-#include "nsIUploadChannel.h"
#include "nsIUploadChannel2.h"
#include "nsIResumableChannel.h"
#include "nsIProxiedChannel.h"
#include "nsITraceableChannel.h"
namespace mozilla {
namespace net {
@@ -71,29 +70,25 @@ enum HttpChannelChildState {
HCC_ONDATA,
HCC_ONSTOP
};
// Header file contents
class HttpChannelChild : public PHttpChannelChild
, public HttpBaseChannel
, public nsICachingChannel
- , public nsIUploadChannel
- , public nsIUploadChannel2
, public nsIEncodedChannel
, public nsIResumableChannel
, public nsIProxiedChannel
, public nsITraceableChannel
, public nsIApplicationCacheChannel
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSICACHINGCHANNEL
- NS_DECL_NSIUPLOADCHANNEL
- NS_DECL_NSIUPLOADCHANNEL2
NS_DECL_NSIENCODEDCHANNEL
NS_DECL_NSIRESUMABLECHANNEL
NS_DECL_NSIPROXIEDCHANNEL
NS_DECL_NSITRACEABLECHANNEL
NS_DECL_NSIAPPLICATIONCACHECONTAINER
NS_DECL_NSIAPPLICATIONCACHECHANNEL
HttpChannelChild();
--- a/netwerk/protocol/http/src/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/src/HttpChannelParent.cpp
@@ -89,16 +89,18 @@ NS_IMPL_ISUPPORTS4(HttpChannelParent,
bool
HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
const IPC::URI& aOriginalURI,
const IPC::URI& aDocURI,
const IPC::URI& aReferrerURI,
const PRUint32& loadFlags,
const RequestHeaderTuples& requestHeaders,
const nsHttpAtom& requestMethod,
+ const nsCString& uploadStreamData,
+ const PRInt32& uploadStreamInfo,
const PRUint16& priority,
const PRUint8& redirectionLimit,
const PRBool& allowPipelining,
const PRBool& forceAllowThirdPartyCookie)
{
nsCOMPtr<nsIURI> uri = aURI;
nsCOMPtr<nsIURI> originalUri = aOriginalURI;
nsCOMPtr<nsIURI> docUri = aDocURI;
@@ -108,21 +110,21 @@ HttpChannelParent::RecvAsyncOpen(const I
uri->GetSpec(uriSpec);
LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
this, uriSpec.get()));
nsresult rv;
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
if (NS_FAILED(rv))
- return false; // TODO: send fail msg to child, return true
+ return false; // TODO: cancel request (bug 536317), return true
rv = NS_NewChannel(getter_AddRefs(mChannel), uri, ios, nsnull, nsnull, loadFlags);
if (NS_FAILED(rv))
- return false; // TODO: send fail msg to child, return true
+ return false; // TODO: cancel request (bug 536317), return true
nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
httpChan->SetRemoteChannel();
if (originalUri)
httpChan->SetOriginalURI(originalUri);
if (docUri)
httpChan->SetDocumentURI(docUri);
@@ -134,25 +136,38 @@ HttpChannelParent::RecvAsyncOpen(const I
for (PRUint32 i = 0; i < requestHeaders.Length(); i++)
httpChan->SetRequestHeader(requestHeaders[i].mHeader,
requestHeaders[i].mValue,
requestHeaders[i].mMerge);
httpChan->SetNotificationCallbacks(this);
httpChan->SetRequestMethod(nsDependentCString(requestMethod.get()));
+
+ if (uploadStreamInfo != eUploadStream_null) {
+ nsCOMPtr<nsIInputStream> stream;
+ rv = NS_NewPostDataStream(getter_AddRefs(stream), false, uploadStreamData, 0);
+ if (!NS_SUCCEEDED(rv)) {
+ return false; // TODO: cancel request (bug 536317), return true
+ }
+ httpChan->InternalSetUploadStream(stream);
+ // We're casting uploadStreamInfo into PRBool here on purpose because
+ // we know possible values are either 0 or 1. See uploadStreamInfoType.
+ httpChan->SetUploadStreamHasHeaders((PRBool) uploadStreamInfo);
+ }
+
if (priority != nsISupportsPriority::PRIORITY_NORMAL)
httpChan->SetPriority(priority);
httpChan->SetRedirectionLimit(redirectionLimit);
httpChan->SetAllowPipelining(allowPipelining);
httpChan->SetForceAllowThirdPartyCookie(forceAllowThirdPartyCookie);
rv = httpChan->AsyncOpen(this, nsnull);
if (NS_FAILED(rv))
- return false; // TODO: send fail msg to child, return true
+ return false; // TODO: cancel request (bug 536317), return true
return true;
}
bool
HttpChannelParent::RecvSetPriority(const PRUint16& priority)
{
nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
--- a/netwerk/protocol/http/src/HttpChannelParent.h
+++ b/netwerk/protocol/http/src/HttpChannelParent.h
@@ -70,16 +70,18 @@ public:
protected:
virtual bool RecvAsyncOpen(const IPC::URI& uri,
const IPC::URI& originalUri,
const IPC::URI& docUri,
const IPC::URI& referrerUri,
const PRUint32& loadFlags,
const RequestHeaderTuples& requestHeaders,
const nsHttpAtom& requestMethod,
+ const nsCString& uploadStreamData,
+ const PRInt32& uploadStreamInfo,
const PRUint16& priority,
const PRUint8& redirectionLimit,
const PRBool& allowPipelining,
const PRBool& forceAllowThirdPartyCookie);
virtual bool RecvSetPriority(const PRUint16& priority);
virtual void ActorDestroy(ActorDestroyReason why);
--- a/netwerk/protocol/http/src/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/src/PHttpChannel.ipdl
@@ -64,16 +64,18 @@ parent:
// originalURI != uri (about:credits?); also not clear if chrome
// channel would ever need to know. Can we get rid of next arg?
URI original,
URI doc,
URI referrer,
PRUint32 loadFlags,
RequestHeaderTuples requestHeaders,
nsHttpAtom requestMethod,
+ nsCString uploadStreamData,
+ PRInt32 uploadStreamInfo,
PRUint16 priority,
PRUint8 redirectionLimit,
PRBool allowPipelining,
PRBool forceAllowThirdPartyCookie);
SetPriority(PRUint16 priority);
child:
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -95,17 +95,16 @@ nsHttpChannel::nsHttpChannel()
, mStartPos(LL_MAXUINT)
, mPendingAsyncCallOnResume(nsnull)
, mSuspendCount(0)
, mApplyConversion(PR_TRUE)
, mCachedContentIsValid(PR_FALSE)
, mCachedContentIsPartial(PR_FALSE)
, mCanceled(PR_FALSE)
, mTransactionReplaced(PR_FALSE)
- , mUploadStreamHasHeaders(PR_FALSE)
, mAuthRetryPending(PR_FALSE)
, mProxyAuth(PR_FALSE)
, mTriedProxyAuth(PR_FALSE)
, mTriedHostAuth(PR_FALSE)
, mSuppressDefensiveAuth(PR_FALSE)
, mResuming(PR_FALSE)
, mInitedCacheEntry(PR_FALSE)
, mCacheForOfflineUse(PR_FALSE)
@@ -4195,107 +4194,16 @@ nsHttpChannel::SetupFallbackChannel(cons
{
LOG(("nsHttpChannel::SetupFallbackChannel [this=%x, key=%s]",
this, aFallbackKey));
mFallbackChannel = PR_TRUE;
mFallbackKey = aFallbackKey;
return NS_OK;
}
-
-//-----------------------------------------------------------------------------
-// nsHttpChannel::nsIUploadChannel
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-nsHttpChannel::GetUploadStream(nsIInputStream **stream)
-{
- NS_ENSURE_ARG_POINTER(stream);
- *stream = mUploadStream;
- NS_IF_ADDREF(*stream);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHttpChannel::SetUploadStream(nsIInputStream *stream,
- const nsACString &contentType,
- PRInt32 contentLength)
-{
- // NOTE: for backwards compatibility and for compatibility with old style
- // plugins, |stream| may include headers, specifically Content-Type and
- // Content-Length headers. in this case, |contentType| and |contentLength|
- // would be unspecified. this is traditionally the case of a POST request,
- // and so we select POST as the request method if contentType and
- // contentLength are unspecified.
-
- if (stream) {
- if (!contentType.IsEmpty()) {
- if (contentLength < 0) {
- stream->Available((PRUint32 *) &contentLength);
- if (contentLength < 0) {
- NS_ERROR("unable to determine content length");
- return NS_ERROR_FAILURE;
- }
- }
- mRequestHead.SetHeader(nsHttp::Content_Length,
- nsPrintfCString("%d", contentLength));
- mRequestHead.SetHeader(nsHttp::Content_Type, contentType);
- mUploadStreamHasHeaders = PR_FALSE;
- mRequestHead.SetMethod(nsHttp::Put); // PUT request
- }
- else {
- mUploadStreamHasHeaders = PR_TRUE;
- mRequestHead.SetMethod(nsHttp::Post); // POST request
- }
- }
- else {
- mUploadStreamHasHeaders = PR_FALSE;
- mRequestHead.SetMethod(nsHttp::Get); // revert to GET request
- }
- mUploadStream = stream;
- return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// nsHttpChannel::nsIUploadChannel2
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-nsHttpChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
- const nsACString &aContentType,
- PRInt64 aContentLength,
- const nsACString &aMethod,
- PRBool aStreamHasHeaders)
-{
- // Ensure stream is set and method is valid
- NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
-
- if (aContentLength < 0 && !aStreamHasHeaders) {
- PRUint32 streamLength;
- aStream->Available(&streamLength);
- aContentLength = streamLength;
- if (aContentLength < 0) {
- NS_ERROR("unable to determine content length");
- return NS_ERROR_FAILURE;
- }
- }
-
- nsresult rv = SetRequestMethod(aMethod);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!aStreamHasHeaders) {
- mRequestHead.SetHeader(nsHttp::Content_Length,
- nsPrintfCString("%lld", aContentLength));
- mRequestHead.SetHeader(nsHttp::Content_Type, aContentType);
- }
-
- mUploadStreamHasHeaders = aStreamHasHeaders;
- mUploadStream = aStream;
- return NS_OK;
-}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIEncodedChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::GetApplyConversion(PRBool *value)
{
--- a/netwerk/protocol/http/src/nsHttpChannel.h
+++ b/netwerk/protocol/http/src/nsHttpChannel.h
@@ -51,18 +51,16 @@
#include "nsIHttpEventSink.h"
#include "nsICachingChannel.h"
#include "nsICacheEntryDescriptor.h"
#include "nsICacheListener.h"
#include "nsIApplicationCache.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIEncodedChannel.h"
-#include "nsIUploadChannel.h"
-#include "nsIUploadChannel2.h"
#include "nsIStringEnumerator.h"
#include "nsIPrompt.h"
#include "nsIResumableChannel.h"
#include "nsIProtocolProxyCallback.h"
#include "nsICancelable.h"
#include "nsIProxiedChannel.h"
#include "nsITraceableChannel.h"
#include "nsIAuthPromptCallback.h"
@@ -74,35 +72,31 @@ using namespace mozilla::net;
//-----------------------------------------------------------------------------
// nsHttpChannel
//-----------------------------------------------------------------------------
class nsHttpChannel : public HttpBaseChannel
, public nsIStreamListener
, public nsICachingChannel
- , public nsIUploadChannel
- , public nsIUploadChannel2
, public nsICacheListener
, public nsIEncodedChannel
, public nsITransportEventSink
, public nsIResumableChannel
, public nsIProtocolProxyCallback
, public nsIProxiedChannel
, public nsITraceableChannel
, public nsIApplicationCacheChannel
, public nsIAuthPromptCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSICACHINGCHANNEL
- NS_DECL_NSIUPLOADCHANNEL
- NS_DECL_NSIUPLOADCHANNEL2
NS_DECL_NSICACHELISTENER
NS_DECL_NSIENCODEDCHANNEL
NS_DECL_NSITRANSPORTEVENTSINK
NS_DECL_NSIRESUMABLECHANNEL
NS_DECL_NSIPROTOCOLPROXYCALLBACK
NS_DECL_NSIPROXIEDCHANNEL
NS_DECL_NSITRACEABLECHANNEL
NS_DECL_NSIAPPLICATIONCACHECONTAINER
@@ -125,16 +119,20 @@ public:
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
// nsISupportsPriority
NS_IMETHOD SetPriority(PRInt32 value);
public: /* internal necko use only */
typedef void (nsHttpChannel:: *nsAsyncCallback)(void);
nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
void SetRemoteChannel() { mRemoteChannel = 1; }
+ void InternalSetUploadStream(nsIInputStream *uploadStream)
+ { mUploadStream = uploadStream; }
+ void SetUploadStreamHasHeaders(PRBool hasHeaders)
+ { mUploadStreamHasHeaders = hasHeaders; }
nsresult SetReferrerInternal(nsIURI *referrer) {
nsCAutoString spec;
nsresult rv = referrer->GetAsciiSpec(spec);
if (NS_FAILED(rv)) return rv;
mReferrer = referrer;
mRequestHead.SetHeader(nsHttp::Referer, spec);
return NS_OK;
@@ -241,17 +239,16 @@ private:
/**
* Method called to resume suspended transaction after we got credentials
* from the user. Called from OnAuthAvailable callback or OnAuthCancelled
* when credentials for next challenge were obtained synchronously.
*/
nsresult ContinueOnAuthAvailable(const nsCSubstring& creds);
private:
- nsCOMPtr<nsIInputStream> mUploadStream;
nsCOMPtr<nsISupports> mSecurityInfo;
nsCOMPtr<nsICancelable> mProxyRequest;
nsRefPtr<nsInputStreamPump> mTransactionPump;
nsRefPtr<nsHttpTransaction> mTransaction;
PRUint64 mLogicalOffset;
nsCString mUserSetCookieHeader;
@@ -313,17 +310,16 @@ private:
nsCString mFallbackKey;
// state flags
PRUint32 mApplyConversion : 1;
PRUint32 mCachedContentIsValid : 1;
PRUint32 mCachedContentIsPartial : 1;
PRUint32 mCanceled : 1;
PRUint32 mTransactionReplaced : 1;
- PRUint32 mUploadStreamHasHeaders : 1;
PRUint32 mAuthRetryPending : 1;
// True when we need to authenticate to proxy, i.e. when we get 407
// response. Used in OnAuthAvailable and OnAuthCancelled callbacks.
PRUint32 mProxyAuth : 1;
PRUint32 mTriedProxyAuth : 1;
PRUint32 mTriedHostAuth : 1;
PRUint32 mSuppressDefensiveAuth : 1;
PRUint32 mResuming : 1;