2001-09-29 00:14:13 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2010-03-11 08:33:00 +03:00
|
|
|
#include "mozilla/chrome/RegistryMessageUtils.h"
|
2014-10-07 21:29:40 +04:00
|
|
|
#include "mozilla/dom/ContentParent.h"
|
|
|
|
#include "mozilla/unused.h"
|
2010-03-11 08:33:00 +03:00
|
|
|
|
1999-11-23 15:13:33 +03:00
|
|
|
#include "nsResProtocolHandler.h"
|
2000-06-09 11:51:13 +04:00
|
|
|
#include "nsIIOService.h"
|
|
|
|
#include "nsIFile.h"
|
2001-09-10 04:42:50 +04:00
|
|
|
#include "nsNetUtil.h"
|
2002-09-13 23:32:45 +04:00
|
|
|
#include "nsURLHelper.h"
|
2007-02-26 19:57:48 +03:00
|
|
|
#include "nsEscape.h"
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2010-06-23 23:59:59 +04:00
|
|
|
#include "mozilla/Omnijar.h"
|
|
|
|
|
2014-10-07 21:29:40 +04:00
|
|
|
using mozilla::dom::ContentParent;
|
2015-06-04 01:25:57 +03:00
|
|
|
using mozilla::LogLevel;
|
2014-10-07 21:29:40 +04:00
|
|
|
using mozilla::unused;
|
|
|
|
|
2004-12-02 09:59:34 +03:00
|
|
|
static NS_DEFINE_CID(kResURLCID, NS_RESURL_CID);
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
static nsResProtocolHandler *gResHandler = nullptr;
|
2001-09-20 05:32:16 +04:00
|
|
|
|
|
|
|
//
|
|
|
|
// Log module for Resource Protocol logging...
|
|
|
|
//
|
|
|
|
// To enable logging (see prlog.h for full details):
|
|
|
|
//
|
|
|
|
// set NSPR_LOG_MODULES=nsResProtocol:5
|
|
|
|
// set NSPR_LOG_FILE=log.txt
|
|
|
|
//
|
2015-06-04 01:25:57 +03:00
|
|
|
// this enables LogLevel::Debug level information and places all output in
|
2001-09-20 05:32:16 +04:00
|
|
|
// the file log.txt
|
|
|
|
//
|
|
|
|
static PRLogModuleInfo *gResLog;
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2011-05-10 17:50:15 +04:00
|
|
|
#define kAPP NS_LITERAL_CSTRING("app")
|
2010-05-21 22:00:57 +04:00
|
|
|
#define kGRE NS_LITERAL_CSTRING("gre")
|
2009-10-08 22:19:07 +04:00
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
//----------------------------------------------------------------------------
|
2001-11-20 05:29:47 +03:00
|
|
|
// nsResURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
|
2001-09-20 05:32:16 +04:00
|
|
|
//----------------------------------------------------------------------------
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2004-12-03 07:19:48 +03:00
|
|
|
nsresult
|
|
|
|
nsResURL::EnsureFile()
|
2001-09-15 01:19:41 +04:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
NS_ENSURE_TRUE(gResHandler, NS_ERROR_NOT_AVAILABLE);
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2002-03-06 10:48:55 +03:00
|
|
|
rv = gResHandler->ResolveURI(this, spec);
|
2010-08-11 02:03:26 +04:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString scheme;
|
2012-07-30 18:20:58 +04:00
|
|
|
rv = net_ExtractURLScheme(spec, nullptr, nullptr, &scheme);
|
2009-10-08 22:19:07 +04:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2010-08-11 02:03:26 +04:00
|
|
|
|
|
|
|
// Bug 585869:
|
|
|
|
// In most cases, the scheme is jar if it's not file.
|
|
|
|
// Regardless, net_GetFileFromURLSpec should be avoided
|
|
|
|
// when the scheme isn't file.
|
2014-05-22 07:48:51 +04:00
|
|
|
if (!scheme.EqualsLiteral("file"))
|
2009-10-08 22:19:07 +04:00
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
|
|
|
2004-12-03 07:19:48 +03:00
|
|
|
rv = net_GetFileFromURLSpec(spec, getter_AddRefs(mFile));
|
2003-09-13 21:55:56 +04:00
|
|
|
#ifdef DEBUG_bsmedberg
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-09-29 10:19:26 +04:00
|
|
|
bool exists = true;
|
2004-12-03 07:19:48 +03:00
|
|
|
mFile->Exists(&exists);
|
2003-09-13 21:55:56 +04:00
|
|
|
if (!exists) {
|
|
|
|
printf("resource %s doesn't exist!\n", spec.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return rv;
|
2001-09-15 01:19:41 +04:00
|
|
|
}
|
|
|
|
|
2004-12-02 09:59:34 +03:00
|
|
|
/* virtual */ nsStandardURL*
|
|
|
|
nsResURL::StartClone()
|
|
|
|
{
|
2010-07-05 13:42:18 +04:00
|
|
|
nsResURL *clone = new nsResURL();
|
2004-12-02 09:59:34 +03:00
|
|
|
return clone;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsResURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
|
|
|
{
|
|
|
|
*aClassIDNoAlloc = kResURLCID;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// nsResProtocolHandler <public>
|
|
|
|
//----------------------------------------------------------------------------
|
1999-11-23 15:13:33 +03:00
|
|
|
|
|
|
|
nsResProtocolHandler::nsResProtocolHandler()
|
2014-08-06 17:31:21 +04:00
|
|
|
: mSubstitutions(16)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2001-09-20 05:32:16 +04:00
|
|
|
gResLog = PR_NewLogModule("nsResProtocol");
|
|
|
|
|
|
|
|
NS_ASSERTION(!gResHandler, "res handler already created!");
|
|
|
|
gResHandler = this;
|
2001-09-15 01:19:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsResProtocolHandler::~nsResProtocolHandler()
|
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
gResHandler = nullptr;
|
1999-11-23 15:13:33 +03:00
|
|
|
}
|
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
nsresult
|
2003-09-13 21:55:56 +04:00
|
|
|
nsResProtocolHandler::Init()
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2001-09-20 05:32:16 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
2003-09-13 21:55:56 +04:00
|
|
|
mIOService = do_GetIOService(&rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2001-09-20 05:32:16 +04:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString appURI, greURI;
|
2011-02-25 14:53:36 +03:00
|
|
|
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, appURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, greURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2003-09-13 21:55:56 +04:00
|
|
|
|
2011-05-10 17:50:15 +04:00
|
|
|
//
|
2011-02-25 14:53:36 +03:00
|
|
|
// make resource:/// point to the application directory or omnijar
|
2011-05-10 17:50:15 +04:00
|
|
|
//
|
2011-02-25 14:53:36 +03:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
rv = NS_NewURI(getter_AddRefs(uri), appURI.Length() ? appURI : greURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = SetSubstitution(EmptyCString(), uri);
|
2011-05-10 17:50:15 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-05-10 17:50:15 +04:00
|
|
|
//
|
|
|
|
// make resource://app/ point to the application directory or omnijar
|
|
|
|
//
|
|
|
|
rv = SetSubstitution(kAPP, uri);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2003-09-13 21:55:56 +04:00
|
|
|
//
|
|
|
|
// make resource://gre/ point to the GRE directory
|
|
|
|
//
|
2011-02-25 14:53:36 +03:00
|
|
|
if (appURI.Length()) { // We already have greURI in uri if appURI.Length() is 0.
|
|
|
|
rv = NS_NewURI(getter_AddRefs(uri), greURI);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = SetSubstitution(kGRE, uri);
|
2004-09-07 22:59:07 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2003-09-13 21:55:56 +04:00
|
|
|
|
|
|
|
//XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
|
|
|
|
// but once I finish multiple chrome registration I'm not sure that it is needed
|
2004-09-07 22:59:07 +04:00
|
|
|
|
2008-10-01 09:15:58 +04:00
|
|
|
// XXX dveditz: resource://pchrome/ defeats profile directory salting
|
|
|
|
// if web content can load it. Tread carefully.
|
|
|
|
|
2004-09-07 22:59:07 +04:00
|
|
|
return rv;
|
1999-11-23 15:13:33 +03:00
|
|
|
}
|
|
|
|
|
2010-03-11 08:33:00 +03:00
|
|
|
static PLDHashOperator
|
|
|
|
EnumerateSubstitution(const nsACString& aKey,
|
|
|
|
nsIURI* aURI,
|
|
|
|
void* aArg)
|
|
|
|
{
|
|
|
|
nsTArray<ResourceMapping>* resources =
|
|
|
|
static_cast<nsTArray<ResourceMapping>*>(aArg);
|
|
|
|
SerializedURI uri;
|
|
|
|
if (aURI) {
|
|
|
|
aURI->GetSpec(uri.spec);
|
|
|
|
aURI->GetOriginCharset(uri.charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
ResourceMapping resource = {
|
2011-08-12 05:43:00 +04:00
|
|
|
nsCString(aKey), uri
|
2010-03-11 08:33:00 +03:00
|
|
|
};
|
|
|
|
resources->AppendElement(resource);
|
|
|
|
return (PLDHashOperator)PL_DHASH_NEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-11-09 05:49:00 +03:00
|
|
|
nsResProtocolHandler::CollectSubstitutions(InfallibleTArray<ResourceMapping>& aResources)
|
2010-03-11 08:33:00 +03:00
|
|
|
{
|
|
|
|
mSubstitutions.EnumerateRead(&EnumerateSubstitution, &aResources);
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// nsResProtocolHandler::nsISupports
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsResProtocolHandler,
|
|
|
|
nsIResProtocolHandler,
|
|
|
|
nsIProtocolHandler,
|
|
|
|
nsISupportsWeakReference)
|
2001-09-20 05:32:16 +04:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// nsResProtocolHandler::nsIProtocolHandler
|
|
|
|
//----------------------------------------------------------------------------
|
1999-11-23 15:13:33 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-03-06 10:48:55 +03:00
|
|
|
nsResProtocolHandler::GetScheme(nsACString &result)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2004-12-04 13:19:29 +03:00
|
|
|
result.AssignLiteral("resource");
|
1999-11-23 15:13:33 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 19:56:38 +04:00
|
|
|
nsResProtocolHandler::GetDefaultPort(int32_t *result)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
|
|
|
*result = -1; // no port for res: URLs
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-08 00:42:57 +04:00
|
|
|
NS_IMETHODIMP
|
2012-08-22 19:56:38 +04:00
|
|
|
nsResProtocolHandler::GetProtocolFlags(uint32_t *result)
|
2001-08-08 00:42:57 +04:00
|
|
|
{
|
2006-11-11 02:49:08 +03:00
|
|
|
// XXXbz Is this really true for all resource: URIs? Could we
|
|
|
|
// somehow give different flags to some of them?
|
2008-12-10 00:27:42 +03:00
|
|
|
*result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
|
2001-08-08 00:42:57 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-23 15:13:33 +03:00
|
|
|
NS_IMETHODIMP
|
2002-03-06 10:48:55 +03:00
|
|
|
nsResProtocolHandler::NewURI(const nsACString &aSpec,
|
|
|
|
const char *aCharset,
|
|
|
|
nsIURI *aBaseURI,
|
1999-11-23 15:13:33 +03:00
|
|
|
nsIURI **result)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2015-03-12 20:20:29 +03:00
|
|
|
nsRefPtr<nsResURL> resURL = new nsResURL();
|
2001-09-15 01:19:41 +04:00
|
|
|
if (!resURL)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2008-10-01 09:15:58 +04:00
|
|
|
// unescape any %2f and %2e to make sure nsStandardURL coalesces them.
|
|
|
|
// Later net_GetFileFromURLSpec() will do a full unescape and we want to
|
|
|
|
// treat them the same way the file system will. (bugs 380994, 394075)
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2008-10-01 09:15:58 +04:00
|
|
|
const char *src = aSpec.BeginReading();
|
|
|
|
const char *end = aSpec.EndReading();
|
|
|
|
const char *last = src;
|
|
|
|
|
|
|
|
spec.SetCapacity(aSpec.Length()+1);
|
|
|
|
for ( ; src < end; ++src) {
|
|
|
|
if (*src == '%' && (src < end-2) && *(src+1) == '2') {
|
|
|
|
char ch = '\0';
|
2008-10-01 09:21:05 +04:00
|
|
|
if (*(src+2) == 'f' || *(src+2) == 'F')
|
2008-10-01 09:15:58 +04:00
|
|
|
ch = '/';
|
|
|
|
else if (*(src+2) == 'e' || *(src+2) == 'E')
|
|
|
|
ch = '.';
|
|
|
|
|
|
|
|
if (ch) {
|
|
|
|
if (last < src)
|
|
|
|
spec.Append(last, src-last);
|
|
|
|
spec.Append(ch);
|
|
|
|
src += 2;
|
|
|
|
last = src+1; // src will be incremented by the loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (last < src)
|
|
|
|
spec.Append(last, src-last);
|
|
|
|
|
|
|
|
rv = resURL->Init(nsIStandardURL::URLTYPE_STANDARD, -1, spec, aCharset, aBaseURI);
|
2015-03-12 20:20:29 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
resURL.forget(result);
|
|
|
|
}
|
1999-11-23 15:13:33 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-10-23 04:16:57 +04:00
|
|
|
nsResProtocolHandler::NewChannel2(nsIURI* uri,
|
|
|
|
nsILoadInfo* aLoadInfo,
|
|
|
|
nsIChannel** result)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2005-12-18 04:50:50 +03:00
|
|
|
NS_ENSURE_ARG_POINTER(uri);
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2014-12-12 20:07:36 +03:00
|
|
|
nsresult rv = ResolveURI(uri, spec);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2014-12-12 20:07:36 +03:00
|
|
|
nsCOMPtr<nsIURI> newURI;
|
|
|
|
rv = NS_NewURI(getter_AddRefs(newURI), spec);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2015-02-19 22:47:59 +03:00
|
|
|
rv = NS_NewChannelInternal(result,
|
|
|
|
newURI,
|
|
|
|
aLoadInfo);
|
2014-12-12 20:07:36 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2012-05-15 20:15:05 +04:00
|
|
|
nsLoadFlags loadFlags = 0;
|
|
|
|
(*result)->GetLoadFlags(&loadFlags);
|
|
|
|
(*result)->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
|
2001-09-15 01:19:41 +04:00
|
|
|
return (*result)->SetOriginalURI(uri);
|
1999-11-23 15:13:33 +03:00
|
|
|
}
|
|
|
|
|
2014-10-23 04:16:57 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsResProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
|
|
|
{
|
|
|
|
return NewChannel2(uri, nullptr, result);
|
|
|
|
}
|
|
|
|
|
2001-06-06 04:10:09 +04:00
|
|
|
NS_IMETHODIMP
|
2012-08-22 19:56:38 +04:00
|
|
|
nsResProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
|
2001-06-06 04:10:09 +04:00
|
|
|
{
|
|
|
|
// don't override anything.
|
2011-10-17 18:59:28 +04:00
|
|
|
*_retval = false;
|
2001-06-06 04:10:09 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// nsResProtocolHandler::nsIResProtocolHandler
|
|
|
|
//----------------------------------------------------------------------------
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2014-10-07 21:29:40 +04:00
|
|
|
static void
|
|
|
|
SendResourceSubstitution(const nsACString& root, nsIURI* baseURI)
|
|
|
|
{
|
|
|
|
if (GeckoProcessType_Content == XRE_GetProcessType()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ResourceMapping resourceMapping;
|
|
|
|
resourceMapping.resource = root;
|
|
|
|
if (baseURI) {
|
|
|
|
baseURI->GetSpec(resourceMapping.resolvedURI.spec);
|
|
|
|
baseURI->GetOriginCharset(resourceMapping.resolvedURI.charset);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<ContentParent*> parents;
|
|
|
|
ContentParent::GetAll(parents);
|
|
|
|
if (!parents.Length()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < parents.Length(); i++) {
|
|
|
|
unused << parents[i]->SendRegisterChromeItem(resourceMapping);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-23 15:13:33 +03:00
|
|
|
NS_IMETHODIMP
|
2003-09-13 21:55:56 +04:00
|
|
|
nsResProtocolHandler::SetSubstitution(const nsACString& root, nsIURI *baseURI)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2003-09-13 21:55:56 +04:00
|
|
|
if (!baseURI) {
|
|
|
|
mSubstitutions.Remove(root);
|
2014-10-07 21:29:40 +04:00
|
|
|
SendResourceSubstitution(root, baseURI);
|
2003-09-13 21:55:56 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2010-08-03 03:37:55 +04:00
|
|
|
// If baseURI isn't a resource URI, we can set the substitution immediately.
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString scheme;
|
2010-08-03 03:37:55 +04:00
|
|
|
nsresult rv = baseURI->GetScheme(scheme);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2014-05-22 07:48:51 +04:00
|
|
|
if (!scheme.EqualsLiteral("resource")) {
|
2012-05-18 21:30:49 +04:00
|
|
|
mSubstitutions.Put(root, baseURI);
|
2014-10-07 21:29:40 +04:00
|
|
|
SendResourceSubstitution(root, baseURI);
|
2012-05-18 21:30:49 +04:00
|
|
|
return NS_OK;
|
2010-08-03 03:37:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// baseURI is a resource URI, let's resolve it first.
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString newBase;
|
2010-08-03 03:37:55 +04:00
|
|
|
rv = ResolveURI(baseURI, newBase);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> newBaseURI;
|
2012-07-30 18:20:58 +04:00
|
|
|
rv = mIOService->NewURI(newBase, nullptr, nullptr,
|
2010-08-03 03:37:55 +04:00
|
|
|
getter_AddRefs(newBaseURI));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2012-05-18 21:30:49 +04:00
|
|
|
mSubstitutions.Put(root, newBaseURI);
|
2014-10-07 21:29:40 +04:00
|
|
|
SendResourceSubstitution(root, newBaseURI);
|
2012-05-18 21:30:49 +04:00
|
|
|
return NS_OK;
|
1999-11-23 15:13:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2003-09-13 21:55:56 +04:00
|
|
|
nsResProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **result)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2001-09-20 05:32:16 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2004-09-07 22:59:07 +04:00
|
|
|
if (mSubstitutions.Get(root, result))
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// try invoking the directory service for "resource:root"
|
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString key;
|
2004-12-04 13:19:29 +03:00
|
|
|
key.AssignLiteral("resource:");
|
2004-09-07 22:59:07 +04:00
|
|
|
key.Append(root);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
nsresult rv = NS_GetSpecialDirectory(key.get(), getter_AddRefs(file));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
rv = mIOService->NewFileURI(file, result);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-11-23 15:13:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-09-29 10:19:26 +04:00
|
|
|
nsResProtocolHandler::HasSubstitution(const nsACString& root, bool *result)
|
1999-11-23 15:13:33 +03:00
|
|
|
{
|
2001-09-20 05:32:16 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
1999-11-23 15:13:33 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
*result = mSubstitutions.Get(root, nullptr);
|
2000-06-28 10:54:56 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-09-15 01:19:41 +04:00
|
|
|
NS_IMETHODIMP
|
2002-03-06 10:48:55 +03:00
|
|
|
nsResProtocolHandler::ResolveURI(nsIURI *uri, nsACString &result)
|
2001-09-15 01:19:41 +04:00
|
|
|
{
|
|
|
|
nsresult rv;
|
2006-07-12 19:25:51 +04:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString host;
|
|
|
|
nsAutoCString path;
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2002-03-06 10:48:55 +03:00
|
|
|
rv = uri->GetAsciiHost(host);
|
2001-09-15 01:19:41 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2002-03-06 10:48:55 +03:00
|
|
|
rv = uri->GetPath(path);
|
2001-09-15 01:19:41 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2011-02-03 01:57:48 +03:00
|
|
|
// Unescape the path so we can perform some checks on it.
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString unescapedPath(path);
|
2011-02-03 01:57:48 +03:00
|
|
|
NS_UnescapeURL(unescapedPath);
|
2006-07-12 19:25:51 +04:00
|
|
|
|
|
|
|
// Don't misinterpret the filepath as an absolute URI.
|
2011-02-03 01:57:48 +03:00
|
|
|
if (unescapedPath.FindChar(':') != -1)
|
2007-02-26 19:57:48 +03:00
|
|
|
return NS_ERROR_MALFORMED_URI;
|
|
|
|
|
2011-02-03 01:57:48 +03:00
|
|
|
if (unescapedPath.FindChar('\\') != -1)
|
2006-07-12 19:25:51 +04:00
|
|
|
return NS_ERROR_MALFORMED_URI;
|
|
|
|
|
2006-09-11 19:51:01 +04:00
|
|
|
const char *p = path.get() + 1; // path always starts with a slash
|
|
|
|
NS_ASSERTION(*(p-1) == '/', "Path did not begin with a slash!");
|
|
|
|
|
|
|
|
if (*p == '/')
|
|
|
|
return NS_ERROR_MALFORMED_URI;
|
|
|
|
|
2001-09-20 05:32:16 +04:00
|
|
|
nsCOMPtr<nsIURI> baseURI;
|
2003-09-13 21:55:56 +04:00
|
|
|
rv = GetSubstitution(host, getter_AddRefs(baseURI));
|
2001-09-15 01:19:41 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2003-09-13 21:55:56 +04:00
|
|
|
rv = baseURI->Resolve(nsDependentCString(p, path.Length()-1), result);
|
2001-09-15 01:19:41 +04:00
|
|
|
|
2015-06-04 01:25:57 +03:00
|
|
|
if (MOZ_LOG_TEST(gResLog, LogLevel::Debug)) {
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString spec;
|
2002-03-06 10:48:55 +03:00
|
|
|
uri->GetAsciiSpec(spec);
|
2015-06-04 01:25:57 +03:00
|
|
|
MOZ_LOG(gResLog, LogLevel::Debug,
|
2010-07-06 00:49:02 +04:00
|
|
|
("%s\n -> %s\n", spec.get(), PromiseFlatCString(result).get()));
|
2001-09-20 05:32:16 +04:00
|
|
|
}
|
2001-09-15 01:19:41 +04:00
|
|
|
return rv;
|
|
|
|
}
|