1999-11-08 00:55:12 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1999-11-30 07:50:42 +03:00
|
|
|
#include "nsNetUtil.h"
|
1999-11-08 00:55:12 +03:00
|
|
|
#include "nsIComponentManager.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsSpecialSystemDirectory.h"
|
|
|
|
#include "nsJARChannel.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsIFileTransportService.h"
|
|
|
|
#include "nsIURL.h"
|
|
|
|
#include "nsIMIMEService.h"
|
2000-01-24 06:54:20 +03:00
|
|
|
#include "nsAutoLock.h"
|
2000-01-25 00:28:28 +03:00
|
|
|
#include "nsIFileStreams.h"
|
2000-01-29 03:06:15 +03:00
|
|
|
#include "nsIPrincipal.h"
|
2000-02-09 08:04:52 +03:00
|
|
|
#include "nsMimeTypes.h"
|
1999-11-08 00:55:12 +03:00
|
|
|
|
|
|
|
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
|
1999-11-12 09:13:13 +03:00
|
|
|
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
2000-02-01 02:43:09 +03:00
|
|
|
static NS_DEFINE_CID(kFileChannelCID, NS_FILECHANNEL_CID);
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class nsJARDownloadObserver : public nsIStreamObserver
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
NS_IMETHOD OnStartRequest(nsIChannel* jarCacheTransport,
|
|
|
|
nsISupports* context) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD OnStopRequest(nsIChannel* jarCacheTransport,
|
|
|
|
nsISupports* context,
|
|
|
|
nsresult status,
|
|
|
|
const PRUnichar* aMsg) {
|
|
|
|
nsresult rv = NS_OK;
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mJARChannel->mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(status) && mJARChannel->mJarCacheTransport) {
|
2000-01-24 07:45:54 +03:00
|
|
|
NS_ASSERTION(jarCacheTransport == (mJARChannel->mJarCacheTransport).get(),
|
2000-01-24 06:54:20 +03:00
|
|
|
"wrong transport");
|
1999-11-08 00:55:12 +03:00
|
|
|
// after successfully downloading the jar file to the cache,
|
|
|
|
// start the extraction process:
|
1999-12-03 05:22:48 +03:00
|
|
|
nsCOMPtr<nsIFileChannel> jarCacheFile;
|
2000-01-25 00:28:28 +03:00
|
|
|
rv = NS_NewFileChannel(mJarCacheFile,
|
|
|
|
PR_RDONLY,
|
|
|
|
nsnull, // XXX content type
|
|
|
|
0, // XXX content length
|
|
|
|
mJARChannel->mLoadGroup,
|
|
|
|
mJARChannel->mCallbacks,
|
|
|
|
mJARChannel->mLoadAttributes,
|
|
|
|
nsnull,
|
|
|
|
mJARChannel->mBufferSegmentSize,
|
|
|
|
mJARChannel->mBufferMaxSize,
|
|
|
|
getter_AddRefs(jarCacheFile));
|
1999-12-03 05:22:48 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
rv = mJARChannel->ExtractJARElement(jarCacheFile);
|
|
|
|
}
|
2000-01-24 06:54:20 +03:00
|
|
|
mJARChannel->mJarCacheTransport = nsnull;
|
1999-11-08 00:55:12 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel) {
|
1999-11-08 00:55:12 +03:00
|
|
|
NS_INIT_REFCNT();
|
1999-12-03 05:22:48 +03:00
|
|
|
mJarCacheFile = jarCacheFile;
|
1999-11-08 00:55:12 +03:00
|
|
|
mJARChannel = jarChannel;
|
|
|
|
NS_ADDREF(mJARChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~nsJARDownloadObserver() {
|
|
|
|
NS_RELEASE(mJARChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2000-01-25 00:28:28 +03:00
|
|
|
nsCOMPtr<nsIFile> mJarCacheFile;
|
1999-11-08 00:55:12 +03:00
|
|
|
nsJARChannel* mJARChannel;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
nsJARChannel::nsJARChannel()
|
|
|
|
: mCommand(nsnull),
|
|
|
|
mContentType(nsnull),
|
2000-02-01 02:43:09 +03:00
|
|
|
mJAREntry(nsnull),
|
|
|
|
mMonitor(nsnull)
|
1999-11-08 00:55:12 +03:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsJARChannel::~nsJARChannel()
|
|
|
|
{
|
|
|
|
if (mCommand)
|
|
|
|
nsCRT::free(mCommand);
|
|
|
|
if (mContentType)
|
|
|
|
nsCRT::free(mContentType);
|
|
|
|
if (mJAREntry)
|
|
|
|
nsCRT::free(mJAREntry);
|
2000-02-01 02:43:09 +03:00
|
|
|
if (mMonitor)
|
|
|
|
PR_DestroyMonitor(mMonitor);
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS6(nsJARChannel,
|
|
|
|
nsIJARChannel,
|
|
|
|
nsIChannel,
|
|
|
|
nsIRequest,
|
|
|
|
nsIStreamObserver,
|
|
|
|
nsIStreamListener,
|
|
|
|
nsIFileSystem)
|
|
|
|
|
|
|
|
NS_METHOD
|
|
|
|
nsJARChannel::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (aOuter)
|
|
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
|
|
|
|
|
|
nsJARChannel* jarChannel = new nsJARChannel();
|
|
|
|
if (jarChannel == nsnull)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(jarChannel);
|
|
|
|
rv = jarChannel->QueryInterface(aIID, aResult);
|
|
|
|
NS_RELEASE(jarChannel);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-11-17 11:14:52 +03:00
|
|
|
nsJARChannel::Init(nsIJARProtocolHandler* aHandler,
|
|
|
|
const char* command,
|
|
|
|
nsIURI* uri,
|
|
|
|
nsILoadGroup* aLoadGroup,
|
1999-11-18 10:36:41 +03:00
|
|
|
nsIInterfaceRequestor* notificationCallbacks,
|
1999-11-17 11:14:52 +03:00
|
|
|
nsLoadFlags loadAttributes,
|
1999-12-04 13:01:32 +03:00
|
|
|
nsIURI* originalURI,
|
|
|
|
PRUint32 bufferSegmentSize,
|
|
|
|
PRUint32 bufferMaxSize)
|
1999-11-08 00:55:12 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
mURI = do_QueryInterface(uri, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
mCommand = nsCRT::strdup(command);
|
|
|
|
if (mCommand == nsnull)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-01-19 10:20:31 +03:00
|
|
|
mOriginalURI = originalURI ? originalURI : uri;
|
1999-12-04 13:01:32 +03:00
|
|
|
mBufferSegmentSize = bufferSegmentSize;
|
|
|
|
mBufferMaxSize = bufferMaxSize;
|
1999-11-17 11:14:52 +03:00
|
|
|
|
|
|
|
rv = SetLoadAttributes(loadAttributes);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = SetLoadGroup(aLoadGroup);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = SetNotificationCallbacks(notificationCallbacks);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-02-01 02:43:09 +03:00
|
|
|
mMonitor = PR_NewMonitor();
|
|
|
|
if (mMonitor == nsnull)
|
2000-01-24 06:54:20 +03:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIRequest methods
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::IsPending(PRBool* result)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::Cancel()
|
|
|
|
{
|
2000-01-24 06:54:20 +03:00
|
|
|
nsresult rv;
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
|
|
|
if (mJarCacheTransport) {
|
|
|
|
rv = mJarCacheTransport->Cancel();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
mJarCacheTransport = nsnull;
|
|
|
|
}
|
|
|
|
if (mJarExtractionTransport) {
|
|
|
|
rv = mJarExtractionTransport->Cancel();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
mJarExtractionTransport = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::Suspend()
|
|
|
|
{
|
2000-01-24 06:54:20 +03:00
|
|
|
nsresult rv;
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
|
|
|
if (mJarCacheTransport) {
|
|
|
|
rv = mJarCacheTransport->Suspend();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
if (mJarExtractionTransport) {
|
|
|
|
rv = mJarExtractionTransport->Suspend();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::Resume()
|
|
|
|
{
|
2000-01-24 06:54:20 +03:00
|
|
|
nsresult rv;
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
|
|
|
if (mJarCacheTransport) {
|
|
|
|
rv = mJarCacheTransport->Resume();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
if (mJarExtractionTransport) {
|
|
|
|
rv = mJarExtractionTransport->Resume();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIChannel methods
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetOriginalURI(nsIURI* *aOriginalURI)
|
|
|
|
{
|
|
|
|
*aOriginalURI = mOriginalURI;
|
|
|
|
NS_ADDREF(*aOriginalURI);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetURI(nsIURI* *aURI)
|
|
|
|
{
|
|
|
|
*aURI = mURI;
|
|
|
|
NS_ADDREF(*aURI);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
|
|
|
nsIInputStream* *result)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream* *result)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::AsyncOpen(nsIStreamObserver* observer, nsISupports* ctxt)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
|
|
|
nsISupports* ctxt,
|
|
|
|
nsIStreamListener* listener)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = mURI->GetJAREntry(&mJAREntry);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChannel> jarBaseChannel;
|
|
|
|
rv = NS_OpenURI(getter_AddRefs(jarBaseChannel),
|
1999-11-17 11:14:52 +03:00
|
|
|
mJARBaseURI, mLoadGroup, mCallbacks, mLoadAttributes);
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFileChannel> jarBaseFile = do_QueryInterface(jarBaseChannel, &rv);
|
|
|
|
|
|
|
|
// XXX need to set a state variable here to say we're reading
|
|
|
|
mStartPosition = startPosition;
|
|
|
|
mReadCount = readCount;
|
|
|
|
mUserContext = ctxt;
|
|
|
|
mUserListener = listener;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// then we've already got a local jar file -- no need to download it
|
|
|
|
rv = ExtractJARElement(jarBaseFile);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// otherwise, we need to download the jar file
|
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
nsCOMPtr<nsIFile> jarCacheFile;
|
|
|
|
rv = GetCacheFile(getter_AddRefs(jarCacheFile));
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-01-25 00:28:28 +03:00
|
|
|
|
|
|
|
PRBool filePresent;
|
|
|
|
|
|
|
|
rv = jarCacheFile->IsFile(&filePresent);
|
|
|
|
|
2000-02-01 02:43:09 +03:00
|
|
|
if (NS_SUCCEEDED(rv) && filePresent)
|
2000-01-25 00:28:28 +03:00
|
|
|
{
|
2000-01-19 10:20:31 +03:00
|
|
|
// then we've already got the file in the local cache -- no need to download it
|
2000-02-01 02:43:09 +03:00
|
|
|
nsCOMPtr<nsIFileChannel> fileChannel;
|
|
|
|
rv = nsComponentManager::CreateInstance(kFileChannelCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIFileChannel),
|
|
|
|
getter_AddRefs(fileChannel));
|
2000-01-19 10:20:31 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-02-01 02:43:09 +03:00
|
|
|
rv = fileChannel->Init(jarCacheFile,
|
|
|
|
PR_RDONLY,
|
|
|
|
nsnull, // contentType
|
|
|
|
-1, // contentLength
|
|
|
|
nsnull, // loadGroup
|
|
|
|
nsnull, // notificationCallbacks
|
|
|
|
nsIChannel::LOAD_NORMAL,
|
|
|
|
nsnull, // originalURI
|
|
|
|
mBufferSegmentSize,
|
|
|
|
mBufferMaxSize);
|
2000-01-19 10:20:31 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-02-01 02:43:09 +03:00
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
rv = ExtractJARElement(fileChannel);
|
2000-01-19 10:20:31 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
// use a file transport to serve as a data pump for the download (done
|
|
|
|
// on some other thread)
|
2000-01-25 00:28:28 +03:00
|
|
|
nsCOMPtr<nsIChannel> jarCacheTransport;
|
|
|
|
rv = fts->CreateTransport(jarCacheFile, PR_RDONLY, mCommand,
|
1999-12-04 13:01:32 +03:00
|
|
|
mBufferSegmentSize, mBufferMaxSize,
|
2000-01-24 06:54:20 +03:00
|
|
|
getter_AddRefs(mJarCacheTransport));
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-24 06:54:20 +03:00
|
|
|
rv = mJarCacheTransport->SetNotificationCallbacks(mCallbacks);
|
1999-11-17 11:14:52 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-12-03 05:22:48 +03:00
|
|
|
nsCOMPtr<nsIStreamObserver> downloadObserver = new nsJARDownloadObserver(jarCacheFile, this);
|
1999-11-08 00:55:12 +03:00
|
|
|
if (downloadObserver == nsnull)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInputStream> jarBaseIn;
|
|
|
|
rv = jarBaseChannel->OpenInputStream(0, -1, getter_AddRefs(jarBaseIn));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-24 06:54:20 +03:00
|
|
|
rv = mJarCacheTransport->AsyncWrite(jarBaseIn, 0, -1, nsnull, downloadObserver);
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-01-25 00:28:28 +03:00
|
|
|
nsJARChannel::GetCacheFile(nsIFile* *cacheFile)
|
1999-11-08 00:55:12 +03:00
|
|
|
{
|
|
|
|
// XXX change later to use the real network cache
|
|
|
|
nsresult rv;
|
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
nsCOMPtr<nsIFile> jarCacheFile;
|
|
|
|
rv = NS_GetSpecialDirectory("xpcom.currentProcess.componentDirectory",
|
|
|
|
getter_AddRefs(jarCacheFile));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
jarCacheFile->Append("jarCache");
|
1999-11-08 00:55:12 +03:00
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
PRBool exists;
|
|
|
|
rv = jarCacheFile->Exists(&exists);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (!exists) {
|
|
|
|
rv = jarCacheFile->Create(nsIFile::DIRECTORY_TYPE, 0664);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-12-03 05:22:48 +03:00
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
nsCOMPtr<nsIURL> jarBaseURL = do_QueryInterface(mJARBaseURI, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
char* jarFileName;
|
|
|
|
rv = jarBaseURL->GetFileName(&jarFileName);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-02-01 02:43:09 +03:00
|
|
|
rv = jarCacheFile->Append(jarFileName);
|
1999-11-08 00:55:12 +03:00
|
|
|
nsCRT::free(jarFileName);
|
2000-02-01 02:43:09 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-08 00:55:12 +03:00
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
*cacheFile = jarCacheFile;
|
|
|
|
NS_ADDREF(*cacheFile);
|
1999-11-08 00:55:12 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsJARChannel::ExtractJARElement(nsIFileChannel* jarBaseFile)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2000-02-01 02:43:09 +03:00
|
|
|
nsAutoMonitor monitor(mMonitor);
|
2000-01-24 06:54:20 +03:00
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
mJARBaseFile = jarBaseFile;
|
|
|
|
|
|
|
|
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-17 11:14:52 +03:00
|
|
|
rv = fts->CreateTransportFromFileSystem(this, mCommand,
|
1999-12-04 13:01:32 +03:00
|
|
|
mBufferSegmentSize, mBufferMaxSize,
|
2000-01-24 06:54:20 +03:00
|
|
|
getter_AddRefs(mJarExtractionTransport));
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-24 06:54:20 +03:00
|
|
|
rv = mJarExtractionTransport->SetNotificationCallbacks(mCallbacks);
|
1999-11-17 11:14:52 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-24 06:54:20 +03:00
|
|
|
rv = mJarExtractionTransport->AsyncRead(mStartPosition, mReadCount, nsnull, this);
|
1999-11-08 00:55:12 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::AsyncWrite(nsIInputStream* fromStream, PRUint32 startPosition,
|
|
|
|
PRInt32 writeCount,
|
|
|
|
nsISupports* ctxt,
|
|
|
|
nsIStreamObserver* observer)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetLoadAttributes(PRUint32* aLoadFlags)
|
|
|
|
{
|
|
|
|
*aLoadFlags = mLoadAttributes;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::SetLoadAttributes(PRUint32 aLoadFlags)
|
|
|
|
{
|
|
|
|
mLoadAttributes = aLoadFlags;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetContentType(char* *aContentType)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (mContentType == nsnull) {
|
|
|
|
char* fileName = new char[PL_strlen(mJAREntry)+1];
|
|
|
|
PL_strcpy(fileName, mJAREntry);
|
|
|
|
|
|
|
|
if (fileName != nsnull) {
|
|
|
|
PRInt32 len = nsCRT::strlen(fileName);
|
|
|
|
const char* ext = nsnull;
|
|
|
|
for (PRInt32 i = len; i >= 0; i--) {
|
|
|
|
if (fileName[i] == '.') {
|
|
|
|
ext = &fileName[i + 1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ext) {
|
|
|
|
NS_WITH_SERVICE(nsIMIMEService, mimeServ, kMIMEServiceCID, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = mimeServ->GetTypeFromExtension(ext, &mContentType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCRT::free(fileName);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
2000-02-09 08:04:52 +03:00
|
|
|
mContentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE);
|
1999-11-08 00:55:12 +03:00
|
|
|
if (mContentType == nsnull)
|
|
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
else
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
*aContentType = nsCRT::strdup(mContentType);
|
|
|
|
if (*aContentType == nsnull)
|
|
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-01-08 09:26:04 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::SetContentType(const char *aContentType)
|
|
|
|
{
|
|
|
|
if (mContentType) {
|
|
|
|
nsCRT::free(mContentType);
|
|
|
|
}
|
|
|
|
|
|
|
|
mContentType = nsCRT::strdup(aContentType);
|
|
|
|
if (!mContentType) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetContentLength(PRInt32* aContentLength)
|
|
|
|
{
|
|
|
|
if (mContentLength == -1)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
*aContentLength = mContentLength;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
|
|
|
{
|
|
|
|
*aLoadGroup = mLoadGroup;
|
|
|
|
NS_IF_ADDREF(*aLoadGroup);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-17 11:14:52 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
|
|
|
{
|
|
|
|
mLoadGroup = aLoadGroup;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetOwner(nsISupports* *aOwner)
|
|
|
|
{
|
2000-02-14 04:59:09 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
nsresult rv = mJAR->GetPrincipal(mJAREntry, getter_AddRefs(principal));
|
|
|
|
if (NS_SUCCEEDED(rv) && principal)
|
|
|
|
rv = principal->QueryInterface(NS_GET_IID(nsISupports), (void **)aOwner);
|
|
|
|
else
|
|
|
|
*aOwner = nsnull;
|
2000-01-29 03:06:15 +03:00
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::SetOwner(nsISupports* aOwner)
|
|
|
|
{
|
2000-02-14 04:59:09 +03:00
|
|
|
//XXX: is this OK?
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
1999-11-17 11:14:52 +03:00
|
|
|
NS_IMETHODIMP
|
1999-11-18 10:36:41 +03:00
|
|
|
nsJARChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
1999-11-17 11:14:52 +03:00
|
|
|
{
|
|
|
|
*aNotificationCallbacks = mCallbacks.get();
|
|
|
|
NS_IF_ADDREF(*aNotificationCallbacks);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-18 10:36:41 +03:00
|
|
|
nsJARChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
1999-11-17 11:14:52 +03:00
|
|
|
{
|
|
|
|
mCallbacks = aNotificationCallbacks;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-08 00:55:12 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIStreamObserver methods:
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-01-24 06:54:20 +03:00
|
|
|
nsJARChannel::OnStartRequest(nsIChannel* jarExtractionTransport,
|
1999-11-08 00:55:12 +03:00
|
|
|
nsISupports* context)
|
|
|
|
{
|
|
|
|
return mUserListener->OnStartRequest(this, mUserContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-01-24 06:54:20 +03:00
|
|
|
nsJARChannel::OnStopRequest(nsIChannel* jarExtractionTransport,
|
1999-11-08 00:55:12 +03:00
|
|
|
nsISupports* context,
|
|
|
|
nsresult status,
|
|
|
|
const PRUnichar* aMsg)
|
|
|
|
{
|
2000-01-24 06:54:20 +03:00
|
|
|
nsresult rv;
|
|
|
|
rv = mUserListener->OnStopRequest(this, mUserContext, status, aMsg);
|
|
|
|
mJarExtractionTransport = nsnull;
|
|
|
|
return rv;
|
1999-11-08 00:55:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIStreamListener methods:
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::OnDataAvailable(nsIChannel* jarCacheTransport,
|
|
|
|
nsISupports* context,
|
|
|
|
nsIInputStream *inStr,
|
|
|
|
PRUint32 sourceOffset,
|
|
|
|
PRUint32 count)
|
|
|
|
{
|
|
|
|
return mUserListener->OnDataAvailable(this, mUserContext,
|
|
|
|
inStr, sourceOffset, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIFileSystem methods:
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
2000-02-14 04:59:09 +03:00
|
|
|
rv = nsComponentManager::CreateInstance(kZipReaderCID,
|
1999-11-12 09:13:13 +03:00
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIZipReader),
|
|
|
|
getter_AddRefs(mJAR));
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
nsCOMPtr<nsIFile> fs;
|
|
|
|
rv = mJARBaseFile->GetFile(getter_AddRefs(fs));
|
1999-11-12 09:13:13 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = mJAR->Init(fs);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-08 00:55:12 +03:00
|
|
|
|
1999-11-12 09:13:13 +03:00
|
|
|
rv = mJAR->Open();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-02-02 04:30:12 +03:00
|
|
|
// If this fails, GetOwner will fail, but otherwise we can continue.
|
2000-02-14 04:59:09 +03:00
|
|
|
mJAR->ParseManifest();
|
2000-02-02 04:30:12 +03:00
|
|
|
|
1999-11-12 09:13:13 +03:00
|
|
|
nsCOMPtr<nsIZipEntry> entry;
|
|
|
|
rv = mJAR->GetEntry(mJAREntry, getter_AddRefs(entry));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-08 00:55:12 +03:00
|
|
|
|
1999-11-12 09:13:13 +03:00
|
|
|
rv = entry->GetRealSize((PRUint32*)contentLength);
|
1999-11-08 00:55:12 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return GetContentType(contentType);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::Close(nsresult status)
|
|
|
|
{
|
|
|
|
mJAR = null_nsCOMPtr();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
|
|
|
{
|
|
|
|
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::GetOutputStream(nsIOutputStream* *aOutputStream)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIJARChannel methods:
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsJARChannel::EnumerateEntries(const char *aRoot, nsISimpleEnumerator **_retval)
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|