diff --git a/dom/src/jsurl/nsJSProtocolHandler.cpp b/dom/src/jsurl/nsJSProtocolHandler.cpp index 8f9780f97853..c9775734cf45 100644 --- a/dom/src/jsurl/nsJSProtocolHandler.cpp +++ b/dom/src/jsurl/nsJSProtocolHandler.cpp @@ -335,7 +335,7 @@ nsresult nsJSThunk::BringUpConsole() // nsIStreamIO implementation... // NS_IMETHODIMP -nsJSThunk::Open(char* *contentType, PRInt32 *contentLength) +nsJSThunk::Open(PRInt32 *contentLength) { // // At this point the script has already been evaluated... @@ -343,12 +343,23 @@ nsJSThunk::Open(char* *contentType, PRInt32 *contentLength) // // If the resultant script evaluation actually does return a value, we // treat it as html. - *contentType = nsCRT::strdup("text/html"); *contentLength = mLength; return NS_OK; } + +NS_IMETHODIMP +nsJSThunk::GetContentType(char * *aContentType) +{ + *aContentType = nsCRT::strdup("text/html"); + + if (*aContentType == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + NS_IMETHODIMP nsJSThunk::Close(nsresult status) { diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index e4b13d2b004a..73b5f721d3b1 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -240,7 +240,8 @@ nsJARChannel::OpenJARElement() { nsresult rv; nsAutoCMonitor mon(this); - rv = Open(nsnull, nsnull); + PRInt32 len; + rv = Open(&len); // is there a better way.... where is my C++ book?! if (NS_SUCCEEDED(rv)) rv = GetInputStream(getter_AddRefs(mSynchronousInputStream)); mon.Notify(); // wake up nsIChannel::Open @@ -646,7 +647,7 @@ nsJARChannel::EnsureZipReader() } NS_IMETHODIMP -nsJARChannel::Open(char* *contentType, PRInt32 *contentLength) +nsJARChannel::Open(PRInt32 *contentLength) { nsresult rv; rv = EnsureZipReader(); @@ -661,10 +662,6 @@ nsJARChannel::Open(char* *contentType, PRInt32 *contentLength) if (NS_FAILED(rv)) return rv; } - if (contentType) { - rv = GetContentType(contentType); - if (NS_FAILED(rv)) return rv; - } return rv; } diff --git a/modules/libjar/nsJARChannel.h b/modules/libjar/nsJARChannel.h index 654a195d0c7f..0f1f7bb91479 100644 --- a/modules/libjar/nsJARChannel.h +++ b/modules/libjar/nsJARChannel.h @@ -84,9 +84,16 @@ public: NS_DECL_NSIJARCHANNEL NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER - NS_DECL_NSISTREAMIO NS_DECL_NSIDOWNLOADOBSERVER + // NS_DECL_NSISTREAMIO and nsIChannel both define (attribute string contentType) + + NS_IMETHOD Open(PRInt32 *contentLength); + NS_IMETHOD Close(nsresult status); + NS_IMETHOD GetInputStream(nsIInputStream * *aInputStream); + NS_IMETHOD GetOutputStream(nsIOutputStream * *aOutputStream); + NS_IMETHOD GetName(char * *aName); + nsJARChannel(); virtual ~nsJARChannel(); diff --git a/netwerk/base/public/nsIStreamIO.idl b/netwerk/base/public/nsIStreamIO.idl index a4e45df57b3f..1e6a9511e888 100644 --- a/netwerk/base/public/nsIStreamIO.idl +++ b/netwerk/base/public/nsIStreamIO.idl @@ -51,11 +51,10 @@ interface nsIFile; interface nsIStreamIO : nsISupports { /** - * Logically opens a stream I/O object, returning its content type - * and length. If either of these are unknown, the value -1 is returned. + * Logically opens a stream I/O object, returning its content length + * If this is unknown, the value -1 is returned. */ - void open(out string contentType, - out long contentLength); + void open(out long contentLength); /** * Logically closes a stream I/O object. A status value is passed in @@ -74,10 +73,15 @@ interface nsIStreamIO : nsISupports readonly attribute nsIOutputStream outputStream; /** - * Returns the 'name' of a stream I/O object. This name is often + * The 'name' of a stream I/O object. This name is often * used for display purposes. */ readonly attribute string name; + + /** + * Associated content type, if any. + **/ + readonly attribute string contentType; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/netwerk/base/src/nsFileStreams.cpp b/netwerk/base/src/nsFileStreams.cpp index 508e2bb9da6d..98469cef8343 100644 --- a/netwerk/base/src/nsFileStreams.cpp +++ b/netwerk/base/src/nsFileStreams.cpp @@ -169,7 +169,7 @@ nsFileIO::GetFile(nsIFile* *aFile) } NS_IMETHODIMP -nsFileIO::Open(char **contentType, PRInt32 *contentLength) +nsFileIO::Open(PRInt32 *contentLength) { NS_ASSERTION(mFile, "File must not be null"); if (mFile == nsnull) @@ -177,9 +177,7 @@ nsFileIO::Open(char **contentType, PRInt32 *contentLength) if (contentLength) *contentLength = 0; - if (contentType) - *contentType = nsnull; - + nsresult rv = NS_OK; nsCOMPtr localFile = do_QueryInterface(mFile, &rv); if (NS_FAILED(rv)) return rv; @@ -193,13 +191,6 @@ nsFileIO::Open(char **contentType, PRInt32 *contentLength) PRBool isDir; rv = localFile->IsDirectory(&isDir); if (NS_SUCCEEDED(rv) && isDir) { - // Directories turn into an HTTP-index stream, with - // unbounded (i.e., read 'til the stream says it's done) - // length. - if (contentType) - *contentType = nsCRT::strdup(APPLICATION_HTTP_INDEX_FORMAT); - if (contentLength) - *contentLength = -1; return NS_OK; } return NS_ERROR_FILE_NOT_FOUND; @@ -219,30 +210,45 @@ nsFileIO::Open(char **contentType, PRInt32 *contentLength) else *contentLength = -1; } - if (contentType) { - // must we really go though this? dougt - nsIMIMEService* mimeServ = nsnull; - nsFileTransportService* fileTransportService = nsFileTransportService::GetInstance(); - if (fileTransportService) { - mimeServ = fileTransportService->GetCachedMimeService(); - if (mimeServ) - rv = mimeServ->GetTypeFromFile(mFile, contentType); - } - - if (!mimeServ || (NS_FAILED(rv))) { - // if all else fails treat it as text/html? - *contentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE); - if (*contentType == nsnull) - rv = NS_ERROR_OUT_OF_MEMORY; - else - rv = NS_OK; - } - } PR_LOG(gFileIOLog, PR_LOG_DEBUG, ("nsFileIO: logically opening %s", mSpec)); return rv; } + +NS_IMETHODIMP +nsFileIO::GetContentType(char * *aContentType) +{ + if (!mContentType.IsEmpty()) { + *aContentType = ToNewCString(mContentType); + return NS_OK; + } + + if (mFile == nsnull) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + nsIMIMEService* mimeServ = nsnull; + nsFileTransportService* fileTransportService = nsFileTransportService::GetInstance(); + if (fileTransportService) { + mimeServ = fileTransportService->GetCachedMimeService(); + if (mimeServ) + rv = mimeServ->GetTypeFromFile(mFile, aContentType); + } + + if (!mimeServ || (NS_FAILED(rv))) { + // if all else fails treat it as text/html? + *aContentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE); + if (*aContentType == nsnull) + rv = NS_ERROR_OUT_OF_MEMORY; + else + rv = NS_OK; + } + + mContentType.Assign(*aContentType); + return rv; +} + NS_IMETHODIMP nsFileIO::Close(nsresult status) { @@ -266,7 +272,7 @@ nsFileIO::GetInputStream(nsIInputStream * *aInputStream) nsresult rv; if (!mFD) { - rv = Open(nsnull, nsnull); + rv = Open(nsnull); if (NS_FAILED(rv)) // file or directory does not exist return rv; } @@ -319,7 +325,7 @@ nsFileIO::GetOutputStream(nsIOutputStream * *aOutputStream) nsresult rv; if (!mFD) { - rv = Open(nsnull, nsnull); + rv = Open(nsnull); if (NS_FAILED(rv)) // file or directory does not exist return rv; } diff --git a/netwerk/base/src/nsFileStreams.h b/netwerk/base/src/nsFileStreams.h index 34be56661770..f7b129a901eb 100644 --- a/netwerk/base/src/nsFileStreams.h +++ b/netwerk/base/src/nsFileStreams.h @@ -70,6 +70,7 @@ protected: PRInt32 mIOFlags; PRInt32 mPerm; nsresult mStatus; + nsCString mContentType; #ifdef PR_LOGGING char* mSpec; #endif diff --git a/netwerk/base/src/nsFileTransport.cpp b/netwerk/base/src/nsFileTransport.cpp index c305e6f14160..0d6e5a8a819f 100644 --- a/netwerk/base/src/nsFileTransport.cpp +++ b/netwerk/base/src/nsFileTransport.cpp @@ -208,8 +208,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileTransportSinkWrapper, nsIOutputStream) ////////////////////////////////////////////////////////////////////////////////// nsFileTransport::nsFileTransport() - : mContentType(nsnull), - mBufferSegmentSize(NS_FILE_TRANSPORT_DEFAULT_SEGMENT_SIZE), + : mBufferSegmentSize(NS_FILE_TRANSPORT_DEFAULT_SEGMENT_SIZE), mBufferMaxSize(NS_FILE_TRANSPORT_DEFAULT_BUFFER_SIZE), mXferState(CLOSED), mRunState(RUNNING), @@ -292,11 +291,6 @@ nsFileTransport::~nsFileTransport() PR_DestroyLock(mLock); mLock = nsnull; } - if (mContentType) { - nsCRT::free(mContentType); - mContentType = nsnull; - } - NS_IF_RELEASE(mService); } @@ -652,7 +646,7 @@ nsFileTransport::Process(nsIProgressEventSink *progressSink) switch (mXferState) { case OPEN_FOR_READ: { - mStatus = mStreamIO->Open(&mContentType, &mTotalAmount); + mStatus = mStreamIO->Open(&mTotalAmount); LOG(("nsFileTransport: OPEN_FOR_READ [this=%x %s] status=%x\n", this, mStreamName.get(), mStatus)); if (mListener) { nsresult rv = mListener->OnStartRequest(this, mContext); // always send the start notification @@ -842,7 +836,7 @@ nsFileTransport::Process(nsIProgressEventSink *progressSink) case OPEN_FOR_WRITE: { LOG(("nsFileTransport: OPEN_FOR_WRITE [this=%x %s]\n", this, mStreamName.get())); - mStatus = mStreamIO->Open(&mContentType, &mTotalAmount); + mStatus = mStreamIO->Open(&mTotalAmount); if (mStatus == NS_ERROR_FILE_NOT_FOUND) mStatus = NS_OK; diff --git a/netwerk/base/src/nsFileTransport.h b/netwerk/base/src/nsFileTransport.h index 97edf81ccf1c..231806ea770b 100644 --- a/netwerk/base/src/nsFileTransport.h +++ b/netwerk/base/src/nsFileTransport.h @@ -122,7 +122,6 @@ protected: nsCOMPtr mProgressSink; nsCOMPtr mNotificationCallbacks; nsCOMPtr mStreamIO; - char *mContentType; PRUint32 mBufferSegmentSize; PRUint32 mBufferMaxSize; diff --git a/netwerk/base/src/nsInputStreamChannel.cpp b/netwerk/base/src/nsInputStreamChannel.cpp index 7afcb5af5afd..7e8ebe9b7d48 100644 --- a/netwerk/base/src/nsInputStreamChannel.cpp +++ b/netwerk/base/src/nsInputStreamChannel.cpp @@ -106,23 +106,34 @@ nsInputStreamIO::Init(const char* name, nsIInputStream* input, } NS_IMETHODIMP -nsInputStreamIO::Open(char **contentType, PRInt32 *contentLength) +nsInputStreamIO::Open(PRInt32 *contentLength) { - *contentType = nsCRT::strdup(mContentType); - if (*contentType == nsnull) - return NS_ERROR_OUT_OF_MEMORY; *contentLength = mContentLength; return NS_OK; } + +NS_IMETHODIMP +nsInputStreamIO::GetContentType(char * *aContentType) +{ + if (!mContentType) { + return NS_ERROR_OUT_OF_MEMORY; + } + *aContentType = nsCRT::strdup(mContentType); + if (*aContentType == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + NS_IMETHODIMP nsInputStreamIO::Close(nsresult status) { mStatus = status; if (mInputStream) return mInputStream->Close(); - else - return NS_OK; + + return NS_OK; } NS_IMETHODIMP @@ -152,7 +163,7 @@ nsInputStreamIO::GetName(char* *aName) // nsStreamIOChannel methods: nsStreamIOChannel::nsStreamIOChannel() - : mContentType(nsnull), mContentLength(-1), + : mOpened(PR_FALSE), mContentType(nsnull), mContentLength(-1), mBufferSegmentSize(0), mBufferMaxSize(0), mLoadFlags(LOAD_NORMAL), mStatus(NS_OK) { @@ -291,7 +302,10 @@ nsStreamIOChannel::GetURI(nsIURI* *aURI) NS_IMETHODIMP nsStreamIOChannel::Open(nsIInputStream **result) { - return mStreamIO->GetInputStream(result); + nsresult rv = mStreamIO->GetInputStream(result); + if (NS_SUCCEEDED(rv)) + mOpened = PR_TRUE; + return rv; } NS_IMETHODIMP @@ -314,6 +328,7 @@ nsStreamIOChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) rv = fts->CreateTransportFromStreamIO(mStreamIO, getter_AddRefs(mFileTransport)); if (NS_FAILED(rv)) goto done; + mOpened = PR_TRUE; } // Hook up the notification callbacks InterfaceRequestor... @@ -325,12 +340,6 @@ nsStreamIOChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) if (NS_FAILED(rv)) goto done; } -#if 0 - if (mContentType == nsnull) { - rv = mStreamIO->Open(&mContentType, &mContentLength); - if (NS_FAILED(rv)) goto done; - } -#endif rv = mFileTransport->AsyncRead(this, ctxt, 0, PRUint32(-1), 0, getter_AddRefs(mRequest)); done: @@ -417,7 +426,12 @@ nsStreamIOChannel::GetContentType(char * *aContentType) { nsresult rv; if (mContentType == nsnull) { - rv = mStreamIO->Open(&mContentType, &mContentLength); + if (!mOpened) { + rv = mStreamIO->Open(&mContentLength); + if (NS_FAILED(rv)) return rv; + mOpened = PR_TRUE; + } + mStreamIO->GetContentType(&mContentType); if (NS_FAILED(rv)) return rv; } *aContentType = nsCRT::strdup(mContentType); @@ -441,9 +455,10 @@ NS_IMETHODIMP nsStreamIOChannel::GetContentLength(PRInt32 *aContentLength) { nsresult rv; - if (mContentType == nsnull) { - rv = mStreamIO->Open(&mContentType, &mContentLength); + if (!mOpened) { + rv = mStreamIO->Open(&mContentLength); if (NS_FAILED(rv)) return rv; + mOpened = PR_TRUE; } *aContentLength = mContentLength; return NS_OK; @@ -483,6 +498,7 @@ nsStreamIOChannel::OnStopRequest(nsIRequest *request, nsISupports* context, nsre // Make sure the stream io is closed mStreamIO->Close(aStatus); + mOpened = PR_FALSE; // There is no point in returning anything other than NS_OK return NS_OK; diff --git a/netwerk/base/src/nsInputStreamChannel.h b/netwerk/base/src/nsInputStreamChannel.h index 1b970d838a07..258b4a7bea0d 100644 --- a/netwerk/base/src/nsInputStreamChannel.h +++ b/netwerk/base/src/nsInputStreamChannel.h @@ -108,6 +108,7 @@ protected: nsCOMPtr mProgressSink; nsCOMPtr mOriginalURI; nsCOMPtr mURI; + PRBool mOpened; char* mContentType; PRInt32 mContentLength; nsCOMPtr mStreamIO; diff --git a/netwerk/protocol/jar/src/nsJARChannel.cpp b/netwerk/protocol/jar/src/nsJARChannel.cpp index e4b13d2b004a..73b5f721d3b1 100644 --- a/netwerk/protocol/jar/src/nsJARChannel.cpp +++ b/netwerk/protocol/jar/src/nsJARChannel.cpp @@ -240,7 +240,8 @@ nsJARChannel::OpenJARElement() { nsresult rv; nsAutoCMonitor mon(this); - rv = Open(nsnull, nsnull); + PRInt32 len; + rv = Open(&len); // is there a better way.... where is my C++ book?! if (NS_SUCCEEDED(rv)) rv = GetInputStream(getter_AddRefs(mSynchronousInputStream)); mon.Notify(); // wake up nsIChannel::Open @@ -646,7 +647,7 @@ nsJARChannel::EnsureZipReader() } NS_IMETHODIMP -nsJARChannel::Open(char* *contentType, PRInt32 *contentLength) +nsJARChannel::Open(PRInt32 *contentLength) { nsresult rv; rv = EnsureZipReader(); @@ -661,10 +662,6 @@ nsJARChannel::Open(char* *contentType, PRInt32 *contentLength) if (NS_FAILED(rv)) return rv; } - if (contentType) { - rv = GetContentType(contentType); - if (NS_FAILED(rv)) return rv; - } return rv; } diff --git a/netwerk/protocol/jar/src/nsJARChannel.h b/netwerk/protocol/jar/src/nsJARChannel.h index 654a195d0c7f..0f1f7bb91479 100644 --- a/netwerk/protocol/jar/src/nsJARChannel.h +++ b/netwerk/protocol/jar/src/nsJARChannel.h @@ -84,9 +84,16 @@ public: NS_DECL_NSIJARCHANNEL NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER - NS_DECL_NSISTREAMIO NS_DECL_NSIDOWNLOADOBSERVER + // NS_DECL_NSISTREAMIO and nsIChannel both define (attribute string contentType) + + NS_IMETHOD Open(PRInt32 *contentLength); + NS_IMETHOD Close(nsresult status); + NS_IMETHOD GetInputStream(nsIInputStream * *aInputStream); + NS_IMETHOD GetOutputStream(nsIOutputStream * *aOutputStream); + NS_IMETHOD GetName(char * *aName); + nsJARChannel(); virtual ~nsJARChannel();