Fixes 127918. Mime Service was being accessed from a non-ui thread. This causes all kinds of problems. Found that content type is not needed while opening most stream io's. Removes content type result from nsIStreamIO::Open(). Added atrribute content type nsIStreamIO. Fixes callers. r=gordon@netscape.com, sr=darin@netscape.com, a=asa@mozilla.org.

This commit is contained in:
dougt%netscape.com 2002-03-13 00:34:54 +00:00
parent ef015e206d
commit 299b47cf06
12 changed files with 120 additions and 80 deletions

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -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<nsILocalFile> 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;
}

View File

@ -70,6 +70,7 @@ protected:
PRInt32 mIOFlags;
PRInt32 mPerm;
nsresult mStatus;
nsCString mContentType;
#ifdef PR_LOGGING
char* mSpec;
#endif

View File

@ -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;

View File

@ -122,7 +122,6 @@ protected:
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
nsCOMPtr<nsIStreamIO> mStreamIO;
char *mContentType;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;

View File

@ -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;

View File

@ -108,6 +108,7 @@ protected:
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
PRBool mOpened;
char* mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIStreamIO> mStreamIO;

View File

@ -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;
}

View File

@ -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();