Back out Bug 536324 part 2.
authorDan Witte <dwitte@mozilla.com>
Mon, 30 Aug 2010 13:20:39 -0700
changeset 51740 6e7ab6de94a790ed8bed3734de87c4842e5f2e4d
parent 51739 e78e4b846285ef12bfdedc36aa1216f54d09dbf2
child 51741 9c16981468a32802432ff3b12da2b1daf19572da
push id15410
push userdwitte@mozilla.com
push dateMon, 30 Aug 2010 22:36:08 +0000
treeherdermozilla-central@03e0a4afd870 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs536324
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out Bug 536324 part 2.
content/base/src/nsWebSocket.cpp
content/html/document/src/nsWyciwygChannel.cpp
content/html/document/src/nsWyciwygChannel.h
dom/src/jsurl/nsJSProtocolHandler.cpp
modules/libjar/nsJARChannel.cpp
modules/libjar/nsJARChannel.h
modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
modules/libpr0n/decoders/icon/beos/nsIconChannel.h
modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
modules/libpr0n/decoders/icon/os2/nsIconChannel.h
modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
modules/libpr0n/decoders/icon/win/nsIconChannel.h
netwerk/base/public/nsChannelProperties.h
netwerk/base/public/nsNetStrings.h
netwerk/base/src/nsBaseChannel.cpp
netwerk/base/src/nsBaseChannel.h
netwerk/base/src/nsNetStrings.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/viewsource/nsViewSourceChannel.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
uriloader/exthandler/nsExternalProtocolHandler.cpp
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -2402,18 +2402,18 @@ NOT_IMPLEMENTED_IF_FUNC_1(GetOwner, nsIS
 NOT_IMPLEMENTED_IF_FUNC_1(SetOwner, nsISupports *owner)
 NOT_IMPLEMENTED_IF_FUNC_1(SetNotificationCallbacks,
                           nsIInterfaceRequestor *callbacks)
 NOT_IMPLEMENTED_IF_FUNC_1(GetSecurityInfo, nsISupports **securityInfo)
 NOT_IMPLEMENTED_IF_FUNC_1(GetContentType, nsACString &value)
 NOT_IMPLEMENTED_IF_FUNC_1(SetContentType, const nsACString &value)
 NOT_IMPLEMENTED_IF_FUNC_1(GetContentCharset, nsACString &value)
 NOT_IMPLEMENTED_IF_FUNC_1(SetContentCharset, const nsACString &value)
-NOT_IMPLEMENTED_IF_FUNC_1(GetContentLength, PRInt64 *value)
-NOT_IMPLEMENTED_IF_FUNC_1(SetContentLength, PRInt64 value)
+NOT_IMPLEMENTED_IF_FUNC_1(GetContentLength, PRInt32 *value)
+NOT_IMPLEMENTED_IF_FUNC_1(SetContentLength, PRInt32 value)
 NOT_IMPLEMENTED_IF_FUNC_1(Open, nsIInputStream **_retval)
 NOT_IMPLEMENTED_IF_FUNC_2(AsyncOpen, nsIStreamListener *listener,
                           nsISupports *context)
 
 //-----------------------------------------------------------------------------
 // nsWebSocketEstablishedConnection::nsIHttpAuthenticableChannel
 //-----------------------------------------------------------------------------
 
--- a/content/html/document/src/nsWyciwygChannel.cpp
+++ b/content/html/document/src/nsWyciwygChannel.cpp
@@ -260,23 +260,23 @@ nsWyciwygChannel::GetContentCharset(nsAC
 
 NS_IMETHODIMP
 nsWyciwygChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsWyciwygChannel::GetContentLength(PRInt64 *aContentLength)
+nsWyciwygChannel::GetContentLength(PRInt32 *aContentLength)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsWyciwygChannel::SetContentLength(PRInt64 aContentLength)
+nsWyciwygChannel::SetContentLength(PRInt32 aContentLength)
 {
   mContentLength = aContentLength;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWyciwygChannel::Open(nsIInputStream ** aReturn)
@@ -501,19 +501,20 @@ nsWyciwygChannel::OnDataAvailable(nsIReq
 {
   LOG(("nsWyciwygChannel::OnDataAvailable [this=%x request=%x offset=%u count=%u]\n",
       this, request, offset, count));
 
   nsresult rv;
   
   rv = mListener->OnDataAvailable(this, mListenerContext, input, offset, count);
 
+  // XXX handle 64-bit stuff for real
   if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
     mProgressSink->OnProgress(this, nsnull, PRUint64(offset + count),
-                              mContentLength);
+                              PRUint64(mContentLength));
 
   return rv; // let the pump cancel on failure
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // nsIRequestObserver
 //////////////////////////////////////////////////////////////////////////////
 
--- a/content/html/document/src/nsWyciwygChannel.h
+++ b/content/html/document/src/nsWyciwygChannel.h
@@ -89,17 +89,17 @@ protected:
 
     void NotifyListener();
        
     nsresult                            mStatus;
     PRPackedBool                        mIsPending;
     PRPackedBool                        mNeedToWriteCharset;
     PRInt32                             mCharsetSource;
     nsCString                           mCharset;
-    PRInt64                             mContentLength;
+    PRInt32                             mContentLength;
     PRUint32                            mLoadFlags;
     nsCOMPtr<nsIURI>                    mURI;
     nsCOMPtr<nsIURI>                    mOriginalURI;
     nsCOMPtr<nsISupports>               mOwner;
     nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
     nsCOMPtr<nsIProgressEventSink>      mProgressSink;
     nsCOMPtr<nsILoadGroup>              mLoadGroup;
     nsCOMPtr<nsIStreamListener>         mListener;
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -1007,23 +1007,23 @@ nsJSChannel::GetContentCharset(nsACStrin
 
 NS_IMETHODIMP
 nsJSChannel::SetContentCharset(const nsACString &aContentCharset)
 {
     return mStreamChannel->SetContentCharset(aContentCharset);
 }
 
 NS_IMETHODIMP
-nsJSChannel::GetContentLength(PRInt64 *aContentLength)
+nsJSChannel::GetContentLength(PRInt32 *aContentLength)
 {
     return mStreamChannel->GetContentLength(aContentLength);
 }
 
 NS_IMETHODIMP
-nsJSChannel::SetContentLength(PRInt64 aContentLength)
+nsJSChannel::SetContentLength(PRInt32 aContentLength)
 {
     return mStreamChannel->SetContentLength(aContentLength);
 }
 
 NS_IMETHODIMP
 nsJSChannel::OnStartRequest(nsIRequest* aRequest,
                             nsISupports* aContext)
 {
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -107,32 +107,32 @@ public:
             mJarReader->Close();
     }
 
     void GetJarReader(nsIZipReader **result)
     {
         NS_IF_ADDREF(*result = mJarReader);
     }
 
-    PRInt64 GetContentLength()
+    PRInt32 GetContentLength()
     {
         return mContentLength;
     }
 
     nsresult EnsureJarStream();
 
 private:
 
     nsCOMPtr<nsIZipReaderCache> mJarCache;
     nsCOMPtr<nsIZipReader>      mJarReader;
     nsCOMPtr<nsIFile>           mJarFile;
     nsCString                   mJarDirSpec;
     nsCOMPtr<nsIInputStream>    mJarStream;
     nsCString                   mJarEntry;
-    PRInt64                     mContentLength;
+    PRInt32                     mContentLength;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsJARInputThunk, nsIInputStream)
 
 nsresult
 nsJARInputThunk::EnsureJarStream()
 {
     if (mJarStream)
@@ -168,21 +168,18 @@ nsJARInputThunk::EnsureJarStream()
         // convert to the proper result if the entry wasn't found
         // so that error pages work
         if (rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
             rv = NS_ERROR_FILE_NOT_FOUND;
         return rv;
     }
 
     // ask the JarStream for the content length
-    // XXX want a 64-bit value from nsIInputStream::Available()
-    PRUint32 contentLength;
-    rv = mJarStream->Available(&contentLength);
+    rv = mJarStream->Available((PRUint32 *) &mContentLength);
     if (NS_FAILED(rv)) return rv;
-    mContentLength = contentLength;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARInputThunk::Close()
 {
     if (mJarStream)
@@ -627,28 +624,28 @@ nsJARChannel::GetContentCharset(nsACStri
 NS_IMETHODIMP
 nsJARChannel::SetContentCharset(const nsACString &aContentCharset)
 {
     mContentCharset = aContentCharset;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJARChannel::GetContentLength(PRInt64 *result)
+nsJARChannel::GetContentLength(PRInt32 *result)
 {
     // if content length is unknown, query mJarInput...
     if (mContentLength < 0 && mJarInput)
         mContentLength = mJarInput->GetContentLength();
 
     *result = mContentLength;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJARChannel::SetContentLength(PRInt64 aContentLength)
+nsJARChannel::SetContentLength(PRInt32 aContentLength)
 {
     // XXX does this really make any sense at all?
     mContentLength = aContentLength;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARChannel::Open(nsIInputStream **stream)
@@ -900,19 +897,19 @@ nsJARChannel::OnDataAvailable(nsIRequest
                                PRUint32 offset, PRUint32 count)
 {
 #if defined(PR_LOGGING)
     LOG(("nsJARChannel::OnDataAvailable [this=%x %s]\n", this, mSpec.get()));
 #endif
 
     nsresult rv;
 
-    // XXX want 64-bit values in OnDataAvailable
     rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
 
     // simply report progress here instead of hooking ourselves up as a
     // nsITransportEventSink implementation.
+    // XXX do the 64-bit stuff for real
     if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
         mProgressSink->OnProgress(this, nsnull, PRUint64(offset + count),
-                                  mContentLength);
+                                  PRUint64(mContentLength));
 
     return rv; // let the pump cancel on failure
 }
--- a/modules/libjar/nsJARChannel.h
+++ b/modules/libjar/nsJARChannel.h
@@ -91,17 +91,17 @@ private:
     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
     nsCOMPtr<nsISupports>           mSecurityInfo;
     nsCOMPtr<nsIProgressEventSink>  mProgressSink;
     nsCOMPtr<nsILoadGroup>          mLoadGroup;
     nsCOMPtr<nsIStreamListener>     mListener;
     nsCOMPtr<nsISupports>           mListenerContext;
     nsCString                       mContentType;
     nsCString                       mContentCharset;
-    PRInt64                         mContentLength;
+    PRInt32                         mContentLength;
     PRUint32                        mLoadFlags;
     nsresult                        mStatus;
     PRPackedBool                    mIsPending;
     PRPackedBool                    mIsUnsafe;
 
     nsJARInputThunk                *mJarInput;
     nsCOMPtr<nsIStreamListener>     mDownloader;
     nsCOMPtr<nsIInputStreamPump>    mPump;
--- a/modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
@@ -402,23 +402,23 @@ NS_IMETHODIMP nsIconChannel::GetContentC
 NS_IMETHODIMP
 nsIconChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   // It doesn't make sense to set the content-charset on this type
   // of channel...
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt64 *aContentLength)
+NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
 {
   *aContentLength = mContentLength;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt64 aContentLength)
+NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
 {
   NS_NOTREACHED("nsIconChannel::SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
 {
   *aOwner = mOwner.get();
--- a/modules/libpr0n/decoders/icon/beos/nsIconChannel.h
+++ b/modules/libpr0n/decoders/icon/beos/nsIconChannel.h
@@ -64,17 +64,17 @@ public:
   nsIconChannel();
   ~nsIconChannel();
 
   nsresult Init(nsIURI* uri);
 
 protected:
   nsCOMPtr<nsIURI> mUrl;
   nsCOMPtr<nsIURI> mOriginalURI;
-  PRInt64          mContentLength;
+  PRInt32          mContentLength;
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   nsCOMPtr<nsISupports>  mOwner; 
 
   nsCOMPtr<nsIInputStreamPump> mPump;
   nsCOMPtr<nsIStreamListener>  mListener;
 
   nsresult ExtractIconInfoFromUrl(nsIFile ** aLocalFile, PRUint32 * aDesiredImageSize, nsACString &aContentType, nsACString &aFileExtension);
--- a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -394,23 +394,23 @@ NS_IMETHODIMP nsIconChannel::GetContentC
 NS_IMETHODIMP
 nsIconChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   //It doesn't make sense to set the content-type on this type
   // of channel...
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt64 *aContentLength)
+NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
 {
   *aContentLength = mContentLength;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt64 aContentLength)
+NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
 {
   NS_NOTREACHED("nsIconChannel::SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
 {
   *aLoadGroup = mLoadGroup;
--- a/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
@@ -631,23 +631,23 @@ NS_IMETHODIMP nsIconChannel::GetContentC
 NS_IMETHODIMP
 nsIconChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   // It doesn't make sense to set the content-charset on this type
   // of channel...
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt64 *aContentLength)
+NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
 {
   *aContentLength = mContentLength;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt64 aContentLength)
+NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
 {
   NS_NOTREACHED("nsIconChannel::SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
 {
   *aOwner = mOwner.get();
--- a/modules/libpr0n/decoders/icon/os2/nsIconChannel.h
+++ b/modules/libpr0n/decoders/icon/os2/nsIconChannel.h
@@ -65,17 +65,17 @@ public:
   nsIconChannel();
   virtual ~nsIconChannel();
 
   nsresult Init(nsIURI* uri);
 
 protected:
   nsCOMPtr<nsIURI> mUrl;
   nsCOMPtr<nsIURI> mOriginalURI;
-  PRInt64          mContentLength;
+  PRInt32          mContentLength;
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   nsCOMPtr<nsISupports>  mOwner; 
 
   nsCOMPtr<nsIInputStreamPump> mPump;
   nsCOMPtr<nsIStreamListener>  mListener;
 
   nsresult ExtractIconInfoFromUrl(nsIFile ** aLocalFile, PRUint32 * aDesiredImageSize, nsACString &aContentType, nsACString &aFileExtension);
--- a/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
@@ -688,23 +688,23 @@ NS_IMETHODIMP nsIconChannel::GetContentC
 NS_IMETHODIMP
 nsIconChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   // It doesn't make sense to set the content-charset on this type
   // of channel...
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt64 *aContentLength)
+NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
 {
   *aContentLength = mContentLength;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt64 aContentLength)
+NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
 {
   NS_NOTREACHED("nsIconChannel::SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
 {
   *aOwner = mOwner.get();
--- a/modules/libpr0n/decoders/icon/win/nsIconChannel.h
+++ b/modules/libpr0n/decoders/icon/win/nsIconChannel.h
@@ -67,17 +67,17 @@ public:
   nsIconChannel();
   ~nsIconChannel();
 
   nsresult Init(nsIURI* uri);
 
 protected:
   nsCOMPtr<nsIURI> mUrl;
   nsCOMPtr<nsIURI> mOriginalURI;
-  PRInt64          mContentLength;
+  PRInt32          mContentLength;
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   nsCOMPtr<nsISupports>  mOwner; 
 
   nsCOMPtr<nsIInputStreamPump> mPump;
   nsCOMPtr<nsIStreamListener>  mListener;
 
   nsresult ExtractIconInfoFromUrl(nsIFile ** aLocalFile, PRUint32 * aDesiredImageSize, nsCString &aContentType, nsCString &aFileExtension);
--- a/netwerk/base/public/nsChannelProperties.h
+++ b/netwerk/base/public/nsChannelProperties.h
@@ -46,32 +46,43 @@
  * @file
  * This file contains constants for properties channels can expose.
  * They can be accessed by using QueryInterface to access the nsIPropertyBag
  * or nsIPropertyBag2 interface on a channel and reading the value.
  */
 
 
 /**
+ * Content-Length of a channel. Used instead of the nsIChannel.contentLength
+ * property.
+ * Not available before onStartRequest has been called.
+ * Type: PRUint64
+ */
+#define NS_CHANNEL_PROP_CONTENT_LENGTH_STR "content-length"
+
+/**
  * MIME Content-Disposition header of channel.  
  * Not available before onStartRequest. 
  * Type: nsACString
  */
 #define NS_CHANNEL_PROP_CONTENT_DISPOSITION_STR "content-disposition"
 
 /**
  * Exists to allow content policy mechanism to function properly during channel
  * redirects.  Contains security contextual information about the load.
  * Type: nsIChannelPolicy
  */
 #define NS_CHANNEL_PROP_CHANNEL_POLICY_STR "channel-policy"
 
 #ifdef IMPL_NS_NET
+#define NS_CHANNEL_PROP_CONTENT_LENGTH gNetStrings->kContentLength
 #define NS_CHANNEL_PROP_CONTENT_DISPOSITION gNetStrings->kContentDisposition
 #define NS_CHANNEL_PROP_CHANNEL_POLICY gNetStrings->kChannelPolicy
 #else
+#define NS_CHANNEL_PROP_CONTENT_LENGTH \
+  NS_LITERAL_STRING(NS_CHANNEL_PROP_CONTENT_LENGTH_STR)
 #define NS_CHANNEL_PROP_CONTENT_DISPOSITION \
   NS_LITERAL_STRING(NS_CHANNEL_PROP_CONTENT_DISPOSITION_STR)
 #define NS_CHANNEL_PROP_CHANNEL_POLICY \
   NS_LITERAL_STRING(NS_CHANNEL_PROP_CHANNEL_POLICY_STR)
 #endif
 
 #endif
--- a/netwerk/base/public/nsNetStrings.h
+++ b/netwerk/base/public/nsNetStrings.h
@@ -42,16 +42,18 @@
 /**
  * Class on which wide strings are available, to avoid constructing strings
  * wherever these strings are used.
  */
 class nsNetStrings {
 public:
   nsNetStrings();
 
+  /** "content-length" */
+  const nsLiteralString kContentLength;
   const nsLiteralString kContentDisposition;
   const nsLiteralString kChannelPolicy;
 };
 
 extern NS_HIDDEN_(nsNetStrings*) gNetStrings;
 
 
 #endif
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -81,18 +81,17 @@ private:
 // usually needed when a function makes callbacks that could process events.
 #define SUSPEND_PUMP_FOR_SCOPE() \
   ScopedRequestSuspender pump_suspender__(mPump)
 
 //-----------------------------------------------------------------------------
 // nsBaseChannel
 
 nsBaseChannel::nsBaseChannel()
-  : mContentLength(-1)
-  , mLoadFlags(LOAD_NORMAL)
+  : mLoadFlags(LOAD_NORMAL)
   , mStatus(NS_OK)
   , mQueriedProgressSink(PR_TRUE)
   , mSynthProgressEvents(PR_FALSE)
   , mWasOpened(PR_FALSE)
   , mWaitingOnAsyncRedirect(PR_FALSE)
 {
   mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
 }
@@ -181,16 +180,33 @@ nsBaseChannel::ContinueRedirect()
 
 PRBool
 nsBaseChannel::HasContentTypeHint() const
 {
   NS_ASSERTION(!IsPending(), "HasContentTypeHint called too late");
   return !mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE);
 }
 
+void
+nsBaseChannel::SetContentLength64(PRInt64 len)
+{
+  // XXX: Storing the content-length as a property may not be what we want.
+  //      It has the drawback of being copied if we redirect this channel.
+  //      Maybe it is time for nsIChannel2.
+  SetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, len);
+}
+
+PRInt64
+nsBaseChannel::ContentLength64()
+{
+  PRInt64 len;
+  nsresult rv = GetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, &len);
+  return NS_SUCCEEDED(rv) ? len : -1;
+}
+
 nsresult
 nsBaseChannel::PushStreamConverter(const char *fromType,
                                    const char *toType,
                                    PRBool invalidatesContentLength,
                                    nsIStreamListener **result)
 {
   NS_ASSERTION(mListener, "no listener");
 
@@ -201,17 +217,17 @@ nsBaseChannel::PushStreamConverter(const
     return rv;
 
   nsCOMPtr<nsIStreamListener> converter;
   rv = scs->AsyncConvertData(fromType, toType, mListener, mListenerContext,
                              getter_AddRefs(converter));
   if (NS_SUCCEEDED(rv)) {
     mListener = converter;
     if (invalidatesContentLength)
-      mContentLength = -1;
+      SetContentLength64(-1);
     if (result) {
       *result = nsnull;
       converter.swap(*result);
     }
   }
   return rv;
 }
 
@@ -499,26 +515,30 @@ nsBaseChannel::GetContentCharset(nsACStr
 NS_IMETHODIMP
 nsBaseChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   mContentCharset = aContentCharset;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBaseChannel::GetContentLength(PRInt64 *aContentLength)
+nsBaseChannel::GetContentLength(PRInt32 *aContentLength)
 {
-  *aContentLength = mContentLength;
+  PRInt64 len = ContentLength64();
+  if (len > PR_INT32_MAX || len < 0)
+    *aContentLength = -1;
+  else
+    *aContentLength = (PRInt32) len;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBaseChannel::SetContentLength(PRInt64 aContentLength)
+nsBaseChannel::SetContentLength(PRInt32 aContentLength)
 {
-  mContentLength = aContentLength;
+  SetContentLength64(aContentLength);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::Open(nsIInputStream **result)
 {
   NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_INITIALIZED);
   NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
@@ -730,17 +750,18 @@ nsBaseChannel::OnDataAvailable(nsIReques
                                PRUint32 count)
 {
   SUSPEND_PUMP_FOR_SCOPE();
 
   nsresult rv = mListener->OnDataAvailable(this, mListenerContext, stream,
                                            offset, count);
   if (mSynthProgressEvents && NS_SUCCEEDED(rv)) {
     PRUint64 prog = PRUint64(offset) + count;
-    OnTransportStatus(nsnull, nsITransport::STATUS_READING, prog, mContentLength);
+    PRUint64 progMax = ContentLength64();
+    OnTransportStatus(nsnull, nsITransport::STATUS_READING, prog, progMax);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::OnRedirectVerifyCallback(nsresult result)
 {
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -180,21 +180,20 @@ public:
     return (mLoadFlags & flag) != 0;
   }
 
   // This is a short-cut to calling nsIRequest::IsPending()
   PRBool IsPending() const {
     return mPump || mWaitingOnAsyncRedirect;
   }
 
-  // Get or set the content length that should be reported for this channel.  -1
-  // indicates an unspecified content length.
-  PRInt64& ContentLength() {
-    return mContentLength;
-  }
+  // Set the content length that should be reported for this channel.  Pass -1
+  // to indicate an unspecified content length.
+  void SetContentLength64(PRInt64 len);
+  PRInt64 ContentLength64();
 
   // Helper function for querying the channel's notification callbacks.
   template <class T> void GetCallback(nsCOMPtr<T> &result) {
     GetInterface(NS_GET_TEMPLATE_IID(T), getter_AddRefs(result));
   }
 
   // Helper function for calling QueryInterface on this.
   nsQueryInterface do_QueryInterface() {
@@ -285,17 +284,16 @@ private:
   nsCOMPtr<nsILoadGroup>              mLoadGroup;
   nsCOMPtr<nsISupports>               mOwner;
   nsCOMPtr<nsISupports>               mSecurityInfo;
   nsCOMPtr<nsIStreamListener>         mListener;
   nsCOMPtr<nsISupports>               mListenerContext;
   nsCOMPtr<nsIChannel>                mRedirectChannel;
   nsCString                           mContentType;
   nsCString                           mContentCharset;
-  PRInt64                             mContentLength;
   PRUint32                            mLoadFlags;
   nsresult                            mStatus;
   PRPackedBool                        mQueriedProgressSink;
   PRPackedBool                        mSynthProgressEvents;
   PRPackedBool                        mWasOpened;
   PRPackedBool                        mWaitingOnAsyncRedirect;
   PRPackedBool                        mOpenRedirectChannel;
   PRUint32                            mRedirectFlags;
--- a/netwerk/base/src/nsNetStrings.cpp
+++ b/netwerk/base/src/nsNetStrings.cpp
@@ -35,13 +35,14 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsNetStrings.h"
 #include "nsChannelProperties.h"
 
 NS_HIDDEN_(nsNetStrings*) gNetStrings;
 
 nsNetStrings::nsNetStrings()
-  : NS_LITERAL_STRING_INIT(kContentDisposition, NS_CHANNEL_PROP_CONTENT_DISPOSITION_STR),
+  : NS_LITERAL_STRING_INIT(kContentLength, NS_CHANNEL_PROP_CONTENT_LENGTH_STR),
+    NS_LITERAL_STRING_INIT(kContentDisposition, NS_CHANNEL_PROP_CONTENT_DISPOSITION_STR),
     NS_LITERAL_STRING_INIT(kChannelPolicy, NS_CHANNEL_PROP_CHANNEL_POLICY_STR)
 {}
 
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -354,27 +354,30 @@ HttpBaseChannel::SetContentCharset(const
   } else {
     // Charset hint
     mContentCharsetHint = aContentCharset;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpBaseChannel::GetContentLength(PRInt64 *aContentLength)
+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(PRInt64 value)
+HttpBaseChannel::SetContentLength(PRInt32 value)
 {
   NS_NOTYETIMPLEMENTED("nsHttpChannel::SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::Open(nsIInputStream **aResult)
 {
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -124,18 +124,18 @@ public:
   NS_IMETHOD GetOwner(nsISupports **aOwner);
   NS_IMETHOD SetOwner(nsISupports *aOwner);
   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(PRInt64 *aContentLength);
-  NS_IMETHOD SetContentLength(PRInt64 aContentLength);
+  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);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -758,16 +758,20 @@ nsHttpChannel::CallOnStartRequest()
                 }
             }
         }
     }
 
     if (mResponseHead && mResponseHead->ContentCharset().IsEmpty())
         mResponseHead->SetContentCharset(mContentCharsetHint);
 
+    if (mResponseHead)
+        SetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH,
+                           mResponseHead->ContentLength());
+
     // Allow consumers to override our content type
     if ((mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) &&
         gIOService->GetContentSniffers().Count() != 0) {
         // NOTE: We can have both a txn pump and a cache pump when the cache
         // content is partial. In that case, we need to read from the cache,
         // because that's the one that has the initial contents. If that fails
         // then give the transaction pump a shot.
 
@@ -2454,26 +2458,26 @@ nsHttpChannel::CheckCache()
 
     PRUint16 isCachedRedirect = mCachedResponseHead->Status()/100 == 3;
 
     if (method != nsHttp::Head && !isCachedRedirect) {
         // If the cached content-length is set and it does not match the data
         // size of the cached content, then the cached response is partial...
         // either we need to issue a byte range request or we need to refetch
         // the entire document.
-        PRInt64 contentLength = mCachedResponseHead->ContentLength();
-        if (contentLength != -1) {
+        nsInt64 contentLength = mCachedResponseHead->ContentLength();
+        if (contentLength != nsInt64(-1)) {
             PRUint32 size;
             rv = mCacheEntry->GetDataSize(&size);
             NS_ENSURE_SUCCESS(rv, rv);
 
-            if (PRInt64(size) != contentLength) {
+            if (nsInt64(size) != contentLength) {
                 LOG(("Cached data size does not match the Content-Length header "
-                     "[content-length=%lld size=%u]\n", contentLength, size));
-                if ((PRInt64(size) < contentLength) && mCachedResponseHead->IsResumable()) {
+                     "[content-length=%lld size=%u]\n", PRInt64(contentLength), size));
+                if ((nsInt64(size) < contentLength) && mCachedResponseHead->IsResumable()) {
                     // looks like a partial entry.
                     rv = SetupByteRangeRequest(size);
                     NS_ENSURE_SUCCESS(rv, rv);
                     mCachedContentIsPartial = PR_TRUE;
                 }
                 return NS_OK;
             }
         }
@@ -4064,17 +4068,17 @@ nsHttpChannel::OnDataAvailable(nsIReques
         else
             transportStatus = nsISocketTransport::STATUS_RECEIVING_FROM;
 
         // mResponseHead may reference new or cached headers, but either way it
         // holds our best estimate of the total content length.  Even in the case
         // of a byte range request, the content length stored in the cached
         // response headers is what we want to use here.
 
-        PRUint64 progressMax(mResponseHead->ContentLength());
+        PRUint64 progressMax(PRUint64(mResponseHead->ContentLength()));
         PRUint64 progress = mLogicalOffset + PRUint64(count);
         NS_ASSERTION(progress <= progressMax, "unexpected progress values");
 
         OnTransportStatus(nsnull, transportStatus, progress, progressMax);
 
         //
         // we have to manually keep the logical offset of the stream up-to-date.
         // we cannot depend solely on the offset provided, since we may have 
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -365,25 +365,25 @@ NS_IMETHODIMP
 nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
 
     return mChannel->SetContentCharset(aContentCharset);
 }
 
 NS_IMETHODIMP
-nsViewSourceChannel::GetContentLength(PRInt64 *aContentLength)
+nsViewSourceChannel::GetContentLength(PRInt32 *aContentLength)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
 
     return mChannel->GetContentLength(aContentLength);
 }
 
 NS_IMETHODIMP
-nsViewSourceChannel::SetContentLength(PRInt64 aContentLength)
+nsViewSourceChannel::SetContentLength(PRInt32 aContentLength)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
 
     return mChannel->SetContentLength(aContentLength);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
@@ -32,16 +32,17 @@
  * 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 "nsMultiMixedConv.h"
 #include "nsMemory.h"
+#include "nsInt64.h"
 #include "plstr.h"
 #include "nsIHttpChannel.h"
 #include "nsIServiceManager.h"
 #include "nsNetUtil.h"
 #include "nsMimeTypes.h"
 #include "nsIStringStream.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
@@ -318,24 +319,24 @@ nsPartChannel::GetContentCharset(nsACStr
 NS_IMETHODIMP
 nsPartChannel::SetContentCharset(const nsACString &aContentCharset)
 {
     mContentCharset = aContentCharset;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPartChannel::GetContentLength(PRInt64 *aContentLength)
+nsPartChannel::GetContentLength(PRInt32 *aContentLength)
 {
-    *aContentLength = mContentLength;
+    *aContentLength = mContentLength; // XXX truncates 64-bit value
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPartChannel::SetContentLength(PRInt64 aContentLength)
+nsPartChannel::SetContentLength(PRInt32 aContentLength)
 {
     mContentLength = aContentLength;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPartChannel::GetContentDisposition(nsACString &aContentDisposition)
 {
@@ -791,17 +792,17 @@ nsMultiMixedConv::SendStart(nsIChannel *
     mTotalSent = 0;
 
     // Set up the new part channel...
     mPartChannel = newChannel;
 
     rv = mPartChannel->SetContentType(mContentType);
     if (NS_FAILED(rv)) return rv;
 
-    rv = mPartChannel->SetContentLength(mContentLength);
+    rv = mPartChannel->SetContentLength(mContentLength); // XXX Truncates 64-bit!
     if (NS_FAILED(rv)) return rv;
 
     rv = mPartChannel->SetContentDisposition(mContentDisposition);
     if (NS_FAILED(rv)) return rv;
 
     nsLoadFlags loadFlags = 0;
     mPartChannel->GetLoadFlags(&loadFlags);
     loadFlags |= nsIChannel::LOAD_REPLACE;
@@ -933,17 +934,17 @@ nsMultiMixedConv::ParseHeaders(nsIChanne
 
             nsCAutoString headerVal(colon + 1);
             headerVal.CompressWhitespace();
 
             // examine header
             if (headerStr.LowerCaseEqualsLiteral("content-type")) {
                 mContentType = headerVal;
             } else if (headerStr.LowerCaseEqualsLiteral("content-length")) {
-                PR_sscanf(headerVal.get(), "%lld", &mContentLength);
+                mContentLength = atoi(headerVal.get()); // XXX 64-bit math?
             } else if (headerStr.LowerCaseEqualsLiteral("content-disposition")) {
                 mContentDisposition = headerVal;
             } else if (headerStr.LowerCaseEqualsLiteral("set-cookie")) {
                 nsCOMPtr<nsIHttpChannelInternal> httpInternal =
                     do_QueryInterface(aChannel);
                 if (httpInternal) {
                     httpInternal->SetCookie(headerVal.get());
                 }
@@ -974,17 +975,17 @@ nsMultiMixedConv::ParseHeaders(nsIChanne
                     
                     mByteRangeStart = atoi(range); // XXX want 64-bit conv
                     tmpPtr++;
                     mByteRangeEnd = atoi(tmpPtr);
                 }
 
                 mIsByteRangeRequest = PR_TRUE;
                 if (mContentLength == LL_MAXUINT)
-                    mContentLength = PRUint64(PRInt64(mByteRangeEnd - mByteRangeStart + 1));
+                    mContentLength = PRUint64(PRInt64(mByteRangeEnd - mByteRangeStart + nsInt64(1)));
             }
         }
         *newLine = tmpChar;
         newLine += lineFeedIncrement;
         cursorLen -= (newLine - cursor);
         cursor = newLine;
     }
 
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -242,24 +242,24 @@ NS_IMETHODIMP nsExtProtocolChannel::GetC
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::SetContentCharset(const nsACString &aContentCharset)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP nsExtProtocolChannel::GetContentLength(PRInt64 * aContentLength)
+NS_IMETHODIMP nsExtProtocolChannel::GetContentLength(PRInt32 * aContentLength)
 {
   *aContentLength = -1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsExtProtocolChannel::SetContentLength(PRInt64 aContentLength)
+nsExtProtocolChannel::SetContentLength(PRInt32 aContentLength)
 {
   NS_NOTREACHED("SetContentLength");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::GetOwner(nsISupports * *aPrincipal)
 {
   NS_NOTREACHED("GetOwner");