1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "DefaultURI.h"
6 #include "nsIClassInfoImpl.h"
7 #include "nsIObjectInputStream.h"
8 #include "nsIObjectOutputStream.h"
9 #include "nsURLHelper.h"
11 #include "mozilla/ipc/URIParams.h"
16 #define NS_DEFAULTURI_CID \
17 { /* 04445aa0-fd27-4c99-bd41-6be6318ae92c */ \
18 0x04445aa0, 0xfd27, 0x4c99, { \
19 0xbd, 0x41, 0x6b, 0xe6, 0x31, 0x8a, 0xe9, 0x2c \
23 #define ASSIGN_AND_ADDREF_THIS(ptrToMutator) \
26 *(ptrToMutator) = do_AddRef(this).take(); \
30 static NS_DEFINE_CID(kDefaultURICID
, NS_DEFAULTURI_CID
);
32 //----------------------------------------------------------------------------
34 //----------------------------------------------------------------------------
36 NS_IMPL_CLASSINFO(DefaultURI
, nullptr, nsIClassInfo::THREADSAFE
,
38 // Empty CI getter. We only need nsIClassInfo for Serialization
39 NS_IMPL_CI_INTERFACE_GETTER0(DefaultURI
)
41 //----------------------------------------------------------------------------
43 //----------------------------------------------------------------------------
45 NS_IMPL_ADDREF(DefaultURI
)
46 NS_IMPL_RELEASE(DefaultURI
)
47 NS_INTERFACE_TABLE_HEAD(DefaultURI
)
48 NS_INTERFACE_TABLE(DefaultURI
, nsIURI
, nsISerializable
)
49 NS_INTERFACE_TABLE_TO_MAP_SEGUE
50 NS_IMPL_QUERY_CLASSINFO(DefaultURI
)
51 if (aIID
.Equals(kDefaultURICID
)) {
52 foundInterface
= static_cast<nsIURI
*>(this);
54 NS_INTERFACE_MAP_ENTRY(nsISizeOf
)
57 //----------------------------------------------------------------------------
59 //----------------------------------------------------------------------------
61 NS_IMETHODIMP
DefaultURI::Read(nsIObjectInputStream
* aInputStream
) {
62 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
63 return NS_ERROR_NOT_IMPLEMENTED
;
66 NS_IMETHODIMP
DefaultURI::Write(nsIObjectOutputStream
* aOutputStream
) {
67 nsAutoCString
spec(mURL
->Spec());
68 return aOutputStream
->WriteStringZ(spec
.get());
71 //----------------------------------------------------------------------------
73 //----------------------------------------------------------------------------
75 size_t DefaultURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
76 return mURL
->SizeOf();
79 size_t DefaultURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
80 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);
83 //----------------------------------------------------------------------------
85 //----------------------------------------------------------------------------
87 NS_IMETHODIMP
DefaultURI::GetSpec(nsACString
& aSpec
) {
92 NS_IMETHODIMP
DefaultURI::GetPrePath(nsACString
& aPrePath
) {
93 aPrePath
= mURL
->PrePath();
97 NS_IMETHODIMP
DefaultURI::GetScheme(nsACString
& aScheme
) {
98 aScheme
= mURL
->Scheme();
102 NS_IMETHODIMP
DefaultURI::GetUserPass(nsACString
& aUserPass
) {
103 aUserPass
= mURL
->Username();
104 nsAutoCString
pass(mURL
->Password());
105 if (pass
.IsEmpty()) {
108 aUserPass
.Append(':');
109 aUserPass
.Append(pass
);
113 NS_IMETHODIMP
DefaultURI::GetUsername(nsACString
& aUsername
) {
114 aUsername
= mURL
->Username();
118 NS_IMETHODIMP
DefaultURI::GetPassword(nsACString
& aPassword
) {
119 aPassword
= mURL
->Password();
123 NS_IMETHODIMP
DefaultURI::GetHostPort(nsACString
& aHostPort
) {
124 aHostPort
= mURL
->HostPort();
128 NS_IMETHODIMP
DefaultURI::GetHost(nsACString
& aHost
) {
129 aHost
= mURL
->Host();
131 // Historically nsIURI.host has always returned an IPv6 address that isn't
132 // enclosed in brackets. Ideally we want to change that, but for the sake of
133 // consitency we'll leave it like that for the moment.
134 // Bug 1603199 should fix this.
135 if (StringBeginsWith(aHost
, "["_ns
) && StringEndsWith(aHost
, "]"_ns
) &&
136 aHost
.FindChar(':') != kNotFound
) {
137 aHost
= Substring(aHost
, 1, aHost
.Length() - 2);
142 NS_IMETHODIMP
DefaultURI::GetPort(int32_t* aPort
) {
143 *aPort
= mURL
->Port();
147 NS_IMETHODIMP
DefaultURI::GetPathQueryRef(nsACString
& aPathQueryRef
) {
148 aPathQueryRef
= mURL
->Path();
152 NS_IMETHODIMP
DefaultURI::Equals(nsIURI
* other
, bool* _retval
) {
157 RefPtr
<DefaultURI
> otherUri
;
158 nsresult rv
= other
->QueryInterface(kDefaultURICID
, getter_AddRefs(otherUri
));
164 *_retval
= mURL
->Spec() == otherUri
->mURL
->Spec();
168 NS_IMETHODIMP
DefaultURI::SchemeIs(const char* scheme
, bool* _retval
) {
173 *_retval
= mURL
->Scheme().Equals(scheme
);
177 NS_IMETHODIMP
DefaultURI::Resolve(const nsACString
& aRelativePath
,
178 nsACString
& aResult
) {
179 nsAutoCString scheme
;
180 nsresult rv
= net_ExtractURLScheme(aRelativePath
, scheme
);
181 if (NS_SUCCEEDED(rv
)) {
182 aResult
= aRelativePath
;
186 // We try to create another URL with this one as its base.
187 RefPtr
<MozURL
> resolvedURL
;
188 rv
= MozURL::Init(getter_AddRefs(resolvedURL
), aRelativePath
, mURL
);
189 if (NS_WARN_IF(NS_FAILED(rv
))) {
190 // If parsing the relative url fails, we revert to the previous behaviour
191 // and just return the relative path.
192 aResult
= aRelativePath
;
196 aResult
= resolvedURL
->Spec();
200 NS_IMETHODIMP
DefaultURI::GetAsciiSpec(nsACString
& aAsciiSpec
) {
201 return GetSpec(aAsciiSpec
);
204 NS_IMETHODIMP
DefaultURI::GetAsciiHostPort(nsACString
& aAsciiHostPort
) {
205 return GetHostPort(aAsciiHostPort
);
208 NS_IMETHODIMP
DefaultURI::GetAsciiHost(nsACString
& aAsciiHost
) {
209 return GetHost(aAsciiHost
);
212 NS_IMETHODIMP
DefaultURI::GetRef(nsACString
& aRef
) {
217 NS_IMETHODIMP
DefaultURI::EqualsExceptRef(nsIURI
* other
, bool* _retval
) {
218 if (!_retval
|| !other
) {
219 return NS_ERROR_NULL_POINTER
;
221 RefPtr
<DefaultURI
> otherUri
;
222 nsresult rv
= other
->QueryInterface(kDefaultURICID
, getter_AddRefs(otherUri
));
228 *_retval
= mURL
->SpecNoRef().Equals(otherUri
->mURL
->SpecNoRef());
232 NS_IMETHODIMP
DefaultURI::GetSpecIgnoringRef(nsACString
& aSpecIgnoringRef
) {
233 aSpecIgnoringRef
= mURL
->SpecNoRef();
237 NS_IMETHODIMP
DefaultURI::GetHasRef(bool* aHasRef
) {
238 *aHasRef
= mURL
->HasFragment();
242 NS_IMETHODIMP
DefaultURI::GetHasUserPass(bool* aHasUserPass
) {
243 *aHasUserPass
= !mURL
->Username().IsEmpty() || !mURL
->Password().IsEmpty();
247 NS_IMETHODIMP
DefaultURI::GetFilePath(nsACString
& aFilePath
) {
248 aFilePath
= mURL
->FilePath();
252 NS_IMETHODIMP
DefaultURI::GetQuery(nsACString
& aQuery
) {
253 aQuery
= mURL
->Query();
257 NS_IMETHODIMP
DefaultURI::GetHasQuery(bool* aHasQuery
) {
258 *aHasQuery
= mURL
->HasQuery();
262 NS_IMETHODIMP
DefaultURI::GetDisplayHost(nsACString
& aDisplayHost
) {
263 // At the moment it doesn't seem useful to decode the hostname if it happens
264 // to contain punycode.
265 return GetHost(aDisplayHost
);
268 NS_IMETHODIMP
DefaultURI::GetDisplayHostPort(nsACString
& aDisplayHostPort
) {
269 // At the moment it doesn't seem useful to decode the hostname if it happens
270 // to contain punycode.
271 return GetHostPort(aDisplayHostPort
);
274 NS_IMETHODIMP
DefaultURI::GetDisplaySpec(nsACString
& aDisplaySpec
) {
275 // At the moment it doesn't seem useful to decode the hostname if it happens
276 // to contain punycode.
277 return GetSpec(aDisplaySpec
);
280 NS_IMETHODIMP
DefaultURI::GetDisplayPrePath(nsACString
& aDisplayPrePath
) {
281 // At the moment it doesn't seem useful to decode the hostname if it happens
282 // to contain punycode.
283 return GetPrePath(aDisplayPrePath
);
286 NS_IMETHODIMP
DefaultURI::Mutate(nsIURIMutator
** _retval
) {
287 RefPtr
<DefaultURI::Mutator
> mutator
= new DefaultURI::Mutator();
289 mutator
.forget(_retval
);
293 void DefaultURI::Serialize(ipc::URIParams
& aParams
) {
294 ipc::DefaultURIParams params
;
295 params
.spec() = mURL
->Spec();
299 //----------------------------------------------------------------------------
301 //----------------------------------------------------------------------------
303 NS_IMPL_ADDREF(DefaultURI::Mutator
)
304 NS_IMPL_RELEASE(DefaultURI::Mutator
)
305 NS_IMETHODIMP
DefaultURI::Mutator::QueryInterface(REFNSIID aIID
,
306 void** aInstancePtr
) {
307 NS_ASSERTION(aInstancePtr
, "QueryInterface requires a non-NULL destination!");
308 nsISupports
* foundInterface
= nullptr;
309 if (aIID
.Equals(NS_GET_IID(nsIURI
))) {
310 RefPtr
<DefaultURI
> defaultURI
= new DefaultURI();
311 mMutator
->Finalize(getter_AddRefs(defaultURI
->mURL
));
313 static_cast<nsISupports
*>(static_cast<nsIURI
*>((defaultURI
.get())));
314 NS_ADDREF(foundInterface
);
315 *aInstancePtr
= foundInterface
;
319 if (aIID
.Equals(NS_GET_IID(nsIURIMutator
)) ||
320 aIID
.Equals(NS_GET_IID(nsISupports
))) {
322 static_cast<nsISupports
*>(static_cast<nsIURIMutator
*>(this));
323 } else if (aIID
.Equals(NS_GET_IID(nsIURISetters
))) {
325 static_cast<nsISupports
*>(static_cast<nsIURISetters
*>(this));
326 } else if (aIID
.Equals(NS_GET_IID(nsIURISetSpec
))) {
328 static_cast<nsISupports
*>(static_cast<nsIURISetSpec
*>(this));
329 } else if (aIID
.Equals(NS_GET_IID(nsISerializable
))) {
331 static_cast<nsISupports
*>(static_cast<nsISerializable
*>(this));
334 if (foundInterface
) {
335 NS_ADDREF(foundInterface
);
336 *aInstancePtr
= foundInterface
;
340 return NS_NOINTERFACE
;
343 NS_IMETHODIMP
DefaultURI::Mutator::Read(nsIObjectInputStream
* aStream
) {
345 nsresult rv
= aStream
->ReadCString(spec
);
349 return SetSpec(spec
, nullptr);
352 NS_IMETHODIMP
DefaultURI::Mutator::Deserialize(
353 const mozilla::ipc::URIParams
& aParams
) {
354 if (aParams
.type() != ipc::URIParams::TDefaultURIParams
) {
355 NS_ERROR("Received unknown parameters from the other process!");
356 return NS_ERROR_FAILURE
;
359 const ipc::DefaultURIParams
& params
= aParams
.get_DefaultURIParams();
360 auto result
= MozURL::Mutator::FromSpec(params
.spec());
361 if (result
.isErr()) {
362 return result
.unwrapErr();
364 mMutator
= Some(result
.unwrap());
368 NS_IMETHODIMP
DefaultURI::Mutator::Finalize(nsIURI
** aURI
) {
369 if (!mMutator
.isSome()) {
370 return NS_ERROR_NOT_AVAILABLE
;
372 RefPtr
<DefaultURI
> uri
= new DefaultURI();
373 mMutator
->Finalize(getter_AddRefs(uri
->mURL
));
374 mMutator
= Nothing();
379 NS_IMETHODIMP
DefaultURI::Mutator::SetSpec(const nsACString
& aSpec
,
380 nsIURIMutator
** aMutator
) {
381 ASSIGN_AND_ADDREF_THIS(aMutator
);
382 auto result
= MozURL::Mutator::FromSpec(aSpec
);
383 if (result
.isErr()) {
384 return result
.unwrapErr();
386 mMutator
= Some(result
.unwrap());
391 DefaultURI::Mutator::SetScheme(const nsACString
& aScheme
,
392 nsIURIMutator
** aMutator
) {
393 ASSIGN_AND_ADDREF_THIS(aMutator
);
394 if (!mMutator
.isSome()) {
395 return NS_ERROR_NULL_POINTER
;
397 mMutator
->SetScheme(aScheme
);
398 return mMutator
->GetStatus();
402 DefaultURI::Mutator::SetUserPass(const nsACString
& aUserPass
,
403 nsIURIMutator
** aMutator
) {
404 ASSIGN_AND_ADDREF_THIS(aMutator
);
405 if (!mMutator
.isSome()) {
406 return NS_ERROR_NULL_POINTER
;
408 int32_t index
= aUserPass
.FindChar(':');
409 if (index
== kNotFound
) {
410 mMutator
->SetUsername(aUserPass
);
411 mMutator
->SetPassword(""_ns
);
412 return mMutator
->GetStatus();
415 mMutator
->SetUsername(Substring(aUserPass
, 0, index
));
416 nsresult rv
= mMutator
->GetStatus();
420 mMutator
->SetPassword(Substring(aUserPass
, index
+ 1));
421 rv
= mMutator
->GetStatus();
429 DefaultURI::Mutator::SetUsername(const nsACString
& aUsername
,
430 nsIURIMutator
** aMutator
) {
431 ASSIGN_AND_ADDREF_THIS(aMutator
);
432 if (!mMutator
.isSome()) {
433 return NS_ERROR_NULL_POINTER
;
435 mMutator
->SetUsername(aUsername
);
436 return mMutator
->GetStatus();
440 DefaultURI::Mutator::SetPassword(const nsACString
& aPassword
,
441 nsIURIMutator
** aMutator
) {
442 ASSIGN_AND_ADDREF_THIS(aMutator
);
443 if (!mMutator
.isSome()) {
444 return NS_ERROR_NULL_POINTER
;
446 mMutator
->SetPassword(aPassword
);
447 return mMutator
->GetStatus();
451 DefaultURI::Mutator::SetHostPort(const nsACString
& aHostPort
,
452 nsIURIMutator
** aMutator
) {
453 ASSIGN_AND_ADDREF_THIS(aMutator
);
454 if (!mMutator
.isSome()) {
455 return NS_ERROR_NULL_POINTER
;
457 mMutator
->SetHostPort(aHostPort
);
458 return mMutator
->GetStatus();
462 DefaultURI::Mutator::SetHost(const nsACString
& aHost
,
463 nsIURIMutator
** aMutator
) {
464 ASSIGN_AND_ADDREF_THIS(aMutator
);
465 if (!mMutator
.isSome()) {
466 return NS_ERROR_NULL_POINTER
;
468 mMutator
->SetHostname(aHost
);
469 return mMutator
->GetStatus();
473 DefaultURI::Mutator::SetPort(int32_t aPort
, nsIURIMutator
** aMutator
) {
474 ASSIGN_AND_ADDREF_THIS(aMutator
);
475 if (!mMutator
.isSome()) {
476 return NS_ERROR_NULL_POINTER
;
478 mMutator
->SetPort(aPort
);
479 return mMutator
->GetStatus();
483 DefaultURI::Mutator::SetPathQueryRef(const nsACString
& aPathQueryRef
,
484 nsIURIMutator
** aMutator
) {
485 ASSIGN_AND_ADDREF_THIS(aMutator
);
486 if (!mMutator
.isSome()) {
487 return NS_ERROR_NULL_POINTER
;
489 if (aPathQueryRef
.IsEmpty()) {
490 mMutator
->SetFilePath(""_ns
);
491 mMutator
->SetQuery(""_ns
);
492 mMutator
->SetRef(""_ns
);
493 return mMutator
->GetStatus();
497 mMutator
->Finalize(getter_AddRefs(url
));
498 mMutator
= Nothing();
501 return NS_ERROR_FAILURE
;
504 nsAutoCString
pathQueryRef(aPathQueryRef
);
505 if (url
->CannotBeABase()) {
506 // If the base URL cannot be a base, then setting the pathQueryRef
507 // needs to change everything after the scheme.
508 pathQueryRef
.Insert(":", 0);
509 pathQueryRef
.Insert(url
->Scheme(), 0);
510 // Clear the URL to make sure FromSpec creates an absolute URL
512 } else if (!StringBeginsWith(pathQueryRef
, "/"_ns
)) {
513 // If the base URL can be a base, make sure the path
515 pathQueryRef
.Insert('/', 0);
518 auto result
= MozURL::Mutator::FromSpec(pathQueryRef
, url
);
519 if (result
.isErr()) {
520 return result
.unwrapErr();
522 mMutator
= Some(result
.unwrap());
523 return mMutator
->GetStatus();
527 DefaultURI::Mutator::SetRef(const nsACString
& aRef
, nsIURIMutator
** aMutator
) {
528 ASSIGN_AND_ADDREF_THIS(aMutator
);
529 if (!mMutator
.isSome()) {
530 return NS_ERROR_NULL_POINTER
;
532 mMutator
->SetRef(aRef
);
533 return mMutator
->GetStatus();
537 DefaultURI::Mutator::SetFilePath(const nsACString
& aFilePath
,
538 nsIURIMutator
** aMutator
) {
539 ASSIGN_AND_ADDREF_THIS(aMutator
);
540 if (!mMutator
.isSome()) {
541 return NS_ERROR_NULL_POINTER
;
543 mMutator
->SetFilePath(aFilePath
);
544 return mMutator
->GetStatus();
548 DefaultURI::Mutator::SetQuery(const nsACString
& aQuery
,
549 nsIURIMutator
** aMutator
) {
550 ASSIGN_AND_ADDREF_THIS(aMutator
);
551 if (!mMutator
.isSome()) {
552 return NS_ERROR_NULL_POINTER
;
554 mMutator
->SetQuery(aQuery
);
555 return mMutator
->GetStatus();
559 DefaultURI::Mutator::SetQueryWithEncoding(const nsACString
& aQuery
,
560 const mozilla::Encoding
* aEncoding
,
561 nsIURIMutator
** aMutator
) {
562 ASSIGN_AND_ADDREF_THIS(aMutator
);
563 if (!mMutator
.isSome()) {
564 return NS_ERROR_NULL_POINTER
;
566 // we only support UTF-8 for DefaultURI
567 mMutator
->SetQuery(aQuery
);
568 return mMutator
->GetStatus();
572 } // namespace mozilla