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