Bug 278262 - JAR URIs should resolve relative URIs in the base section r=biesi sr=darin

git-svn-id: svn://10.0.0.236/trunk@168213 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bsmedberg%covad.net
2005-01-23 23:03:39 +00:00
parent 98bd1c51dd
commit 202f2efa47
3 changed files with 68 additions and 42 deletions

View File

@@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -35,6 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsAutoPtr.h"
#include "nsJARProtocolHandler.h"
#include "nsIIOService.h"
#include "nsCRT.h"
@@ -153,35 +155,19 @@ nsJARProtocolHandler::NewURI(const nsACString &aSpec,
nsIURI **result)
{
nsresult rv = NS_OK;
nsIURI* url;
nsJARURI *jarURI = new nsJARURI();
nsRefPtr<nsJARURI> jarURI = new nsJARURI();
if (!jarURI)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(url = jarURI);
rv = jarURI->Init(aCharset);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
NS_ENSURE_SUCCESS(rv, rv);
rv = jarURI->SetSpecWithBase(aSpec, aBaseURI);
if (NS_FAILED(rv))
return rv;
}
if (aBaseURI) {
nsCAutoString aResolvedURI;
rv = aBaseURI->Resolve(aSpec, aResolvedURI);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aResolvedURI);
}
else
rv = url->SetSpec(aSpec);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
NS_ADDREF(*result = jarURI);
return rv;
}

View File

@@ -52,8 +52,6 @@
static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
static NS_DEFINE_CID(kThisImplCID, NS_THIS_JARURI_IMPL_CID);
////////////////////////////////////////////////////////////////////////////////
nsJARURI::nsJARURI()
@@ -75,8 +73,8 @@ NS_INTERFACE_MAP_BEGIN(nsJARURI)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
// see nsJARURI::Equals
if (aIID.Equals(kThisImplCID))
foundInterface = NS_STATIC_CAST(nsIJARURI *, this);
if (aIID.Equals(NS_GET_IID(nsJARURI)))
foundInterface = NS_REINTERPRET_CAST(nsISupports*, this);
else
NS_INTERFACE_MAP_END
@@ -248,38 +246,75 @@ nsJARURI::GetSpec(nsACString &aSpec)
}
NS_IMETHODIMP
nsJARURI::SetSpec(const nsACString &aSpec)
nsJARURI::SetSpec(const nsACString& aSpec)
{
return SetSpecWithBase(aSpec, nsnull);
}
nsresult
nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL)
{
nsresult rv;
nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
if (NS_FAILED(rv)) return rv;
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString scheme;
rv = ioServ->ExtractScheme(aSpec, scheme);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) {
// not an absolute URI
if (!aBaseURL)
return NS_ERROR_MALFORMED_URI;
if (strcmp("jar", scheme.get()) != 0)
return NS_ERROR_MALFORMED_URI;
nsRefPtr<nsJARURI> otherJAR;
aBaseURL->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE);
mJARFile = otherJAR->mJARFile;
nsCOMPtr<nsIStandardURL> entry(do_CreateInstance(NS_STANDARDURL_CONTRACTID));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
rv = entry->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1,
aSpec, mCharsetHint.get(), otherJAR->mJAREntry);
if (NS_FAILED(rv))
return rv;
mJAREntry = do_QueryInterface(entry);
if (!mJAREntry)
return NS_NOINTERFACE;
return NS_OK;
}
NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI);
nsACString::const_iterator begin, end;
aSpec.BeginReading(begin);
aSpec.EndReading(end);
while (begin != end && *begin != ':')
++begin;
++begin; // now we're past the "jar:"
// Search backward from the end for the "!/" delimiter. Remember, jar URLs
// can nest, e.g.:
// jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html
// This gets the b.html document from out of the a.jar file, that's
// contained within the bar.jar file.
// Also, the outermost "inner" URI may be a relative URI:
// jar:../relative.jar!/a.html
nsACString::const_iterator begin, end, delim_begin, delim_end;
aSpec.BeginReading(begin);
aSpec.EndReading(end);
delim_begin = begin;
delim_end = end;
nsACString::const_iterator delim_begin (begin),
delim_end (end);
if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end))
return NS_ERROR_MALFORMED_URI;
begin.advance(4);
rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), nsnull, getter_AddRefs(mJARFile));
rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(),
aBaseURL, getter_AddRefs(mJARFile));
if (NS_FAILED(rv)) return rv;
// skip over any extra '/' chars
@@ -419,14 +454,16 @@ nsJARURI::GetOriginCharset(nsACString &aOriginCharset)
NS_IMETHODIMP
nsJARURI::Equals(nsIURI *other, PRBool *result)
{
nsresult rv;
*result = PR_FALSE;
if (other == nsnull)
return NS_OK; // not equal
nsRefPtr<nsJARURI> otherJAR;
nsresult rv = other->QueryInterface(kThisImplCID, getter_AddRefs(otherJAR));
if (NS_FAILED(rv))
other->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
if (!otherJAR)
return NS_OK; // not equal
PRBool equal;

View File

@@ -74,6 +74,8 @@ public:
NS_DECL_NSISERIALIZABLE
NS_DECL_NSICLASSINFO
NS_DEFINE_STATIC_IID_ACCESSOR(NS_THIS_JARURI_IMPL_CID);
// nsJARURI
nsJARURI();
virtual ~nsJARURI();
@@ -84,6 +86,7 @@ public:
nsresult CreateEntryURL(const nsACString& entryFilename,
const char* charset,
nsIURL** url);
nsresult SetSpecWithBase(const nsACString& aSpec, nsIURI* aBaseURL);
protected:
nsCOMPtr<nsIURI> mJARFile;