зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 97528 "1200 urls created on startup about:blank" (take 2)
r=dp, sr=brendan
This commit is contained in:
Родитель
051c211df1
Коммит
819e81b079
|
@ -270,16 +270,20 @@ NS_IMETHODIMP
|
||||||
nsJARChannel::AsyncOpen(nsIStreamListener* listener, nsISupports* ctxt)
|
nsJARChannel::AsyncOpen(nsIStreamListener* listener, nsISupports* ctxt)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
mUserContext = ctxt;
|
mUserContext = ctxt;
|
||||||
mUserListener = listener;
|
mUserListener = listener;
|
||||||
|
mSynchronousRead = PR_FALSE;
|
||||||
|
|
||||||
if (mLoadGroup) {
|
if (mLoadGroup) {
|
||||||
rv = mLoadGroup->AddRequest(this, nsnull);
|
rv = mLoadGroup->AddRequest(this, nsnull);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSynchronousRead = PR_FALSE;
|
rv = EnsureJARFileAvailable();
|
||||||
return EnsureJARFileAvailable();
|
if (NS_FAILED(rv) && mLoadGroup)
|
||||||
|
mLoadGroup->RemoveRequest(this, nsnull, rv);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -288,30 +292,43 @@ nsJARChannel::EnsureJARFileAvailable()
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
||||||
if (NS_FAILED(rv)) goto error;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = mURI->GetJAREntry(&mJAREntry);
|
rv = mURI->GetJAREntry(&mJAREntry);
|
||||||
if (NS_FAILED(rv)) goto error;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = NS_NewDownloader(getter_AddRefs(mDownloader),
|
// try to get a nsIFile directly from the url, which will often succeed.
|
||||||
mJARBaseURI, this, nsnull, mSynchronousRead,
|
{
|
||||||
mLoadGroup, mCallbacks, mLoadFlags);
|
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mJARBaseURI);
|
||||||
|
if (fileURL)
|
||||||
|
fileURL->GetFile(getter_AddRefs(mDownloadedJARFile));
|
||||||
|
}
|
||||||
|
|
||||||
// if DownloadComplete() was called early, need to release the reference.
|
if (mDownloadedJARFile) {
|
||||||
if (mSynchronousRead && mSynchronousInputStream)
|
// after successfully downloading the jar file to the cache,
|
||||||
mDownloader = null_nsCOMPtr();
|
// start the extraction process:
|
||||||
|
if (mSynchronousRead)
|
||||||
|
rv = OpenJARElement();
|
||||||
|
else
|
||||||
|
rv = AsyncReadJARElement();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = NS_NewDownloader(getter_AddRefs(mDownloader),
|
||||||
|
mJARBaseURI, this, nsnull, mSynchronousRead,
|
||||||
|
mLoadGroup, mCallbacks, mLoadFlags);
|
||||||
|
|
||||||
error:
|
// if DownloadComplete() was called early, need to release the reference.
|
||||||
if (NS_FAILED(rv) && mLoadGroup) {
|
if (mSynchronousRead && mSynchronousInputStream)
|
||||||
nsresult rv2 = mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
|
mDownloader = 0;
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv2), "RemoveChannel failed");
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -340,10 +357,12 @@ nsJARChannel::AsyncReadJARElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = jarTransport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0,
|
rv = jarTransport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0,
|
||||||
|
@ -566,13 +585,15 @@ nsJARChannel::OnStopRequest(nsIRequest* jarExtractionTransport, nsISupports* con
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsCOMPtr<nsIURI> jarURI;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
nsXPIDLCString jarURLStr;
|
nsCOMPtr<nsIURI> jarURI;
|
||||||
rv = mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
if (NS_SUCCEEDED(rv)) {
|
rv = mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
if (NS_SUCCEEDED(rv)) {
|
||||||
("nsJarProtocol: jar extraction complete %s status=%x",
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
(const char*)jarURLStr, aStatus));
|
("nsJarProtocol: jar extraction complete %s status=%x",
|
||||||
|
(const char*)jarURLStr, aStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -656,10 +677,12 @@ NS_IMETHODIMP
|
||||||
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
||||||
{
|
{
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
NS_ENSURE_TRUE(mJAR, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(mJAR, NS_ERROR_NULL_POINTER);
|
||||||
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
||||||
|
|
|
@ -270,16 +270,20 @@ NS_IMETHODIMP
|
||||||
nsJARChannel::AsyncOpen(nsIStreamListener* listener, nsISupports* ctxt)
|
nsJARChannel::AsyncOpen(nsIStreamListener* listener, nsISupports* ctxt)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
mUserContext = ctxt;
|
mUserContext = ctxt;
|
||||||
mUserListener = listener;
|
mUserListener = listener;
|
||||||
|
mSynchronousRead = PR_FALSE;
|
||||||
|
|
||||||
if (mLoadGroup) {
|
if (mLoadGroup) {
|
||||||
rv = mLoadGroup->AddRequest(this, nsnull);
|
rv = mLoadGroup->AddRequest(this, nsnull);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSynchronousRead = PR_FALSE;
|
rv = EnsureJARFileAvailable();
|
||||||
return EnsureJARFileAvailable();
|
if (NS_FAILED(rv) && mLoadGroup)
|
||||||
|
mLoadGroup->RemoveRequest(this, nsnull, rv);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -288,30 +292,43 @@ nsJARChannel::EnsureJARFileAvailable()
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
|
||||||
if (NS_FAILED(rv)) goto error;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = mURI->GetJAREntry(&mJAREntry);
|
rv = mURI->GetJAREntry(&mJAREntry);
|
||||||
if (NS_FAILED(rv)) goto error;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = NS_NewDownloader(getter_AddRefs(mDownloader),
|
// try to get a nsIFile directly from the url, which will often succeed.
|
||||||
mJARBaseURI, this, nsnull, mSynchronousRead,
|
{
|
||||||
mLoadGroup, mCallbacks, mLoadFlags);
|
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mJARBaseURI);
|
||||||
|
if (fileURL)
|
||||||
|
fileURL->GetFile(getter_AddRefs(mDownloadedJARFile));
|
||||||
|
}
|
||||||
|
|
||||||
// if DownloadComplete() was called early, need to release the reference.
|
if (mDownloadedJARFile) {
|
||||||
if (mSynchronousRead && mSynchronousInputStream)
|
// after successfully downloading the jar file to the cache,
|
||||||
mDownloader = null_nsCOMPtr();
|
// start the extraction process:
|
||||||
|
if (mSynchronousRead)
|
||||||
|
rv = OpenJARElement();
|
||||||
|
else
|
||||||
|
rv = AsyncReadJARElement();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = NS_NewDownloader(getter_AddRefs(mDownloader),
|
||||||
|
mJARBaseURI, this, nsnull, mSynchronousRead,
|
||||||
|
mLoadGroup, mCallbacks, mLoadFlags);
|
||||||
|
|
||||||
error:
|
// if DownloadComplete() was called early, need to release the reference.
|
||||||
if (NS_FAILED(rv) && mLoadGroup) {
|
if (mSynchronousRead && mSynchronousInputStream)
|
||||||
nsresult rv2 = mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
|
mDownloader = 0;
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv2), "RemoveChannel failed");
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -340,10 +357,12 @@ nsJARChannel::AsyncReadJARElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = jarTransport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0,
|
rv = jarTransport->AsyncRead(this, nsnull, 0, PRUint32(-1), 0,
|
||||||
|
@ -566,13 +585,15 @@ nsJARChannel::OnStopRequest(nsIRequest* jarExtractionTransport, nsISupports* con
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsCOMPtr<nsIURI> jarURI;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
nsXPIDLCString jarURLStr;
|
nsCOMPtr<nsIURI> jarURI;
|
||||||
rv = mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
if (NS_SUCCEEDED(rv)) {
|
rv = mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
if (NS_SUCCEEDED(rv)) {
|
||||||
("nsJarProtocol: jar extraction complete %s status=%x",
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
(const char*)jarURLStr, aStatus));
|
("nsJarProtocol: jar extraction complete %s status=%x",
|
||||||
|
(const char*)jarURLStr, aStatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -656,10 +677,12 @@ NS_IMETHODIMP
|
||||||
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
|
||||||
{
|
{
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
nsXPIDLCString jarURLStr;
|
if (PR_LOG_TEST(gJarProtocolLog, PR_LOG_DEBUG)) {
|
||||||
mURI->GetSpec(getter_Copies(jarURLStr));
|
nsXPIDLCString jarURLStr;
|
||||||
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
mURI->GetSpec(getter_Copies(jarURLStr));
|
||||||
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
|
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
|
||||||
|
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
NS_ENSURE_TRUE(mJAR, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(mJAR, NS_ERROR_NULL_POINTER);
|
||||||
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
return mJAR->GetInputStream(mJAREntry, aInputStream);
|
||||||
|
|
|
@ -75,4 +75,9 @@ interface nsIResProtocolHandler : nsIProtocolHandler
|
||||||
* Returns true if substitutions are already defined for the specified root.
|
* Returns true if substitutions are already defined for the specified root.
|
||||||
*/
|
*/
|
||||||
boolean hasSubstitutions(in string root);
|
boolean hasSubstitutions(in string root);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolution utility function.
|
||||||
|
*/
|
||||||
|
string resolveURI(in nsIURI resourceURI);
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,6 @@ LIBRARY_NAME = nkres_s
|
||||||
REQUIRES = xpcom string exthandler mimetype
|
REQUIRES = xpcom string exthandler mimetype
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
nsResChannel.cpp \
|
|
||||||
nsResProtocolHandler.cpp \
|
nsResProtocolHandler.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -41,6 +40,10 @@ EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
|
||||||
# static lib.
|
# static lib.
|
||||||
FORCE_STATIC_LIB = 1
|
FORCE_STATIC_LIB = 1
|
||||||
|
|
||||||
|
LOCAL_INCLUDES = \
|
||||||
|
-I$(DEPTH)/netwerk/base/src \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
ifeq ($(OS_ARCH), Linux)
|
ifeq ($(OS_ARCH), Linux)
|
||||||
|
|
|
@ -28,10 +28,13 @@ LIBRARY_NAME=nkres_s
|
||||||
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
|
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
|
||||||
|
|
||||||
CPP_OBJS= \
|
CPP_OBJS= \
|
||||||
.\$(OBJDIR)\nsResChannel.obj \
|
|
||||||
.\$(OBJDIR)\nsResProtocolHandler.obj \
|
.\$(OBJDIR)\nsResProtocolHandler.obj \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
INCS = $(INCS) \
|
||||||
|
-I$(DEPTH)\netwerk\base\src \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
include <$(DEPTH)\config\rules.mak>
|
||||||
|
|
||||||
install:: $(LIBRARY)
|
install:: $(LIBRARY)
|
||||||
|
|
|
@ -1,651 +0,0 @@
|
||||||
/* -*- 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.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at http://www.mozilla.org/NPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS
|
|
||||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
* implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code is mozilla.org code.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is Netscape
|
|
||||||
* Communications Corporation. Portions created by Netscape are
|
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
||||||
* Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsResChannel.h"
|
|
||||||
#include "nsCRT.h"
|
|
||||||
#include "netCore.h"
|
|
||||||
#include "nsIServiceManager.h"
|
|
||||||
#include "nsIFileTransportService.h"
|
|
||||||
#include "nsIComponentManager.h"
|
|
||||||
#include "nsIURL.h"
|
|
||||||
#include "nsIIOService.h"
|
|
||||||
#include "nsXPIDLString.h"
|
|
||||||
#include "nsCExternalHandlerService.h"
|
|
||||||
#include "nsIMIMEService.h"
|
|
||||||
#include "nsNetUtil.h"
|
|
||||||
#include "nsMimeTypes.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|
||||||
|
|
||||||
#if defined(PR_LOGGING)
|
|
||||||
//
|
|
||||||
// Log module for nsResChannel logging...
|
|
||||||
//
|
|
||||||
// To enable logging (see prlog.h for full details):
|
|
||||||
//
|
|
||||||
// set NSPR_LOG_MODULES=nsResChannel:5
|
|
||||||
// set NSPR_LOG_FILE=nspr.log
|
|
||||||
//
|
|
||||||
// this enables PR_LOG_DEBUG level information and places all output in
|
|
||||||
// the file nspr.log
|
|
||||||
PRLogModuleInfo* gResChannelLog = nsnull;
|
|
||||||
|
|
||||||
#endif /* PR_LOGGING */
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
nsResChannel::nsResChannel()
|
|
||||||
: mLoadFlags(nsIResChannel::LOAD_NORMAL),
|
|
||||||
mState(QUIESCENT),
|
|
||||||
mStatus(NS_OK)
|
|
||||||
#ifdef DEBUG
|
|
||||||
,mInitiator(nsnull)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
NS_INIT_REFCNT();
|
|
||||||
#if defined(PR_LOGGING)
|
|
||||||
//
|
|
||||||
// Initialize the global PRLogModule for socket transport logging
|
|
||||||
// if necessary...
|
|
||||||
//
|
|
||||||
if (nsnull == gResChannelLog) {
|
|
||||||
gResChannelLog = PR_NewLogModule("nsResChannel");
|
|
||||||
}
|
|
||||||
#endif /* PR_LOGGING */
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsResChannel::Init(nsIResProtocolHandler* handler, nsIURI* uri)
|
|
||||||
{
|
|
||||||
mHandler = handler;
|
|
||||||
mResourceURI = uri;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsResChannel::~nsResChannel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ADDREF(nsResChannel)
|
|
||||||
NS_IMPL_THREADSAFE_RELEASE(nsResChannel)
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(nsResChannel)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIResChannel)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIFileChannel)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIResChannel)
|
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIResChannel)
|
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIResChannel)
|
|
||||||
NS_INTERFACE_MAP_END_THREADSAFE
|
|
||||||
|
|
||||||
NS_METHOD
|
|
||||||
nsResChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
|
||||||
{
|
|
||||||
nsResChannel* rc = new nsResChannel();
|
|
||||||
if (rc == nsnull)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
NS_ADDREF(rc);
|
|
||||||
nsresult rv = rc->QueryInterface(aIID, aResult);
|
|
||||||
NS_RELEASE(rc);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsResChannel::Substitutions
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsResChannel::Substitutions::Init()
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsResChannel* channel = GET_SUBSTITUTIONS_CHANNEL(this);
|
|
||||||
|
|
||||||
if (mSubstitutions)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
char* root;
|
|
||||||
rv = channel->mResourceURI->GetHost(&root);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
// XXX don't pass null to GetSubstitutions!
|
|
||||||
const char* strRoot = root ? root : "";
|
|
||||||
rv = channel->mHandler->GetSubstitutions(strRoot,
|
|
||||||
getter_AddRefs(mSubstitutions));
|
|
||||||
nsCRT::free(root);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsResChannel::Substitutions::Next(char* *result)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsResChannel* channel = GET_SUBSTITUTIONS_CHANNEL(this);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> substURI;
|
|
||||||
rv = mSubstitutions->GetElementAt(mCurrentIndex++, getter_AddRefs(substURI));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
if (substURI == nsnull)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
char* path = nsnull;
|
|
||||||
rv = channel->mResourceURI->GetPath(&path);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// XXX this path[0] check is a hack -- it seems to me that GetPath
|
|
||||||
// shouldn't include the leading slash:
|
|
||||||
char* aResolvedURI;
|
|
||||||
rv = substURI->Resolve(path[0] == '/' ? path+1 : path, &aResolvedURI);
|
|
||||||
nsCRT::free(path);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
*result = aResolvedURI;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsIRequest methods:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetName(PRUnichar* *result)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsXPIDLCString urlStr;
|
|
||||||
rv = mResourceURI->GetSpec(getter_Copies(urlStr));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
nsString name;
|
|
||||||
name.AppendWithConversion(urlStr);
|
|
||||||
*result = name.ToNewUnicode();
|
|
||||||
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::IsPending(PRBool *result)
|
|
||||||
{
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->IsPending(result);
|
|
||||||
*result = PR_FALSE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetStatus(nsresult *status)
|
|
||||||
{
|
|
||||||
*status = mStatus;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::Cancel(nsresult status)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
if (mResolvedChannel) {
|
|
||||||
rv = mResolvedChannel->Cancel(status);
|
|
||||||
}
|
|
||||||
mStatus = status;
|
|
||||||
mResolvedChannel = nsnull; // remove the resolution
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::Suspend()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->Suspend();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::Resume()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->Resume();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsIChannel methods:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetOriginalURI(nsIURI* *aURI)
|
|
||||||
{
|
|
||||||
*aURI = mOriginalURI ? mOriginalURI : mResourceURI;
|
|
||||||
NS_ADDREF(*aURI);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetOriginalURI(nsIURI* aURI)
|
|
||||||
{
|
|
||||||
mOriginalURI = aURI;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetURI(nsIURI* *aURI)
|
|
||||||
{
|
|
||||||
if (mResolvedChannel) {
|
|
||||||
return mResolvedChannel->GetURI(aURI);
|
|
||||||
}
|
|
||||||
*aURI = mResourceURI;
|
|
||||||
NS_ADDREF(*aURI);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsResChannel::EnsureNextResolvedChannel()
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsXPIDLCString resolvedURI;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> serv(do_GetService(kIOServiceCID, &rv));
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
|
|
||||||
rv = mSubstitutions.Next(getter_Copies(resolvedURI));
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
|
|
||||||
rv = serv->NewChannel(resolvedURI, nsnull,
|
|
||||||
getter_AddRefs(mResolvedChannel));
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
rv = NS_OK; // returning NS_OK lets us try again
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mOriginalURI) {
|
|
||||||
rv = mResolvedChannel->SetOriginalURI(mOriginalURI);
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
}
|
|
||||||
if (mLoadGroup) {
|
|
||||||
rv = mResolvedChannel->SetLoadGroup(mLoadGroup);
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
}
|
|
||||||
if (mLoadFlags != nsIResChannel::LOAD_NORMAL) {
|
|
||||||
rv = mResolvedChannel->SetLoadFlags(mLoadFlags);
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
}
|
|
||||||
if (mCallbacks) {
|
|
||||||
rv = mResolvedChannel->SetNotificationCallbacks(mCallbacks);
|
|
||||||
if (NS_FAILED(rv)) goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
#if defined(PR_LOGGING)
|
|
||||||
nsXPIDLCString resURI;
|
|
||||||
(void)mResourceURI->GetSpec(getter_Copies(resURI));
|
|
||||||
PR_LOG(gResChannelLog, PR_LOG_DEBUG,
|
|
||||||
("nsResChannel: resolving %s ",
|
|
||||||
(const char*)resURI));
|
|
||||||
PR_LOG(gResChannelLog, PR_LOG_DEBUG,
|
|
||||||
(" to %s => status %x\n",
|
|
||||||
(const char*)resolvedURI, rv));
|
|
||||||
#endif /* PR_LOGGING */
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::Open(nsIInputStream **result)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return NS_ERROR_IN_PROGRESS;
|
|
||||||
|
|
||||||
rv = mSubstitutions.Init();
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
do {
|
|
||||||
rv = EnsureNextResolvedChannel();
|
|
||||||
if (NS_FAILED(rv)) break;
|
|
||||||
|
|
||||||
if (mResolvedChannel)
|
|
||||||
rv = mResolvedChannel->Open(result);
|
|
||||||
} while (NS_FAILED(rv));
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX What does OpenOutputStream mean for a res "channel"
|
|
||||||
#if 0
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::OpenOutputStream(PRUint32 transferOffset, PRUint32 transferCount, nsIOutputStream **result)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return NS_ERROR_IN_PROGRESS;
|
|
||||||
|
|
||||||
rv = mSubstitutions.Init();
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
do {
|
|
||||||
rv = EnsureNextResolvedChannel();
|
|
||||||
if (NS_FAILED(rv)) break;
|
|
||||||
|
|
||||||
if (mResolvedChannel)
|
|
||||||
rv = mResolvedChannel->OpenOutputStream(transferOffset, transferCount, result);
|
|
||||||
} while (NS_FAILED(rv));
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == nsnull || mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
mInitiator = PR_CurrentThread();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (mState) {
|
|
||||||
case QUIESCENT:
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return NS_ERROR_IN_PROGRESS;
|
|
||||||
|
|
||||||
// first time through
|
|
||||||
rv = mSubstitutions.Init();
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
// fall through
|
|
||||||
mState = ASYNC_READ;
|
|
||||||
|
|
||||||
case ASYNC_READ:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return NS_ERROR_IN_PROGRESS;
|
|
||||||
}
|
|
||||||
NS_ASSERTION(mState == ASYNC_READ, "wrong state");
|
|
||||||
|
|
||||||
mUserContext = ctxt;
|
|
||||||
mUserObserver = listener; // cast back to nsIStreamListener later
|
|
||||||
|
|
||||||
do {
|
|
||||||
rv = EnsureNextResolvedChannel();
|
|
||||||
if (NS_FAILED(rv)) break;
|
|
||||||
|
|
||||||
if (mResolvedChannel)
|
|
||||||
rv = mResolvedChannel->AsyncOpen(this, nsnull);
|
|
||||||
// Later, this AsyncRead will call back our OnStopRequest
|
|
||||||
// method. The action resumes there...
|
|
||||||
} while (NS_FAILED(rv));
|
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
(void)EndRequest(rv);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetLoadFlags(PRUint32 *aLoadFlags)
|
|
||||||
{
|
|
||||||
*aLoadFlags = mLoadFlags;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetLoadFlags(PRUint32 aLoadFlags)
|
|
||||||
{
|
|
||||||
mLoadFlags = aLoadFlags;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetContentType(char * *aContentType)
|
|
||||||
{
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->GetContentType(aContentType);
|
|
||||||
|
|
||||||
// if we have not created a mResolvedChannel, use the mime service
|
|
||||||
nsCOMPtr<nsIMIMEService> MIMEService (do_GetService(NS_MIMESERVICE_CONTRACTID));
|
|
||||||
if (!MIMEService) return NS_ERROR_FAILURE;
|
|
||||||
return MIMEService->GetTypeFromURI(mResourceURI, aContentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetContentType(const char *aContentType)
|
|
||||||
{
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->SetContentType(aContentType);
|
|
||||||
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetContentLength(PRInt32 *aContentLength)
|
|
||||||
{
|
|
||||||
if (mResolvedChannel)
|
|
||||||
return mResolvedChannel->GetContentLength(aContentLength);
|
|
||||||
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetContentLength(PRInt32 aContentLength)
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("nsResChannel::SetContentLength");
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
|
||||||
{
|
|
||||||
*aLoadGroup = mLoadGroup;
|
|
||||||
NS_IF_ADDREF(*aLoadGroup);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
|
||||||
{
|
|
||||||
mLoadGroup = aLoadGroup;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetOwner(nsISupports* *aOwner)
|
|
||||||
{
|
|
||||||
*aOwner = mOwner.get();
|
|
||||||
NS_IF_ADDREF(*aOwner);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetOwner(nsISupports* aOwner)
|
|
||||||
{
|
|
||||||
mOwner = aOwner;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
|
||||||
{
|
|
||||||
*aNotificationCallbacks = mCallbacks.get();
|
|
||||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
|
||||||
{
|
|
||||||
mCallbacks = aNotificationCallbacks;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("nsResChannel::GetSecurityInfo");
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsIStreamListener methods:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::OnStartRequest(nsIRequest* request, nsISupports* context)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
NS_ASSERTION(mUserObserver, "No observer...");
|
|
||||||
return mUserObserver->OnStartRequest(NS_STATIC_CAST(nsIResChannel*, this), mUserContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::OnStopRequest(nsIRequest* request, nsISupports* context,
|
|
||||||
nsresult aStatus)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
if (NS_FAILED(aStatus) && aStatus != NS_BINDING_ABORTED) {
|
|
||||||
nsCOMPtr<nsIRequest> dummyRequest;
|
|
||||||
|
|
||||||
// if we failed to process this channel, then try the next one:
|
|
||||||
switch (mState) {
|
|
||||||
case ASYNC_READ:
|
|
||||||
return AsyncOpen(GetUserListener(), mUserContext);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return EndRequest(aStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsResChannel::EndRequest(nsresult aStatus)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
rv = mUserObserver->OnStopRequest(NS_STATIC_CAST(nsIResChannel*, this),
|
|
||||||
mUserContext, aStatus);
|
|
||||||
#if 0 // we don't add the resource channel to the group (although maybe we should)
|
|
||||||
if (mLoadGroup) {
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
mLoadGroup->RemoveChannel(this, context, notif);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Release the reference to the consumer stream listener...
|
|
||||||
mUserObserver = 0;
|
|
||||||
mUserContext = 0;
|
|
||||||
mResolvedChannel = 0;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsResChannel::OnDataAvailable(nsIRequest* request, nsISupports* context,
|
|
||||||
nsIInputStream *aIStream, PRUint32 aSourceOffset,
|
|
||||||
PRUint32 aLength)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
|
||||||
"wrong thread calling this routine");
|
|
||||||
#endif
|
|
||||||
return GetUserListener()->OnDataAvailable(NS_STATIC_CAST(nsIResChannel*, this),
|
|
||||||
mUserContext, aIStream,
|
|
||||||
aSourceOffset, aLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/* void init (in nsIFile file, in long ioFlags, in long perm); */
|
|
||||||
NS_IMETHODIMP nsResChannel::Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* readonly attribute nsIFile file; */
|
|
||||||
NS_IMETHODIMP nsResChannel::GetFile(nsIFile * *result)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
rv = mSubstitutions.Init();
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file;
|
|
||||||
do {
|
|
||||||
rv = EnsureNextResolvedChannel();
|
|
||||||
if (NS_FAILED(rv)) break;
|
|
||||||
|
|
||||||
if (mResolvedChannel) {
|
|
||||||
nsCOMPtr<nsIFileChannel> fc(do_QueryInterface(mResolvedChannel));
|
|
||||||
if (fc) {
|
|
||||||
rv = fc->GetFile(getter_AddRefs(file));
|
|
||||||
if (file) {
|
|
||||||
PRBool exists;
|
|
||||||
rv = file->Exists(&exists);
|
|
||||||
if (NS_SUCCEEDED(rv) && exists) {
|
|
||||||
*result = file;
|
|
||||||
NS_ADDREF(*result);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (NS_FAILED(rv));
|
|
||||||
|
|
||||||
*result = nsnull;
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attribute long ioFlags; */
|
|
||||||
NS_IMETHODIMP nsResChannel::GetIoFlags(PRInt32 *aIoFlags)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP nsResChannel::SetIoFlags(PRInt32 aIoFlags)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attribute long permissions; */
|
|
||||||
NS_IMETHODIMP nsResChannel::GetPermissions(PRInt32 *aPermissions)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
NS_IMETHODIMP nsResChannel::SetPermissions(PRInt32 aPermissions)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* -*- 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.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at http://www.mozilla.org/NPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS
|
|
||||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
* implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code is mozilla.org code.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is Netscape
|
|
||||||
* Communications Corporation. Portions created by Netscape are
|
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
||||||
* Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef nsResChannel_h__
|
|
||||||
#define nsResChannel_h__
|
|
||||||
|
|
||||||
#include "nsIResChannel.h"
|
|
||||||
#include "nsIFileChannel.h"
|
|
||||||
#include "nsIStreamListener.h"
|
|
||||||
#include "nsIStreamProvider.h"
|
|
||||||
#include "nsIResProtocolHandler.h"
|
|
||||||
#include "nsIURI.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
|
||||||
#include "nsILoadGroup.h"
|
|
||||||
#include "nsIInputStream.h"
|
|
||||||
#include "nsISupportsArray.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsAutoLock.h"
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include "prthread.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class nsResChannel : public nsIResChannel,
|
|
||||||
public nsIFileChannel,
|
|
||||||
public nsIStreamListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIREQUEST
|
|
||||||
NS_DECL_NSICHANNEL
|
|
||||||
NS_DECL_NSIFILECHANNEL
|
|
||||||
NS_DECL_NSIRESCHANNEL
|
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
|
||||||
NS_DECL_NSISTREAMLISTENER
|
|
||||||
|
|
||||||
nsResChannel();
|
|
||||||
virtual ~nsResChannel();
|
|
||||||
|
|
||||||
// Define a Create method to be used with a factory:
|
|
||||||
static NS_METHOD
|
|
||||||
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
|
||||||
|
|
||||||
nsresult Init(nsIResProtocolHandler* handler, nsIURI* uri);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Substitutions {
|
|
||||||
public:
|
|
||||||
Substitutions() : mCurrentIndex(0) {}
|
|
||||||
~Substitutions() {}
|
|
||||||
|
|
||||||
nsresult Init();
|
|
||||||
nsresult Next(char* *result);
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsIURI> mResourceURI;
|
|
||||||
nsCOMPtr<nsISupportsArray> mSubstitutions;
|
|
||||||
PRUint32 mCurrentIndex;
|
|
||||||
};
|
|
||||||
friend class Substitutions;
|
|
||||||
|
|
||||||
#define GET_SUBSTITUTIONS_CHANNEL(_this) \
|
|
||||||
((nsResChannel*)((char*)(_this) - offsetof(nsResChannel, mSubstitutions)))
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
QUIESCENT,
|
|
||||||
ASYNC_READ,
|
|
||||||
ASYNC_WRITE
|
|
||||||
};
|
|
||||||
|
|
||||||
nsIStreamListener* GetUserListener() {
|
|
||||||
// this method doesn't addref the listener
|
|
||||||
NS_ASSERTION(mState == ASYNC_READ, "wrong state");
|
|
||||||
// this cast is safe because we set mUserObserver in AsyncRead
|
|
||||||
nsIRequestObserver* obs = mUserObserver;
|
|
||||||
nsIStreamListener* listener = NS_STATIC_CAST(nsIStreamListener*, obs);
|
|
||||||
return listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIStreamProvider* GetUserProvider() {
|
|
||||||
// this method doesn't addref the provider
|
|
||||||
NS_ASSERTION(mState == ASYNC_WRITE, "wrong state");
|
|
||||||
// this cast is safe because we set mUserObserver in AsyncWrite
|
|
||||||
nsIRequestObserver* obs = mUserObserver;
|
|
||||||
nsIStreamProvider* provider = NS_STATIC_CAST(nsIStreamProvider*, obs);
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult EnsureNextResolvedChannel();
|
|
||||||
nsresult EndRequest(nsresult aStatus);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
|
||||||
nsCOMPtr<nsIURI> mResourceURI;
|
|
||||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
|
||||||
PRUint32 mLoadFlags;
|
|
||||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
|
||||||
nsCOMPtr<nsISupports> mOwner;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIResProtocolHandler> mHandler;
|
|
||||||
nsCOMPtr<nsIChannel> mResolvedChannel;
|
|
||||||
State mState;
|
|
||||||
Substitutions mSubstitutions;
|
|
||||||
nsCOMPtr<nsIRequestObserver> mUserObserver;
|
|
||||||
nsCOMPtr<nsISupports> mUserContext;
|
|
||||||
nsresult mStatus;
|
|
||||||
#ifdef DEBUG
|
|
||||||
PRThread* mInitiator;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // nsResChannel_h__
|
|
|
@ -19,6 +19,7 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* IBM Corp.
|
* IBM Corp.
|
||||||
|
* Darin Fisher <darin@netscape.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nsResProtocolHandler.h"
|
#include "nsResProtocolHandler.h"
|
||||||
|
@ -26,25 +27,65 @@
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
#include "nsIIOService.h"
|
#include "nsIIOService.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsResChannel.h"
|
#include "nsILocalFile.h"
|
||||||
#include "nsIFileChannel.h"
|
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
#include "prmem.h"
|
#include "prmem.h"
|
||||||
#include "prprf.h"
|
#include "prprf.h"
|
||||||
#include "nsXPIDLString.h"
|
#include "nsXPIDLString.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsDirectoryServiceDefs.h"
|
#include "nsDirectoryServiceDefs.h"
|
||||||
#include "nsNetCID.h"
|
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
|
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsResURL : overrides nsStdURL::GetFile to provide nsIFile resolution
|
||||||
|
|
||||||
|
#include "nsStdURL.h"
|
||||||
|
|
||||||
|
class nsResURL : public nsStdURL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetFile(nsIFile **);
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsResURL::GetFile(nsIFile **result)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
NS_ENSURE_TRUE(nsResProtocolHandler::get(), NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
|
nsXPIDLCString spec;
|
||||||
|
rv = nsResProtocolHandler::get()->ResolveURI(this, getter_Copies(spec));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsILocalFile> localFile =
|
||||||
|
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = localFile->SetURL(spec);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
return CallQueryInterface(localFile, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
nsResProtocolHandler *nsResProtocolHandler::mGlobalInstance = nsnull;
|
||||||
|
|
||||||
nsResProtocolHandler::nsResProtocolHandler()
|
nsResProtocolHandler::nsResProtocolHandler()
|
||||||
: mLock(nsnull), mSubstitutions(32)
|
: mSubstitutions(32)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
NS_ASSERTION(!mGlobalInstance, "res handler already created!");
|
||||||
|
mGlobalInstance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsResProtocolHandler::~nsResProtocolHandler()
|
||||||
|
{
|
||||||
|
mGlobalInstance = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -55,14 +96,8 @@ nsResProtocolHandler::SetSpecialDir(const char* rootName, const char* sysDir)
|
||||||
rv = NS_GetSpecialDirectory(sysDir, getter_AddRefs(file));
|
rv = NS_GetSpecialDirectory(sysDir, getter_AddRefs(file));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCOMPtr<nsIFileURL> fileURL(do_CreateInstance(kStandardURLCID, &rv));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = fileURL->SetFile(file);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsXPIDLCString spec;
|
nsXPIDLCString spec;
|
||||||
rv = fileURL->GetSpec(getter_Copies(spec));
|
rv = file->GetURL(getter_Copies(spec));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
return AppendSubstitution(rootName, spec);
|
return AppendSubstitution(rootName, spec);
|
||||||
|
@ -73,9 +108,8 @@ nsResProtocolHandler::Init()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
mLock = PR_NewLock();
|
mIOService = do_GetIOService(&rv);
|
||||||
if (mLock == nsnull)
|
if (NS_FAILED(rv)) return rv;
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
// set up initial mappings
|
// set up initial mappings
|
||||||
rv = SetSpecialDir("ProgramDir", NS_OS_CURRENT_PROCESS_DIR);
|
rv = SetSpecialDir("ProgramDir", NS_OS_CURRENT_PROCESS_DIR);
|
||||||
|
@ -121,12 +155,6 @@ nsResProtocolHandler::Init()
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsResProtocolHandler::~nsResProtocolHandler()
|
|
||||||
{
|
|
||||||
if (mLock)
|
|
||||||
PR_DestroyLock(mLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS3(nsResProtocolHandler, nsIResProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
|
NS_IMPL_THREADSAFE_ISUPPORTS3(nsResProtocolHandler, nsIResProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
|
||||||
|
|
||||||
NS_METHOD
|
NS_METHOD
|
||||||
|
@ -179,23 +207,16 @@ nsResProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> url(do_CreateInstance(kStandardURLCID, &rv));
|
nsResURL *resURL;
|
||||||
if (NS_FAILED(rv)) return rv;
|
NS_NEWXPCOM(resURL, nsResURL);
|
||||||
|
if (!resURL)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
NS_ADDREF(resURL);
|
||||||
|
|
||||||
if (aBaseURI) {
|
rv = resURL->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aBaseURI);
|
||||||
nsXPIDLCString aResolvedURI;
|
if (NS_SUCCEEDED(rv))
|
||||||
rv = aBaseURI->Resolve(aSpec, getter_Copies(aResolvedURI));
|
rv = CallQueryInterface(resURL, result);
|
||||||
if (NS_FAILED(rv)) return rv;
|
NS_RELEASE(resURL);
|
||||||
rv = url->SetSpec(aResolvedURI);
|
|
||||||
} else {
|
|
||||||
rv = url->SetSpec((char*)aSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
*result = url;
|
|
||||||
NS_ADDREF(*result);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,19 +224,15 @@ NS_IMETHODIMP
|
||||||
nsResProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
nsResProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
nsXPIDLCString spec;
|
||||||
nsResChannel* channel;
|
|
||||||
rv = nsResChannel::Create(nsnull, NS_GET_IID(nsIResChannel), (void**)&channel);
|
rv = ResolveURI(uri, getter_Copies(spec));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = channel->Init(this, uri);
|
rv = mIOService->NewChannel(spec, nsnull, result);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) return rv;
|
||||||
NS_RELEASE(channel);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = (nsIChannel*)(nsIResChannel*)channel;
|
return (*result)->SetOriginalURI(uri);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -231,12 +248,9 @@ NS_IMETHODIMP
|
||||||
nsResProtocolHandler::PrependSubstitution(const char *root, const char *urlStr)
|
nsResProtocolHandler::PrependSubstitution(const char *root, const char *urlStr)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsAutoLock lock(mLock);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> ioServ = do_GetIOService(&rv);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
nsCOMPtr<nsIURI> url;
|
nsCOMPtr<nsIURI> url;
|
||||||
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
rv = mIOService->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCStringKey key(root);
|
nsCStringKey key(root);
|
||||||
|
@ -268,12 +282,9 @@ NS_IMETHODIMP
|
||||||
nsResProtocolHandler::AppendSubstitution(const char *root, const char *urlStr)
|
nsResProtocolHandler::AppendSubstitution(const char *root, const char *urlStr)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsAutoLock lock(mLock);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> ioServ = do_GetIOService(&rv);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
nsCOMPtr<nsIURI> url;
|
nsCOMPtr<nsIURI> url;
|
||||||
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
rv = mIOService->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCStringKey key(root);
|
nsCStringKey key(root);
|
||||||
|
@ -324,12 +335,9 @@ NS_IMETHODIMP
|
||||||
nsResProtocolHandler::RemoveSubstitution(const char *root, const char *urlStr)
|
nsResProtocolHandler::RemoveSubstitution(const char *root, const char *urlStr)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsAutoLock lock(mLock);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIIOService> ioServ = do_GetIOService(&rv);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
nsCOMPtr<nsIURI> url;
|
nsCOMPtr<nsIURI> url;
|
||||||
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
rv = mIOService->NewURI(urlStr, nsnull, getter_AddRefs(url));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
nsCStringKey key(root);
|
nsCStringKey key(root);
|
||||||
|
@ -361,7 +369,6 @@ NS_IMETHODIMP
|
||||||
nsResProtocolHandler::GetSubstitutions(const char *root, nsISupportsArray* *result)
|
nsResProtocolHandler::GetSubstitutions(const char *root, nsISupportsArray* *result)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsAutoLock lock(mLock);
|
|
||||||
|
|
||||||
nsCStringKey key(root);
|
nsCStringKey key(root);
|
||||||
nsISupportsArray* strings = (nsISupportsArray*)mSubstitutions.Get(&key);
|
nsISupportsArray* strings = (nsISupportsArray*)mSubstitutions.Get(&key);
|
||||||
|
@ -382,4 +389,35 @@ nsResProtocolHandler::HasSubstitutions(const char *root, PRBool *result)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsResProtocolHandler::ResolveURI(nsIURI *uri, char **result)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsXPIDLCString host, path;
|
||||||
|
|
||||||
|
rv = uri->GetHost(getter_Copies(host));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = uri->GetPath(getter_Copies(path));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupportsArray> substitutions;
|
||||||
|
rv = GetSubstitutions(host.get() ?
|
||||||
|
host.get() : "", getter_AddRefs(substitutions));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// always use the first substitution
|
||||||
|
nsCOMPtr<nsIURI> substURI;
|
||||||
|
substitutions->GetElementAt(0, getter_AddRefs(substURI));
|
||||||
|
if (!substURI) return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
rv = substURI->Resolve(path[0] == '/' ? path+1 : path, result);
|
||||||
|
#if 0
|
||||||
|
nsXPIDLCString spec;
|
||||||
|
uri->GetSpec(getter_Copies(spec));
|
||||||
|
printf("%s\n -> %s\n", spec.get(), *result);
|
||||||
|
#endif
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* Rights Reserved.
|
* Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Darin Fisher <darin@netscape.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef nsResProtocolHandler_h___
|
#ifndef nsResProtocolHandler_h___
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include "nsIResProtocolHandler.h"
|
#include "nsIResProtocolHandler.h"
|
||||||
#include "nsHashtable.h"
|
#include "nsHashtable.h"
|
||||||
#include "nsISupportsArray.h"
|
#include "nsISupportsArray.h"
|
||||||
|
#include "nsIIOService.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
|
|
||||||
class nsResProtocolHandler : public nsIResProtocolHandler, public nsSupportsWeakReference
|
class nsResProtocolHandler : public nsIResProtocolHandler, public nsSupportsWeakReference
|
||||||
|
@ -45,9 +47,13 @@ public:
|
||||||
nsresult Init();
|
nsresult Init();
|
||||||
nsresult SetSpecialDir(const char* rootName, const char* specialDir);
|
nsresult SetSpecialDir(const char* rootName, const char* specialDir);
|
||||||
|
|
||||||
protected:
|
static nsResProtocolHandler *get() { return mGlobalInstance; }
|
||||||
PRLock* mLock;
|
|
||||||
nsSupportsHashtable mSubstitutions;
|
private:
|
||||||
|
static nsResProtocolHandler *mGlobalInstance;
|
||||||
|
|
||||||
|
nsSupportsHashtable mSubstitutions;
|
||||||
|
nsCOMPtr<nsIIOService> mIOService;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsResProtocolHandler_h___ */
|
#endif /* nsResProtocolHandler_h___ */
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
/* -*- 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.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at http://www.mozilla.org/NPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS
|
|
||||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
* implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code is mozilla.org code.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is Netscape
|
|
||||||
* Communications Corporation. Portions created by Netscape are
|
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
||||||
* Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsIGenericFactory.h"
|
|
||||||
#include "nsResProtocolHandler.h"
|
|
||||||
|
|
||||||
static nsModuleComponentInfo gResComponents[] = {
|
|
||||||
{ "The Resource Protocol Handler",
|
|
||||||
NS_RESPROTOCOLHANDLER_CID,
|
|
||||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource",
|
|
||||||
nsResProtocolHandler::Create
|
|
||||||
}
|
|
||||||
2};
|
|
||||||
|
|
||||||
NS_IMPL_NSGETMODULE(res, gResComponents)
|
|
Загрузка…
Ссылка в новой задаче