mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
32d406eed2
Differential Revision: https://phabricator.services.mozilla.com/D90254
535 lines
16 KiB
C++
535 lines
16 KiB
C++
/* 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/. */
|
|
|
|
#include "DefaultURI.h"
|
|
#include "nsIClassInfoImpl.h"
|
|
#include "nsIObjectInputStream.h"
|
|
#include "nsIObjectOutputStream.h"
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
#define NS_DEFAULTURI_CID \
|
|
{ /* 04445aa0-fd27-4c99-bd41-6be6318ae92c */ \
|
|
0x04445aa0, 0xfd27, 0x4c99, { \
|
|
0xbd, 0x41, 0x6b, 0xe6, 0x31, 0x8a, 0xe9, 0x2c \
|
|
} \
|
|
}
|
|
|
|
#define ASSIGN_AND_ADDREF_THIS(ptrToMutator) \
|
|
do { \
|
|
if (ptrToMutator) { \
|
|
*(ptrToMutator) = do_AddRef(this).take(); \
|
|
} \
|
|
} while (0)
|
|
|
|
static NS_DEFINE_CID(kDefaultURICID, NS_DEFAULTURI_CID);
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsIClassInfo
|
|
//----------------------------------------------------------------------------
|
|
|
|
NS_IMPL_CLASSINFO(DefaultURI, nullptr, nsIClassInfo::THREADSAFE,
|
|
NS_DEFAULTURI_CID)
|
|
// Empty CI getter. We only need nsIClassInfo for Serialization
|
|
NS_IMPL_CI_INTERFACE_GETTER0(DefaultURI)
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsISupports
|
|
//----------------------------------------------------------------------------
|
|
|
|
NS_IMPL_ADDREF(DefaultURI)
|
|
NS_IMPL_RELEASE(DefaultURI)
|
|
NS_INTERFACE_TABLE_HEAD(DefaultURI)
|
|
NS_INTERFACE_TABLE(DefaultURI, nsIURI, nsISerializable)
|
|
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
|
NS_IMPL_QUERY_CLASSINFO(DefaultURI)
|
|
if (aIID.Equals(kDefaultURICID)) {
|
|
foundInterface = static_cast<nsIURI*>(this);
|
|
} else
|
|
NS_INTERFACE_MAP_ENTRY(nsISizeOf)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsISerializable
|
|
//----------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP DefaultURI::Read(nsIObjectInputStream* aInputStream) {
|
|
MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Write(nsIObjectOutputStream* aOutputStream) {
|
|
nsAutoCString spec(mURL->Spec());
|
|
return aOutputStream->WriteStringZ(spec.get());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsISizeOf
|
|
//----------------------------------------------------------------------------
|
|
|
|
size_t DefaultURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
|
return mURL->SizeOf();
|
|
}
|
|
|
|
size_t DefaultURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
|
|
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsIURI
|
|
//----------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP DefaultURI::GetSpec(nsACString& aSpec) {
|
|
aSpec = mURL->Spec();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetPrePath(nsACString& aPrePath) {
|
|
aPrePath = mURL->PrePath();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetScheme(nsACString& aScheme) {
|
|
aScheme = mURL->Scheme();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetUserPass(nsACString& aUserPass) {
|
|
aUserPass = mURL->Username();
|
|
nsAutoCString pass(mURL->Password());
|
|
if (pass.IsEmpty()) {
|
|
return NS_OK;
|
|
}
|
|
aUserPass.Append(':');
|
|
aUserPass.Append(pass);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetUsername(nsACString& aUsername) {
|
|
aUsername = mURL->Username();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetPassword(nsACString& aPassword) {
|
|
aPassword = mURL->Password();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetHostPort(nsACString& aHostPort) {
|
|
aHostPort = mURL->HostPort();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetHost(nsACString& aHost) {
|
|
aHost = mURL->Host();
|
|
|
|
// Historically nsIURI.host has always returned an IPv6 address that isn't
|
|
// enclosed in brackets. Ideally we want to change that, but for the sake of
|
|
// consitency we'll leave it like that for the moment.
|
|
// Bug 1603199 should fix this.
|
|
if (StringBeginsWith(aHost, "["_ns) && StringEndsWith(aHost, "]"_ns) &&
|
|
aHost.FindChar(':') != kNotFound) {
|
|
aHost = Substring(aHost, 1, aHost.Length() - 2);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetPort(int32_t* aPort) {
|
|
*aPort = mURL->Port();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetPathQueryRef(nsACString& aPathQueryRef) {
|
|
aPathQueryRef = mURL->Path();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Equals(nsIURI* other, bool* _retval) {
|
|
RefPtr<DefaultURI> otherUri;
|
|
nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
|
|
if (NS_FAILED(rv)) {
|
|
*_retval = false;
|
|
return NS_OK;
|
|
}
|
|
|
|
*_retval = mURL->Spec() == otherUri->mURL->Spec();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::SchemeIs(const char* scheme, bool* _retval) {
|
|
*_retval = mURL->Scheme().Equals(scheme);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Resolve(const nsACString& aRelativePath,
|
|
nsACString& aResult) {
|
|
nsAutoCString scheme;
|
|
nsresult rv = net_ExtractURLScheme(aRelativePath, scheme);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
aResult = aRelativePath;
|
|
return NS_OK;
|
|
}
|
|
|
|
// We try to create another URL with this one as its base.
|
|
RefPtr<MozURL> resolvedURL;
|
|
rv = MozURL::Init(getter_AddRefs(resolvedURL), aRelativePath, mURL);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
// If parsing the relative url fails, we revert to the previous behaviour
|
|
// and just return the relative path.
|
|
aResult = aRelativePath;
|
|
return NS_OK;
|
|
}
|
|
|
|
aResult = resolvedURL->Spec();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetAsciiSpec(nsACString& aAsciiSpec) {
|
|
return GetSpec(aAsciiSpec);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetAsciiHostPort(nsACString& aAsciiHostPort) {
|
|
return GetHostPort(aAsciiHostPort);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetAsciiHost(nsACString& aAsciiHost) {
|
|
return GetHost(aAsciiHost);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetRef(nsACString& aRef) {
|
|
aRef = mURL->Ref();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::EqualsExceptRef(nsIURI* other, bool* _retval) {
|
|
RefPtr<DefaultURI> otherUri;
|
|
nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
|
|
if (NS_FAILED(rv)) {
|
|
*_retval = false;
|
|
return NS_OK;
|
|
}
|
|
|
|
*_retval = mURL->SpecNoRef().Equals(otherUri->mURL->SpecNoRef());
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetSpecIgnoringRef(nsACString& aSpecIgnoringRef) {
|
|
aSpecIgnoringRef = mURL->SpecNoRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetHasRef(bool* aHasRef) {
|
|
*aHasRef = mURL->HasFragment();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetFilePath(nsACString& aFilePath) {
|
|
aFilePath = mURL->FilePath();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetQuery(nsACString& aQuery) {
|
|
aQuery = mURL->Query();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetDisplayHost(nsACString& aDisplayHost) {
|
|
// At the moment it doesn't seem useful to decode the hostname if it happens
|
|
// to contain punycode.
|
|
return GetHost(aDisplayHost);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetDisplayHostPort(nsACString& aDisplayHostPort) {
|
|
// At the moment it doesn't seem useful to decode the hostname if it happens
|
|
// to contain punycode.
|
|
return GetHostPort(aDisplayHostPort);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetDisplaySpec(nsACString& aDisplaySpec) {
|
|
// At the moment it doesn't seem useful to decode the hostname if it happens
|
|
// to contain punycode.
|
|
return GetSpec(aDisplaySpec);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::GetDisplayPrePath(nsACString& aDisplayPrePath) {
|
|
// At the moment it doesn't seem useful to decode the hostname if it happens
|
|
// to contain punycode.
|
|
return GetPrePath(aDisplayPrePath);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Mutate(nsIURIMutator** _retval) {
|
|
RefPtr<DefaultURI::Mutator> mutator = new DefaultURI::Mutator();
|
|
mutator->Init(this);
|
|
mutator.forget(_retval);
|
|
return NS_OK;
|
|
}
|
|
|
|
void DefaultURI::Serialize(ipc::URIParams& aParams) {
|
|
ipc::DefaultURIParams params;
|
|
params.spec() = mURL->Spec();
|
|
aParams = params;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// nsIURIMutator
|
|
//----------------------------------------------------------------------------
|
|
|
|
NS_IMPL_ADDREF(DefaultURI::Mutator)
|
|
NS_IMPL_RELEASE(DefaultURI::Mutator)
|
|
NS_IMETHODIMP DefaultURI::Mutator::QueryInterface(REFNSIID aIID,
|
|
void** aInstancePtr) {
|
|
NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
|
|
nsISupports* foundInterface = nullptr;
|
|
if (aIID.Equals(NS_GET_IID(nsIURI))) {
|
|
RefPtr<DefaultURI> defaultURI = new DefaultURI();
|
|
mMutator->Finalize(getter_AddRefs(defaultURI->mURL));
|
|
foundInterface =
|
|
static_cast<nsISupports*>(static_cast<nsIURI*>((defaultURI.get())));
|
|
NS_ADDREF(foundInterface);
|
|
*aInstancePtr = foundInterface;
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIURIMutator)) ||
|
|
aIID.Equals(NS_GET_IID(nsISupports))) {
|
|
foundInterface =
|
|
static_cast<nsISupports*>(static_cast<nsIURIMutator*>(this));
|
|
} else if (aIID.Equals(NS_GET_IID(nsIURISetters))) {
|
|
foundInterface =
|
|
static_cast<nsISupports*>(static_cast<nsIURISetters*>(this));
|
|
} else if (aIID.Equals(NS_GET_IID(nsIURISetSpec))) {
|
|
foundInterface =
|
|
static_cast<nsISupports*>(static_cast<nsIURISetSpec*>(this));
|
|
} else if (aIID.Equals(NS_GET_IID(nsISerializable))) {
|
|
foundInterface =
|
|
static_cast<nsISupports*>(static_cast<nsISerializable*>(this));
|
|
}
|
|
|
|
if (foundInterface) {
|
|
NS_ADDREF(foundInterface);
|
|
*aInstancePtr = foundInterface;
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Mutator::Read(nsIObjectInputStream* aStream) {
|
|
nsAutoCString spec;
|
|
nsresult rv = aStream->ReadCString(spec);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
return SetSpec(spec, nullptr);
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Mutator::Deserialize(
|
|
const mozilla::ipc::URIParams& aParams) {
|
|
if (aParams.type() != ipc::URIParams::TDefaultURIParams) {
|
|
NS_ERROR("Received unknown parameters from the other process!");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
const ipc::DefaultURIParams& params = aParams.get_DefaultURIParams();
|
|
auto result = MozURL::Mutator::FromSpec(params.spec());
|
|
if (result.isErr()) {
|
|
return result.unwrapErr();
|
|
}
|
|
mMutator = Some(result.unwrap());
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Mutator::Finalize(nsIURI** aURI) {
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
RefPtr<DefaultURI> uri = new DefaultURI();
|
|
mMutator->Finalize(getter_AddRefs(uri->mURL));
|
|
mMutator = Nothing();
|
|
uri.forget(aURI);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP DefaultURI::Mutator::SetSpec(const nsACString& aSpec,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
auto result = MozURL::Mutator::FromSpec(aSpec);
|
|
if (result.isErr()) {
|
|
return result.unwrapErr();
|
|
}
|
|
mMutator = Some(result.unwrap());
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetScheme(const nsACString& aScheme,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetScheme(aScheme);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetUserPass(const nsACString& aUserPass,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
int32_t index = aUserPass.FindChar(':');
|
|
if (index == kNotFound) {
|
|
mMutator->SetUsername(aUserPass);
|
|
mMutator->SetPassword(""_ns);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
mMutator->SetUsername(Substring(aUserPass, 0, index));
|
|
nsresult rv = mMutator->GetStatus();
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
mMutator->SetPassword(Substring(aUserPass, index + 1));
|
|
rv = mMutator->GetStatus();
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetUsername(const nsACString& aUsername,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetUsername(aUsername);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetPassword(const nsACString& aPassword,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetPassword(aPassword);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetHostPort(const nsACString& aHostPort,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetHostPort(aHostPort);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetHost(const nsACString& aHost,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetHostname(aHost);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetPort(int32_t aPort, nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetPort(aPort);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetPathQueryRef(const nsACString& aPathQueryRef,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aPathQueryRef.IsEmpty()) {
|
|
mMutator->SetFilePath(""_ns);
|
|
mMutator->SetQuery(""_ns);
|
|
mMutator->SetRef(""_ns);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
nsAutoCString pathQueryRef(aPathQueryRef);
|
|
if (!StringBeginsWith(pathQueryRef, "/"_ns)) {
|
|
pathQueryRef.Insert('/', 0);
|
|
}
|
|
|
|
RefPtr<MozURL> url;
|
|
mMutator->Finalize(getter_AddRefs(url));
|
|
mMutator = Nothing();
|
|
|
|
auto result = MozURL::Mutator::FromSpec(pathQueryRef, url);
|
|
if (result.isErr()) {
|
|
return result.unwrapErr();
|
|
}
|
|
mMutator = Some(result.unwrap());
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetRef(const nsACString& aRef, nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetRef(aRef);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetFilePath(const nsACString& aFilePath,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetFilePath(aFilePath);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetQuery(const nsACString& aQuery,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
mMutator->SetQuery(aQuery);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
DefaultURI::Mutator::SetQueryWithEncoding(const nsACString& aQuery,
|
|
const mozilla::Encoding* aEncoding,
|
|
nsIURIMutator** aMutator) {
|
|
ASSIGN_AND_ADDREF_THIS(aMutator);
|
|
if (!mMutator.isSome()) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
// we only support UTF-8 for DefaultURI
|
|
mMutator->SetQuery(aQuery);
|
|
return mMutator->GetStatus();
|
|
}
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|