Bug 474536. Expose the underlying channel's content-disposition on jar: channels. r+sr=bzbarsky
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -41,16 +41,17 @@
#include "nsJARChannel.h"
#include "nsJARProtocolHandler.h"
#include "nsMimeTypes.h"
#include "nsNetUtil.h"
#include "nsInt64.h"
#include "nsEscape.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
+#include "nsChannelProperties.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsIFileURL.h"
#include "nsIJAR.h"
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
@@ -213,16 +214,19 @@ nsJARInputThunk::ReadSegments(nsWriteSeg
NS_IMETHODIMP
nsJARInputThunk::IsNonBlocking(PRBool *nonBlocking)
{
*nonBlocking = PR_FALSE;
return NS_OK;
}
//-----------------------------------------------------------------------------
+// nsJARChannel
+//-----------------------------------------------------------------------------
+
nsJARChannel::nsJARChannel()
: mContentLength(-1)
, mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
, mIsPending(PR_FALSE)
, mIsUnsafe(PR_TRUE)
, mJarInput(nsnull)
@@ -241,28 +245,33 @@ nsJARChannel::~nsJARChannel()
// with the exception of certain error cases mJarInput will already be null.
NS_IF_RELEASE(mJarInput);
// release owning reference to the jar handler
nsJARProtocolHandler *handler = gJarHandler;
NS_RELEASE(handler); // NULL parameter
}
-NS_IMPL_ISUPPORTS6(nsJARChannel,
- nsIRequest,
- nsIChannel,
- nsIStreamListener,
- nsIRequestObserver,
- nsIDownloadObserver,
- nsIJARChannel)
+NS_IMPL_ISUPPORTS_INHERITED6(nsJARChannel,
+ nsHashPropertyBag,
+ nsIRequest,
+ nsIChannel,
+ nsIStreamListener,
+ nsIRequestObserver,
+ nsIDownloadObserver,
+ nsIJARChannel)
nsresult
nsJARChannel::Init(nsIURI *uri)
{
nsresult rv;
+ rv = nsHashPropertyBag::Init();
+ if (NS_FAILED(rv))
+ return rv;
+
mJarURI = do_QueryInterface(uri, &rv);
if (NS_FAILED(rv))
return rv;
mOriginalURI = mJarURI;
// Prevent loading jar:javascript URIs (see bug 290982).
nsCOMPtr<nsIURI> innerURI;
@@ -747,41 +756,47 @@ nsJARChannel::OnDownloadComplete(nsIDown
}
if (NS_SUCCEEDED(status)) {
status = rv;
}
}
}
if (NS_SUCCEEDED(status) && channel) {
+ nsCAutoString header;
// Grab the security info from our base channel
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
// We only want to run scripts if the server really intended to
// send us a JAR file. Check the server-supplied content type for
// a JAR type.
- nsCAutoString header;
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"),
header);
-
nsCAutoString contentType;
nsCAutoString charset;
NS_ParseContentType(header, contentType, charset);
-
mIsUnsafe = !contentType.EqualsLiteral("application/java-archive") &&
!contentType.EqualsLiteral("application/x-jar");
+ rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Disposition"),
+ header);
+ if (NS_SUCCEEDED(rv))
+ SetPropertyAsACString(NS_CHANNEL_PROP_CONTENT_DISPOSITION, header);
} else {
nsCOMPtr<nsIJARChannel> innerJARChannel(do_QueryInterface(channel));
if (innerJARChannel) {
PRBool unsafe;
innerJARChannel->GetIsUnsafe(&unsafe);
mIsUnsafe = unsafe;
}
+ // Soon-to-be common way to get Disposition: right now only nsIJARChannel
+ rv = NS_GetContentDisposition(request, header);
+ if (NS_SUCCEEDED(rv))
+ SetPropertyAsACString(NS_CHANNEL_PROP_CONTENT_DISPOSITION, header);
}
}
if (NS_SUCCEEDED(status) && mIsUnsafe) {
PRBool allowUnpack = PR_FALSE;
nsCOMPtr<nsIPrefBranch> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID);
--- a/modules/libjar/nsJARChannel.h
+++ b/modules/libjar/nsJARChannel.h
@@ -42,29 +42,31 @@
#include "nsIJARURI.h"
#include "nsIInputStreamPump.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "nsIStreamListener.h"
#include "nsIZipReader.h"
#include "nsIDownloader.h"
#include "nsILoadGroup.h"
+#include "nsHashPropertyBag.h"
#include "nsIFile.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "prlog.h"
class nsJARInputThunk;
//-----------------------------------------------------------------------------
class nsJARChannel : public nsIJARChannel
, public nsIDownloadObserver
, public nsIStreamListener
+ , public nsHashPropertyBag
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSIJARCHANNEL
NS_DECL_NSIDOWNLOADOBSERVER
NS_DECL_NSIREQUESTOBSERVER
--- a/netwerk/base/public/nsChannelProperties.h
+++ b/netwerk/base/public/nsChannelProperties.h
@@ -53,16 +53,26 @@
/**
* 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"
+
#ifdef IMPL_NS_NET
#define NS_CHANNEL_PROP_CONTENT_LENGTH gNetStrings->kContentLength
+#define NS_CHANNEL_PROP_CONTENT_DISPOSITION gNetStrings->kContentDisposition
#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)
#endif
#endif
--- a/netwerk/base/public/nsNetStrings.h
+++ b/netwerk/base/public/nsNetStrings.h
@@ -44,14 +44,15 @@
* wherever these strings are used.
*/
class nsNetStrings {
public:
nsNetStrings();
/** "content-length" */
const nsLiteralString kContentLength;
+ const nsLiteralString kContentDisposition;
};
extern NS_HIDDEN_(nsNetStrings*) gNetStrings;
#endif
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -57,16 +57,17 @@
#include "nsIRequestObserverProxy.h"
#include "nsISimpleStreamListener.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
+#include "nsChannelProperties.h"
#include "nsIInputStreamChannel.h"
#include "nsITransport.h"
#include "nsIStreamTransportService.h"
#include "nsIHttpChannel.h"
#include "nsIDownloader.h"
#include "nsIStreamLoader.h"
#include "nsIUnicharStreamLoader.h"
#include "nsIPipe.h"
@@ -189,16 +190,29 @@ NS_NewChannel(nsIChannel **res
*result = chan;
else
NS_RELEASE(chan);
}
}
return rv;
}
+// For now, works only with JARChannel. Future: with all channels that may
+// have Content-Disposition header (JAR, nsIHttpChannel, and nsIMultiPartChannel).
+inline nsresult
+NS_GetContentDisposition(nsIRequest *channel,
+ nsACString &result)
+{
+ nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(channel));
+ if (props)
+ return props->GetPropertyAsACString(NS_CHANNEL_PROP_CONTENT_DISPOSITION,
+ result);
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
// Use this function with CAUTION. It creates a stream that blocks when you
// Read() from it and blocking the UI thread is a bad idea. If you don't want
// to implement a full blown asynchronous consumer (via nsIStreamListener) look
// at nsIStreamLoader instead.
inline nsresult
NS_OpenURI(nsIInputStream **result,
nsIURI *uri,
nsIIOService *ioService = nsnull, // pass in nsIIOService to optimize callers
--- a/netwerk/base/src/nsNetStrings.cpp
+++ b/netwerk/base/src/nsNetStrings.cpp
@@ -36,11 +36,12 @@
#include "nsNetStrings.h"
#include "nsChannelProperties.h"
NS_HIDDEN_(nsNetStrings*) gNetStrings;
nsNetStrings::nsNetStrings()
: NS_LITERAL_STRING_INIT(kContentLength, NS_CHANNEL_PROP_CONTENT_LENGTH_STR)
+ : NS_LITERAL_STRING_INIT(kContentDisposition, NS_CHANNEL_PROP_CONTENT_DISPOSITION_STR)
{}
--- a/netwerk/protocol/http/src/nsHttpAtomList.h
+++ b/netwerk/protocol/http/src/nsHttpAtomList.h
@@ -57,16 +57,17 @@ HTTP_ATOM(Accept_Language, "Ac
HTTP_ATOM(Accept_Ranges, "Accept-Ranges")
HTTP_ATOM(Age, "Age")
HTTP_ATOM(Allow, "Allow")
HTTP_ATOM(Authentication, "Authentication")
HTTP_ATOM(Authorization, "Authorization")
HTTP_ATOM(Cache_Control, "Cache-Control")
HTTP_ATOM(Connection, "Connection")
HTTP_ATOM(Content_Base, "Content-Base")
+HTTP_ATOM(Content_Disposition, "Content-Disposition")
HTTP_ATOM(Content_Encoding, "Content-Encoding")
HTTP_ATOM(Content_Language, "Content-Language")
HTTP_ATOM(Content_Length, "Content-Length")
HTTP_ATOM(Content_Location, "Content-Location")
HTTP_ATOM(Content_MD5, "Content-MD5")
HTTP_ATOM(Content_Range, "Content-Range")
HTTP_ATOM(Content_Transfer_Encoding, "Content-Transfer-Encoding")
HTTP_ATOM(Content_Type, "Content-Type")
--- a/netwerk/streamconv/test/Makefile.in
+++ b/netwerk/streamconv/test/Makefile.in
@@ -68,9 +68,8 @@ LDFLAGS += -SUBSYSTEM:CONSOLE
ifdef MOZ_NO_DEBUG_RTL
DEFINES += -MOZ_NO_DEBUG_RTL
endif
ifdef NGPREFS
DEFINES += -DNGPREFS
endif
endif # WINNT
-DEFINES += -DIMPL_NS_NET
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -60,17 +60,17 @@
#include "netCore.h"
#include "nsCRT.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
#include "nsXPIDLString.h"
#include "nsString.h"
-
+#include "nsNetUtil.h"
#include "nsIDOMWindowInternal.h"
#include "nsReadableUtils.h"
#include "nsDOMError.h"
#include "nsICategoryManager.h"
#include "nsCExternalHandlerService.h" // contains contractids for the helper app service
#include "nsIMIMEHeaderParam.h"
@@ -375,16 +375,19 @@ nsresult nsDocumentOpenInfo::DispatchCon
httpChannel->GetURI(getter_AddRefs(uri));
}
else
{
nsCOMPtr<nsIMultiPartChannel> multipartChannel(do_QueryInterface(request));
if (multipartChannel)
{
rv = multipartChannel->GetContentDisposition(disposition);
+ } else {
+ // Soon-to-be common way to get Disposition: right now only JARChannel
+ rv = NS_GetContentDisposition(request, disposition);
}
}
LOG((" Disposition header: '%s'", disposition.get()));
if (NS_SUCCEEDED(rv) && !disposition.IsEmpty())
{
nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);