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 idunknown
push userunknown
push dateunknown
bugs536324
milestone2.0b5pre
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");