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/. */
4
5 #include "DefaultURI.h"
6 #include "nsIClassInfoImpl.h"
7 #include "nsIObjectInputStream.h"
8 #include "nsIObjectOutputStream.h"
9 namespace mozilla {
10 namespace net {
11
12 #define NS_DEFAULTURI_CID \
13 { /* 04445aa0-fd27-4c99-bd41-6be6318ae92c */ \
14 0x04445aa0, 0xfd27, 0x4c99, { \
15 0xbd, 0x41, 0x6b, 0xe6, 0x31, 0x8a, 0xe9, 0x2c \
16 } \
17 }
18
19 #define ASSIGN_AND_ADDREF_THIS(ptrToMutator) \
20 do { \
21 if (ptrToMutator) { \
22 *(ptrToMutator) = do_AddRef(this).take(); \
23 } \
24 } while (0)
25
26 static NS_DEFINE_CID(kDefaultURICID, NS_DEFAULTURI_CID);
27
28 //----------------------------------------------------------------------------
29 // nsIClassInfo
30 //----------------------------------------------------------------------------
31
32 NS_IMPL_CLASSINFO(DefaultURI, nullptr, nsIClassInfo::THREADSAFE,
33 NS_DEFAULTURI_CID)
34 // Empty CI getter. We only need nsIClassInfo for Serialization
35 NS_IMPL_CI_INTERFACE_GETTER0(DefaultURI)
36
37 //----------------------------------------------------------------------------
38 // nsISupports
39 //----------------------------------------------------------------------------
40
41 NS_IMPL_ADDREF(DefaultURI)
42 NS_IMPL_RELEASE(DefaultURI)
43 NS_INTERFACE_TABLE_HEAD(DefaultURI)
44 NS_INTERFACE_TABLE(DefaultURI, nsIURI, nsISerializable)
45 NS_INTERFACE_TABLE_TO_MAP_SEGUE
46 NS_IMPL_QUERY_CLASSINFO(DefaultURI)
47 if (aIID.Equals(kDefaultURICID)) {
48 foundInterface = static_cast<nsIURI*>(this);
49 } else
NS_INTERFACE_MAP_ENTRY(nsISizeOf)50 NS_INTERFACE_MAP_ENTRY(nsISizeOf)
51 NS_INTERFACE_MAP_END
52
53 //----------------------------------------------------------------------------
54 // nsISerializable
55 //----------------------------------------------------------------------------
56
57 NS_IMETHODIMP DefaultURI::Read(nsIObjectInputStream* aInputStream) {
58 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
59 return NS_ERROR_NOT_IMPLEMENTED;
60 }
61
Write(nsIObjectOutputStream * aOutputStream)62 NS_IMETHODIMP DefaultURI::Write(nsIObjectOutputStream* aOutputStream) {
63 nsAutoCString spec(mURL->Spec());
64 return aOutputStream->WriteStringZ(spec.get());
65 }
66
67 //----------------------------------------------------------------------------
68 // nsISizeOf
69 //----------------------------------------------------------------------------
70
SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const71 size_t DefaultURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
72 return mURL->SizeOf();
73 }
74
SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const75 size_t DefaultURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
76 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
77 }
78
79 //----------------------------------------------------------------------------
80 // nsIURI
81 //----------------------------------------------------------------------------
82
GetSpec(nsACString & aSpec)83 NS_IMETHODIMP DefaultURI::GetSpec(nsACString& aSpec) {
84 aSpec = mURL->Spec();
85 return NS_OK;
86 }
87
GetPrePath(nsACString & aPrePath)88 NS_IMETHODIMP DefaultURI::GetPrePath(nsACString& aPrePath) {
89 aPrePath = mURL->PrePath();
90 return NS_OK;
91 }
92
GetScheme(nsACString & aScheme)93 NS_IMETHODIMP DefaultURI::GetScheme(nsACString& aScheme) {
94 aScheme = mURL->Scheme();
95 return NS_OK;
96 }
97
GetUserPass(nsACString & aUserPass)98 NS_IMETHODIMP DefaultURI::GetUserPass(nsACString& aUserPass) {
99 aUserPass = mURL->Username();
100 nsAutoCString pass(mURL->Password());
101 if (pass.IsEmpty()) {
102 return NS_OK;
103 }
104 aUserPass.Append(':');
105 aUserPass.Append(pass);
106 return NS_OK;
107 }
108
GetUsername(nsACString & aUsername)109 NS_IMETHODIMP DefaultURI::GetUsername(nsACString& aUsername) {
110 aUsername = mURL->Username();
111 return NS_OK;
112 }
113
GetPassword(nsACString & aPassword)114 NS_IMETHODIMP DefaultURI::GetPassword(nsACString& aPassword) {
115 aPassword = mURL->Password();
116 return NS_OK;
117 }
118
GetHostPort(nsACString & aHostPort)119 NS_IMETHODIMP DefaultURI::GetHostPort(nsACString& aHostPort) {
120 aHostPort = mURL->HostPort();
121 return NS_OK;
122 }
123
GetHost(nsACString & aHost)124 NS_IMETHODIMP DefaultURI::GetHost(nsACString& aHost) {
125 aHost = mURL->Host();
126
127 // Historically nsIURI.host has always returned an IPv6 address that isn't
128 // enclosed in brackets. Ideally we want to change that, but for the sake of
129 // consitency we'll leave it like that for the moment.
130 // Bug 1603199 should fix this.
131 if (StringBeginsWith(aHost, "["_ns) && StringEndsWith(aHost, "]"_ns) &&
132 aHost.FindChar(':') != kNotFound) {
133 aHost = Substring(aHost, 1, aHost.Length() - 2);
134 }
135 return NS_OK;
136 }
137
GetPort(int32_t * aPort)138 NS_IMETHODIMP DefaultURI::GetPort(int32_t* aPort) {
139 *aPort = mURL->Port();
140 return NS_OK;
141 }
142
GetPathQueryRef(nsACString & aPathQueryRef)143 NS_IMETHODIMP DefaultURI::GetPathQueryRef(nsACString& aPathQueryRef) {
144 aPathQueryRef = mURL->Path();
145 return NS_OK;
146 }
147
Equals(nsIURI * other,bool * _retval)148 NS_IMETHODIMP DefaultURI::Equals(nsIURI* other, bool* _retval) {
149 RefPtr<DefaultURI> otherUri;
150 nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
151 if (NS_FAILED(rv)) {
152 *_retval = false;
153 return NS_OK;
154 }
155
156 *_retval = mURL->Spec() == otherUri->mURL->Spec();
157 return NS_OK;
158 }
159
SchemeIs(const char * scheme,bool * _retval)160 NS_IMETHODIMP DefaultURI::SchemeIs(const char* scheme, bool* _retval) {
161 *_retval = mURL->Scheme().Equals(scheme);
162 return NS_OK;
163 }
164
Resolve(const nsACString & aRelativePath,nsACString & aResult)165 NS_IMETHODIMP DefaultURI::Resolve(const nsACString& aRelativePath,
166 nsACString& aResult) {
167 nsAutoCString scheme;
168 nsresult rv = net_ExtractURLScheme(aRelativePath, scheme);
169 if (NS_SUCCEEDED(rv)) {
170 aResult = aRelativePath;
171 return NS_OK;
172 }
173
174 // We try to create another URL with this one as its base.
175 RefPtr<MozURL> resolvedURL;
176 rv = MozURL::Init(getter_AddRefs(resolvedURL), aRelativePath, mURL);
177 if (NS_WARN_IF(NS_FAILED(rv))) {
178 // If parsing the relative url fails, we revert to the previous behaviour
179 // and just return the relative path.
180 aResult = aRelativePath;
181 return NS_OK;
182 }
183
184 aResult = resolvedURL->Spec();
185 return NS_OK;
186 }
187
GetAsciiSpec(nsACString & aAsciiSpec)188 NS_IMETHODIMP DefaultURI::GetAsciiSpec(nsACString& aAsciiSpec) {
189 return GetSpec(aAsciiSpec);
190 }
191
GetAsciiHostPort(nsACString & aAsciiHostPort)192 NS_IMETHODIMP DefaultURI::GetAsciiHostPort(nsACString& aAsciiHostPort) {
193 return GetHostPort(aAsciiHostPort);
194 }
195
GetAsciiHost(nsACString & aAsciiHost)196 NS_IMETHODIMP DefaultURI::GetAsciiHost(nsACString& aAsciiHost) {
197 return GetHost(aAsciiHost);
198 }
199
GetRef(nsACString & aRef)200 NS_IMETHODIMP DefaultURI::GetRef(nsACString& aRef) {
201 aRef = mURL->Ref();
202 return NS_OK;
203 }
204
EqualsExceptRef(nsIURI * other,bool * _retval)205 NS_IMETHODIMP DefaultURI::EqualsExceptRef(nsIURI* other, bool* _retval) {
206 RefPtr<DefaultURI> otherUri;
207 nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
208 if (NS_FAILED(rv)) {
209 *_retval = false;
210 return NS_OK;
211 }
212
213 *_retval = mURL->SpecNoRef().Equals(otherUri->mURL->SpecNoRef());
214 return NS_OK;
215 }
216
GetSpecIgnoringRef(nsACString & aSpecIgnoringRef)217 NS_IMETHODIMP DefaultURI::GetSpecIgnoringRef(nsACString& aSpecIgnoringRef) {
218 aSpecIgnoringRef = mURL->SpecNoRef();
219 return NS_OK;
220 }
221
GetHasRef(bool * aHasRef)222 NS_IMETHODIMP DefaultURI::GetHasRef(bool* aHasRef) {
223 *aHasRef = mURL->HasFragment();
224 return NS_OK;
225 }
226
GetFilePath(nsACString & aFilePath)227 NS_IMETHODIMP DefaultURI::GetFilePath(nsACString& aFilePath) {
228 aFilePath = mURL->FilePath();
229 return NS_OK;
230 }
231
GetQuery(nsACString & aQuery)232 NS_IMETHODIMP DefaultURI::GetQuery(nsACString& aQuery) {
233 aQuery = mURL->Query();
234 return NS_OK;
235 }
236
GetDisplayHost(nsACString & aDisplayHost)237 NS_IMETHODIMP DefaultURI::GetDisplayHost(nsACString& aDisplayHost) {
238 // At the moment it doesn't seem useful to decode the hostname if it happens
239 // to contain punycode.
240 return GetHost(aDisplayHost);
241 }
242
GetDisplayHostPort(nsACString & aDisplayHostPort)243 NS_IMETHODIMP DefaultURI::GetDisplayHostPort(nsACString& aDisplayHostPort) {
244 // At the moment it doesn't seem useful to decode the hostname if it happens
245 // to contain punycode.
246 return GetHostPort(aDisplayHostPort);
247 }
248
GetDisplaySpec(nsACString & aDisplaySpec)249 NS_IMETHODIMP DefaultURI::GetDisplaySpec(nsACString& aDisplaySpec) {
250 // At the moment it doesn't seem useful to decode the hostname if it happens
251 // to contain punycode.
252 return GetSpec(aDisplaySpec);
253 }
254
GetDisplayPrePath(nsACString & aDisplayPrePath)255 NS_IMETHODIMP DefaultURI::GetDisplayPrePath(nsACString& aDisplayPrePath) {
256 // At the moment it doesn't seem useful to decode the hostname if it happens
257 // to contain punycode.
258 return GetPrePath(aDisplayPrePath);
259 }
260
Mutate(nsIURIMutator ** _retval)261 NS_IMETHODIMP DefaultURI::Mutate(nsIURIMutator** _retval) {
262 RefPtr<DefaultURI::Mutator> mutator = new DefaultURI::Mutator();
263 mutator->Init(this);
264 mutator.forget(_retval);
265 return NS_OK;
266 }
267
Serialize(ipc::URIParams & aParams)268 void DefaultURI::Serialize(ipc::URIParams& aParams) {
269 ipc::DefaultURIParams params;
270 params.spec() = mURL->Spec();
271 aParams = params;
272 }
273
274 //----------------------------------------------------------------------------
275 // nsIURIMutator
276 //----------------------------------------------------------------------------
277
278 NS_IMPL_ADDREF(DefaultURI::Mutator)
NS_IMPL_RELEASE(DefaultURI::Mutator)279 NS_IMPL_RELEASE(DefaultURI::Mutator)
280 NS_IMETHODIMP DefaultURI::Mutator::QueryInterface(REFNSIID aIID,
281 void** aInstancePtr) {
282 NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
283 nsISupports* foundInterface = nullptr;
284 if (aIID.Equals(NS_GET_IID(nsIURI))) {
285 RefPtr<DefaultURI> defaultURI = new DefaultURI();
286 mMutator->Finalize(getter_AddRefs(defaultURI->mURL));
287 foundInterface =
288 static_cast<nsISupports*>(static_cast<nsIURI*>((defaultURI.get())));
289 NS_ADDREF(foundInterface);
290 *aInstancePtr = foundInterface;
291 return NS_OK;
292 }
293
294 if (aIID.Equals(NS_GET_IID(nsIURIMutator)) ||
295 aIID.Equals(NS_GET_IID(nsISupports))) {
296 foundInterface =
297 static_cast<nsISupports*>(static_cast<nsIURIMutator*>(this));
298 } else if (aIID.Equals(NS_GET_IID(nsIURISetters))) {
299 foundInterface =
300 static_cast<nsISupports*>(static_cast<nsIURISetters*>(this));
301 } else if (aIID.Equals(NS_GET_IID(nsIURISetSpec))) {
302 foundInterface =
303 static_cast<nsISupports*>(static_cast<nsIURISetSpec*>(this));
304 } else if (aIID.Equals(NS_GET_IID(nsISerializable))) {
305 foundInterface =
306 static_cast<nsISupports*>(static_cast<nsISerializable*>(this));
307 }
308
309 if (foundInterface) {
310 NS_ADDREF(foundInterface);
311 *aInstancePtr = foundInterface;
312 return NS_OK;
313 }
314
315 return NS_NOINTERFACE;
316 }
317
Read(nsIObjectInputStream * aStream)318 NS_IMETHODIMP DefaultURI::Mutator::Read(nsIObjectInputStream* aStream) {
319 nsAutoCString spec;
320 nsresult rv = aStream->ReadCString(spec);
321 if (NS_FAILED(rv)) {
322 return rv;
323 }
324 return SetSpec(spec, nullptr);
325 }
326
Deserialize(const mozilla::ipc::URIParams & aParams)327 NS_IMETHODIMP DefaultURI::Mutator::Deserialize(
328 const mozilla::ipc::URIParams& aParams) {
329 if (aParams.type() != ipc::URIParams::TDefaultURIParams) {
330 NS_ERROR("Received unknown parameters from the other process!");
331 return NS_ERROR_FAILURE;
332 }
333
334 const ipc::DefaultURIParams& params = aParams.get_DefaultURIParams();
335 auto result = MozURL::Mutator::FromSpec(params.spec());
336 if (result.isErr()) {
337 return result.unwrapErr();
338 }
339 mMutator = Some(result.unwrap());
340 return NS_OK;
341 }
342
Finalize(nsIURI ** aURI)343 NS_IMETHODIMP DefaultURI::Mutator::Finalize(nsIURI** aURI) {
344 if (!mMutator.isSome()) {
345 return NS_ERROR_NOT_AVAILABLE;
346 }
347 RefPtr<DefaultURI> uri = new DefaultURI();
348 mMutator->Finalize(getter_AddRefs(uri->mURL));
349 mMutator = Nothing();
350 uri.forget(aURI);
351 return NS_OK;
352 }
353
SetSpec(const nsACString & aSpec,nsIURIMutator ** aMutator)354 NS_IMETHODIMP DefaultURI::Mutator::SetSpec(const nsACString& aSpec,
355 nsIURIMutator** aMutator) {
356 ASSIGN_AND_ADDREF_THIS(aMutator);
357 auto result = MozURL::Mutator::FromSpec(aSpec);
358 if (result.isErr()) {
359 return result.unwrapErr();
360 }
361 mMutator = Some(result.unwrap());
362 return NS_OK;
363 }
364
365 NS_IMETHODIMP
SetScheme(const nsACString & aScheme,nsIURIMutator ** aMutator)366 DefaultURI::Mutator::SetScheme(const nsACString& aScheme,
367 nsIURIMutator** aMutator) {
368 ASSIGN_AND_ADDREF_THIS(aMutator);
369 if (!mMutator.isSome()) {
370 return NS_ERROR_NULL_POINTER;
371 }
372 mMutator->SetScheme(aScheme);
373 return mMutator->GetStatus();
374 }
375
376 NS_IMETHODIMP
SetUserPass(const nsACString & aUserPass,nsIURIMutator ** aMutator)377 DefaultURI::Mutator::SetUserPass(const nsACString& aUserPass,
378 nsIURIMutator** aMutator) {
379 ASSIGN_AND_ADDREF_THIS(aMutator);
380 if (!mMutator.isSome()) {
381 return NS_ERROR_NULL_POINTER;
382 }
383 int32_t index = aUserPass.FindChar(':');
384 if (index == kNotFound) {
385 mMutator->SetUsername(aUserPass);
386 mMutator->SetPassword(""_ns);
387 return mMutator->GetStatus();
388 }
389
390 mMutator->SetUsername(Substring(aUserPass, 0, index));
391 nsresult rv = mMutator->GetStatus();
392 if (NS_FAILED(rv)) {
393 return rv;
394 }
395 mMutator->SetPassword(Substring(aUserPass, index + 1));
396 rv = mMutator->GetStatus();
397 if (NS_FAILED(rv)) {
398 return rv;
399 }
400 return NS_OK;
401 }
402
403 NS_IMETHODIMP
SetUsername(const nsACString & aUsername,nsIURIMutator ** aMutator)404 DefaultURI::Mutator::SetUsername(const nsACString& aUsername,
405 nsIURIMutator** aMutator) {
406 ASSIGN_AND_ADDREF_THIS(aMutator);
407 if (!mMutator.isSome()) {
408 return NS_ERROR_NULL_POINTER;
409 }
410 mMutator->SetUsername(aUsername);
411 return mMutator->GetStatus();
412 }
413
414 NS_IMETHODIMP
SetPassword(const nsACString & aPassword,nsIURIMutator ** aMutator)415 DefaultURI::Mutator::SetPassword(const nsACString& aPassword,
416 nsIURIMutator** aMutator) {
417 ASSIGN_AND_ADDREF_THIS(aMutator);
418 if (!mMutator.isSome()) {
419 return NS_ERROR_NULL_POINTER;
420 }
421 mMutator->SetPassword(aPassword);
422 return mMutator->GetStatus();
423 }
424
425 NS_IMETHODIMP
SetHostPort(const nsACString & aHostPort,nsIURIMutator ** aMutator)426 DefaultURI::Mutator::SetHostPort(const nsACString& aHostPort,
427 nsIURIMutator** aMutator) {
428 ASSIGN_AND_ADDREF_THIS(aMutator);
429 if (!mMutator.isSome()) {
430 return NS_ERROR_NULL_POINTER;
431 }
432 mMutator->SetHostPort(aHostPort);
433 return mMutator->GetStatus();
434 }
435
436 NS_IMETHODIMP
SetHost(const nsACString & aHost,nsIURIMutator ** aMutator)437 DefaultURI::Mutator::SetHost(const nsACString& aHost,
438 nsIURIMutator** aMutator) {
439 ASSIGN_AND_ADDREF_THIS(aMutator);
440 if (!mMutator.isSome()) {
441 return NS_ERROR_NULL_POINTER;
442 }
443 mMutator->SetHostname(aHost);
444 return mMutator->GetStatus();
445 }
446
447 NS_IMETHODIMP
SetPort(int32_t aPort,nsIURIMutator ** aMutator)448 DefaultURI::Mutator::SetPort(int32_t aPort, nsIURIMutator** aMutator) {
449 ASSIGN_AND_ADDREF_THIS(aMutator);
450 if (!mMutator.isSome()) {
451 return NS_ERROR_NULL_POINTER;
452 }
453 mMutator->SetPort(aPort);
454 return mMutator->GetStatus();
455 }
456
457 NS_IMETHODIMP
SetPathQueryRef(const nsACString & aPathQueryRef,nsIURIMutator ** aMutator)458 DefaultURI::Mutator::SetPathQueryRef(const nsACString& aPathQueryRef,
459 nsIURIMutator** aMutator) {
460 ASSIGN_AND_ADDREF_THIS(aMutator);
461 if (!mMutator.isSome()) {
462 return NS_ERROR_NULL_POINTER;
463 }
464 if (aPathQueryRef.IsEmpty()) {
465 mMutator->SetFilePath(""_ns);
466 mMutator->SetQuery(""_ns);
467 mMutator->SetRef(""_ns);
468 return mMutator->GetStatus();
469 }
470
471 nsAutoCString pathQueryRef(aPathQueryRef);
472 if (!StringBeginsWith(pathQueryRef, "/"_ns)) {
473 pathQueryRef.Insert('/', 0);
474 }
475
476 RefPtr<MozURL> url;
477 mMutator->Finalize(getter_AddRefs(url));
478 mMutator = Nothing();
479
480 auto result = MozURL::Mutator::FromSpec(pathQueryRef, url);
481 if (result.isErr()) {
482 return result.unwrapErr();
483 }
484 mMutator = Some(result.unwrap());
485 return mMutator->GetStatus();
486 }
487
488 NS_IMETHODIMP
SetRef(const nsACString & aRef,nsIURIMutator ** aMutator)489 DefaultURI::Mutator::SetRef(const nsACString& aRef, nsIURIMutator** aMutator) {
490 ASSIGN_AND_ADDREF_THIS(aMutator);
491 if (!mMutator.isSome()) {
492 return NS_ERROR_NULL_POINTER;
493 }
494 mMutator->SetRef(aRef);
495 return mMutator->GetStatus();
496 }
497
498 NS_IMETHODIMP
SetFilePath(const nsACString & aFilePath,nsIURIMutator ** aMutator)499 DefaultURI::Mutator::SetFilePath(const nsACString& aFilePath,
500 nsIURIMutator** aMutator) {
501 ASSIGN_AND_ADDREF_THIS(aMutator);
502 if (!mMutator.isSome()) {
503 return NS_ERROR_NULL_POINTER;
504 }
505 mMutator->SetFilePath(aFilePath);
506 return mMutator->GetStatus();
507 }
508
509 NS_IMETHODIMP
SetQuery(const nsACString & aQuery,nsIURIMutator ** aMutator)510 DefaultURI::Mutator::SetQuery(const nsACString& aQuery,
511 nsIURIMutator** aMutator) {
512 ASSIGN_AND_ADDREF_THIS(aMutator);
513 if (!mMutator.isSome()) {
514 return NS_ERROR_NULL_POINTER;
515 }
516 mMutator->SetQuery(aQuery);
517 return mMutator->GetStatus();
518 }
519
520 NS_IMETHODIMP
SetQueryWithEncoding(const nsACString & aQuery,const mozilla::Encoding * aEncoding,nsIURIMutator ** aMutator)521 DefaultURI::Mutator::SetQueryWithEncoding(const nsACString& aQuery,
522 const mozilla::Encoding* aEncoding,
523 nsIURIMutator** aMutator) {
524 ASSIGN_AND_ADDREF_THIS(aMutator);
525 if (!mMutator.isSome()) {
526 return NS_ERROR_NULL_POINTER;
527 }
528 // we only support UTF-8 for DefaultURI
529 mMutator->SetQuery(aQuery);
530 return mMutator->GetStatus();
531 }
532
533 } // namespace net
534 } // namespace mozilla
535