1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "base/basictypes.h"
10 #include "nsNetUtil.h"
11 #include "nsIClassInfoImpl.h"
12 #include "nsIIOService.h"
13 #include "nsIStandardURL.h"
15 #include "nsReadableUtils.h"
17 #include "nsIObjectInputStream.h"
18 #include "nsIObjectOutputStream.h"
19 #include "nsQueryObject.h"
20 #include "mozilla/ipc/URIUtils.h"
22 using namespace mozilla::ipc
;
24 static NS_DEFINE_CID(kJARURICID
, NS_JARURI_CID
);
26 ////////////////////////////////////////////////////////////////////////////////
28 NS_IMPL_CLASSINFO(nsJARURI
, nullptr, nsIClassInfo::THREADSAFE
, NS_JARURI_CID
)
29 // Empty CI getter. We only need nsIClassInfo for Serialization
30 NS_IMPL_CI_INTERFACE_GETTER0(nsJARURI
)
32 nsJARURI::nsJARURI() {}
34 nsJARURI::~nsJARURI() {}
36 // XXX Why is this threadsafe?
37 NS_IMPL_ADDREF(nsJARURI
)
38 NS_IMPL_RELEASE(nsJARURI
)
39 NS_INTERFACE_MAP_BEGIN(nsJARURI
)
40 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIJARURI
)
41 NS_INTERFACE_MAP_ENTRY(nsIURI
)
42 NS_INTERFACE_MAP_ENTRY(nsIURL
)
43 NS_INTERFACE_MAP_ENTRY(nsIJARURI
)
44 NS_INTERFACE_MAP_ENTRY(nsISerializable
)
45 NS_IMPL_QUERY_CLASSINFO(nsJARURI
)
46 NS_INTERFACE_MAP_ENTRY(nsINestedURI
)
47 NS_INTERFACE_MAP_ENTRY_CONCRETE(nsJARURI
)
50 nsresult
nsJARURI::Init(const char* charsetHint
) {
51 mCharsetHint
= charsetHint
;
55 #define NS_JAR_SCHEME "jar:"_ns
56 #define NS_JAR_DELIMITER "!/"_ns
57 #define NS_BOGUS_ENTRY_SCHEME "x:///"_ns
59 // FormatSpec takes the entry spec (including the "x:///" at the
60 // beginning) and gives us a full JAR spec.
61 nsresult
nsJARURI::FormatSpec(const nsACString
& entrySpec
, nsACString
& result
,
62 bool aIncludeScheme
) {
63 // The entrySpec MUST start with "x:///"
64 NS_ASSERTION(StringBeginsWith(entrySpec
, NS_BOGUS_ENTRY_SCHEME
),
67 nsAutoCString fileSpec
;
68 nsresult rv
= mJARFile
->GetSpec(fileSpec
);
69 if (NS_FAILED(rv
)) return rv
;
72 result
= NS_JAR_SCHEME
;
76 result
.Append(fileSpec
+ NS_JAR_DELIMITER
+
77 Substring(entrySpec
, 5, entrySpec
.Length() - 5));
81 nsresult
nsJARURI::CreateEntryURL(const nsACString
& entryFilename
,
82 const char* charset
, nsIURL
** url
) {
84 // Flatten the concatenation, just in case. See bug 128288
85 nsAutoCString
spec(NS_BOGUS_ENTRY_SCHEME
+ entryFilename
);
86 return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID
)
87 .Apply(&nsIStandardURLMutator::Init
, nsIStandardURL::URLTYPE_NO_AUTHORITY
,
88 -1, spec
, charset
, nullptr, nullptr)
92 ////////////////////////////////////////////////////////////////////////////////
93 // nsISerializable methods:
96 nsJARURI::Read(nsIObjectInputStream
* aStream
) {
97 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
98 return NS_ERROR_NOT_IMPLEMENTED
;
101 nsresult
nsJARURI::ReadPrivate(nsIObjectInputStream
* aInputStream
) {
104 nsCOMPtr
<nsISupports
> supports
;
105 rv
= aInputStream
->ReadObject(true, getter_AddRefs(supports
));
106 NS_ENSURE_SUCCESS(rv
, rv
);
108 mJARFile
= do_QueryInterface(supports
, &rv
);
109 NS_ENSURE_SUCCESS(rv
, rv
);
111 rv
= aInputStream
->ReadObject(true, getter_AddRefs(supports
));
112 NS_ENSURE_SUCCESS(rv
, rv
);
114 mJAREntry
= do_QueryInterface(supports
);
115 NS_ENSURE_SUCCESS(rv
, rv
);
117 rv
= aInputStream
->ReadCString(mCharsetHint
);
122 nsJARURI::Write(nsIObjectOutputStream
* aOutputStream
) {
125 rv
= aOutputStream
->WriteCompoundObject(mJARFile
, NS_GET_IID(nsIURI
), true);
126 NS_ENSURE_SUCCESS(rv
, rv
);
128 rv
= aOutputStream
->WriteCompoundObject(mJAREntry
, NS_GET_IID(nsIURL
), true);
129 NS_ENSURE_SUCCESS(rv
, rv
);
131 rv
= aOutputStream
->WriteStringZ(mCharsetHint
.get());
135 ////////////////////////////////////////////////////////////////////////////////
139 nsJARURI::GetSpec(nsACString
& aSpec
) {
140 nsAutoCString entrySpec
;
141 mJAREntry
->GetSpec(entrySpec
);
142 return FormatSpec(entrySpec
, aSpec
);
146 nsJARURI::GetSpecIgnoringRef(nsACString
& aSpec
) {
147 nsAutoCString entrySpec
;
148 mJAREntry
->GetSpecIgnoringRef(entrySpec
);
149 return FormatSpec(entrySpec
, aSpec
);
153 nsJARURI::GetDisplaySpec(nsACString
& aUnicodeSpec
) {
154 return GetSpec(aUnicodeSpec
);
158 nsJARURI::GetDisplayHostPort(nsACString
& aUnicodeHostPort
) {
159 return GetHostPort(aUnicodeHostPort
);
163 nsJARURI::GetDisplayPrePath(nsACString
& aPrePath
) {
164 return GetPrePath(aPrePath
);
168 nsJARURI::GetDisplayHost(nsACString
& aUnicodeHost
) {
169 return GetHost(aUnicodeHost
);
173 nsJARURI::GetHasRef(bool* result
) { return mJAREntry
->GetHasRef(result
); }
175 nsresult
nsJARURI::SetSpecInternal(const nsACString
& aSpec
) {
176 return SetSpecWithBase(aSpec
, nullptr);
179 // Queries this list of interfaces. If none match, it queries mURI.
180 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsJARURI::Mutator
, nsIURISetters
, nsIURIMutator
,
181 nsIURLMutator
, nsISerializable
,
185 nsJARURI::Mutator::SetFileName(const nsACString
& aFileName
,
186 nsIURIMutator
** aMutator
) {
188 return NS_ERROR_NULL_POINTER
;
191 nsCOMPtr
<nsIURIMutator
> mutator
= this;
192 mutator
.forget(aMutator
);
194 return mURI
->SetFileNameInternal(aFileName
);
198 nsJARURI::Mutator::SetFileBaseName(const nsACString
& aFileBaseName
,
199 nsIURIMutator
** aMutator
) {
201 return NS_ERROR_NULL_POINTER
;
204 nsCOMPtr
<nsIURIMutator
> mutator
= this;
205 mutator
.forget(aMutator
);
207 return mURI
->SetFileBaseNameInternal(aFileBaseName
);
211 nsJARURI::Mutator::SetFileExtension(const nsACString
& aFileExtension
,
212 nsIURIMutator
** aMutator
) {
214 return NS_ERROR_NULL_POINTER
;
217 nsCOMPtr
<nsIURIMutator
> mutator
= this;
218 mutator
.forget(aMutator
);
220 return mURI
->SetFileExtensionInternal(aFileExtension
);
224 nsJARURI::Mutate(nsIURIMutator
** aMutator
) {
225 RefPtr
<nsJARURI::Mutator
> mutator
= new nsJARURI::Mutator();
226 nsresult rv
= mutator
->InitFromURI(this);
230 mutator
.forget(aMutator
);
234 nsresult
nsJARURI::SetSpecWithBase(const nsACString
& aSpec
, nsIURI
* aBaseURL
) {
237 nsCOMPtr
<nsIIOService
> ioServ(do_GetIOService(&rv
));
238 NS_ENSURE_SUCCESS(rv
, rv
);
240 nsAutoCString scheme
;
241 rv
= ioServ
->ExtractScheme(aSpec
, scheme
);
243 // not an absolute URI
244 if (!aBaseURL
) return NS_ERROR_MALFORMED_URI
;
246 RefPtr
<nsJARURI
> otherJAR
= do_QueryObject(aBaseURL
);
247 NS_ENSURE_TRUE(otherJAR
, NS_NOINTERFACE
);
249 mJARFile
= otherJAR
->mJARFile
;
251 nsCOMPtr
<nsIURI
> entry
;
253 rv
= NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID
)
254 .Apply(&nsIStandardURLMutator::Init
,
255 nsIStandardURL::URLTYPE_NO_AUTHORITY
, -1, aSpec
,
256 mCharsetHint
.get(), otherJAR
->mJAREntry
, nullptr)
262 mJAREntry
= do_QueryInterface(entry
);
263 if (!mJAREntry
) return NS_NOINTERFACE
;
268 NS_ENSURE_TRUE(scheme
.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI
);
270 nsACString::const_iterator begin
, end
;
271 aSpec
.BeginReading(begin
);
272 aSpec
.EndReading(end
);
274 while (begin
!= end
&& *begin
!= ':') ++begin
;
276 ++begin
; // now we're past the "jar:"
278 nsACString::const_iterator delim_begin
= begin
;
279 nsACString::const_iterator delim_end
= end
;
280 nsACString::const_iterator frag
= begin
;
282 if (FindInReadable(NS_JAR_DELIMITER
, delim_begin
, delim_end
)) {
285 while (frag
!= end
&& (*frag
!= '#' && *frag
!= '?')) {
289 // there was a fragment or query, mark that as the end of the URL to scan
293 // Search backward from the end for the "!/" delimiter. Remember, jar URLs
295 // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html
296 // This gets the b.html document from out of the a.jar file, that's
297 // contained within the bar.jar file.
298 // Also, the outermost "inner" URI may be a relative URI:
299 // jar:../relative.jar!/a.html
304 if (!RFindInReadable(NS_JAR_DELIMITER
, delim_begin
, delim_end
)) {
305 return NS_ERROR_MALFORMED_URI
;
308 rv
= ioServ
->NewURI(Substring(begin
, delim_begin
), mCharsetHint
.get(),
309 aBaseURL
, getter_AddRefs(mJARFile
));
310 if (NS_FAILED(rv
)) return rv
;
312 // skip over any extra '/' chars
313 while (*delim_end
== '/') ++delim_end
;
315 aSpec
.EndReading(end
); // set to the original 'end'
316 return SetJAREntry(Substring(delim_end
, end
));
320 nsJARURI::GetPrePath(nsACString
& prePath
) {
321 prePath
= NS_JAR_SCHEME
;
326 nsJARURI::GetScheme(nsACString
& aScheme
) {
331 nsresult
nsJARURI::SetScheme(const nsACString
& aScheme
) {
332 // doesn't make sense to set the scheme of a jar: URL
333 return NS_ERROR_FAILURE
;
337 nsJARURI::GetUserPass(nsACString
& aUserPass
) { return NS_ERROR_FAILURE
; }
339 nsresult
nsJARURI::SetUserPass(const nsACString
& aUserPass
) {
340 return NS_ERROR_FAILURE
;
344 nsJARURI::GetUsername(nsACString
& aUsername
) { return NS_ERROR_FAILURE
; }
346 nsresult
nsJARURI::SetUsername(const nsACString
& aUsername
) {
347 return NS_ERROR_FAILURE
;
351 nsJARURI::GetPassword(nsACString
& aPassword
) { return NS_ERROR_FAILURE
; }
353 nsresult
nsJARURI::SetPassword(const nsACString
& aPassword
) {
354 return NS_ERROR_FAILURE
;
358 nsJARURI::GetHostPort(nsACString
& aHostPort
) { return NS_ERROR_FAILURE
; }
360 nsresult
nsJARURI::SetHostPort(const nsACString
& aHostPort
) {
361 return NS_ERROR_FAILURE
;
365 nsJARURI::GetHost(nsACString
& aHost
) { return NS_ERROR_FAILURE
; }
367 nsresult
nsJARURI::SetHost(const nsACString
& aHost
) { return NS_ERROR_FAILURE
; }
370 nsJARURI::GetPort(int32_t* aPort
) { return NS_ERROR_FAILURE
; }
372 nsresult
nsJARURI::SetPort(int32_t aPort
) { return NS_ERROR_FAILURE
; }
374 nsresult
nsJARURI::GetPathQueryRef(nsACString
& aPath
) {
375 nsAutoCString entrySpec
;
376 mJAREntry
->GetSpec(entrySpec
);
377 return FormatSpec(entrySpec
, aPath
, false);
380 nsresult
nsJARURI::SetPathQueryRef(const nsACString
& aPath
) {
381 return NS_ERROR_FAILURE
;
385 nsJARURI::GetAsciiSpec(nsACString
& aSpec
) {
386 // XXX Shouldn't this like... make sure it returns ASCII or something?
387 return GetSpec(aSpec
);
391 nsJARURI::GetAsciiHostPort(nsACString
& aHostPort
) { return NS_ERROR_FAILURE
; }
394 nsJARURI::GetAsciiHost(nsACString
& aHost
) { return NS_ERROR_FAILURE
; }
397 nsJARURI::Equals(nsIURI
* other
, bool* result
) {
398 return EqualsInternal(other
, eHonorRef
, result
);
402 nsJARURI::EqualsExceptRef(nsIURI
* other
, bool* result
) {
403 return EqualsInternal(other
, eIgnoreRef
, result
);
408 nsresult
nsJARURI::EqualsInternal(nsIURI
* other
,
409 nsJARURI::RefHandlingEnum refHandlingMode
,
413 if (!other
) return NS_OK
; // not equal
415 RefPtr
<nsJARURI
> otherJAR
= do_QueryObject(other
);
416 if (!otherJAR
) return NS_OK
; // not equal
419 nsresult rv
= mJARFile
->Equals(otherJAR
->mJARFile
, &equal
);
420 if (NS_FAILED(rv
) || !equal
) {
421 return rv
; // not equal
424 return refHandlingMode
== eHonorRef
425 ? mJAREntry
->Equals(otherJAR
->mJAREntry
, result
)
426 : mJAREntry
->EqualsExceptRef(otherJAR
->mJAREntry
, result
);
430 nsJARURI::SchemeIs(const char* i_Scheme
, bool* o_Equals
) {
431 MOZ_ASSERT(o_Equals
);
437 *o_Equals
= PL_strcasecmp("jar", i_Scheme
) ? false : true;
441 nsresult
nsJARURI::Clone(nsIURI
** result
) {
442 RefPtr
<nsJARURI
> uri
= new nsJARURI();
443 uri
->mJARFile
= mJARFile
;
444 uri
->mJAREntry
= mJAREntry
;
451 nsJARURI::Resolve(const nsACString
& relativePath
, nsACString
& result
) {
454 nsCOMPtr
<nsIIOService
> ioServ(do_GetIOService(&rv
));
455 if (NS_FAILED(rv
)) return rv
;
457 nsAutoCString scheme
;
458 rv
= ioServ
->ExtractScheme(relativePath
, scheme
);
459 if (NS_SUCCEEDED(rv
)) {
460 // then aSpec is absolute
461 result
= relativePath
;
465 nsAutoCString resolvedPath
;
466 mJAREntry
->Resolve(relativePath
, resolvedPath
);
468 return FormatSpec(resolvedPath
, result
);
471 ////////////////////////////////////////////////////////////////////////////////
475 nsJARURI::GetFilePath(nsACString
& filePath
) {
476 return mJAREntry
->GetFilePath(filePath
);
479 nsresult
nsJARURI::SetFilePath(const nsACString
& filePath
) {
480 return NS_MutateURI(mJAREntry
).SetFilePath(filePath
).Finalize(mJAREntry
);
484 nsJARURI::GetQuery(nsACString
& query
) { return mJAREntry
->GetQuery(query
); }
486 nsresult
nsJARURI::SetQuery(const nsACString
& query
) {
487 return NS_MutateURI(mJAREntry
).SetQuery(query
).Finalize(mJAREntry
);
490 nsresult
nsJARURI::SetQueryWithEncoding(const nsACString
& query
,
491 const Encoding
* encoding
) {
492 return NS_MutateURI(mJAREntry
)
493 .SetQueryWithEncoding(query
, encoding
)
494 .Finalize(mJAREntry
);
498 nsJARURI::GetRef(nsACString
& ref
) { return mJAREntry
->GetRef(ref
); }
500 nsresult
nsJARURI::SetRef(const nsACString
& ref
) {
501 return NS_MutateURI(mJAREntry
).SetRef(ref
).Finalize(mJAREntry
);
505 nsJARURI::GetDirectory(nsACString
& directory
) {
506 return mJAREntry
->GetDirectory(directory
);
510 nsJARURI::GetFileName(nsACString
& fileName
) {
511 return mJAREntry
->GetFileName(fileName
);
514 nsresult
nsJARURI::SetFileNameInternal(const nsACString
& fileName
) {
515 return NS_MutateURI(mJAREntry
)
516 .Apply(&nsIURLMutator::SetFileName
, fileName
, nullptr)
517 .Finalize(mJAREntry
);
521 nsJARURI::GetFileBaseName(nsACString
& fileBaseName
) {
522 return mJAREntry
->GetFileBaseName(fileBaseName
);
525 nsresult
nsJARURI::SetFileBaseNameInternal(const nsACString
& fileBaseName
) {
526 return NS_MutateURI(mJAREntry
)
527 .Apply(&nsIURLMutator::SetFileBaseName
, fileBaseName
, nullptr)
528 .Finalize(mJAREntry
);
532 nsJARURI::GetFileExtension(nsACString
& fileExtension
) {
533 return mJAREntry
->GetFileExtension(fileExtension
);
536 nsresult
nsJARURI::SetFileExtensionInternal(const nsACString
& fileExtension
) {
537 return NS_MutateURI(mJAREntry
)
538 .Apply(&nsIURLMutator::SetFileExtension
, fileExtension
, nullptr)
539 .Finalize(mJAREntry
);
543 nsJARURI::GetCommonBaseSpec(nsIURI
* uriToCompare
, nsACString
& commonSpec
) {
544 commonSpec
.Truncate();
546 NS_ENSURE_ARG_POINTER(uriToCompare
);
548 commonSpec
.Truncate();
549 nsCOMPtr
<nsIJARURI
> otherJARURI(do_QueryInterface(uriToCompare
));
555 nsCOMPtr
<nsIURI
> otherJARFile
;
556 nsresult rv
= otherJARURI
->GetJARFile(getter_AddRefs(otherJARFile
));
557 if (NS_FAILED(rv
)) return rv
;
560 rv
= mJARFile
->Equals(otherJARFile
, &equal
);
561 if (NS_FAILED(rv
)) return rv
;
564 // See what the JAR file URIs have in common
565 nsCOMPtr
<nsIURL
> ourJARFileURL(do_QueryInterface(mJARFile
));
566 if (!ourJARFileURL
) {
567 // Not a URL, so nothing in common
570 nsAutoCString common
;
571 rv
= ourJARFileURL
->GetCommonBaseSpec(otherJARFile
, common
);
572 if (NS_FAILED(rv
)) return rv
;
574 commonSpec
= NS_JAR_SCHEME
+ common
;
578 // At this point we have the same JAR file. Compare the JAREntrys
579 nsAutoCString otherEntry
;
580 rv
= otherJARURI
->GetJAREntry(otherEntry
);
581 if (NS_FAILED(rv
)) return rv
;
583 nsCOMPtr
<nsIURL
> url
;
584 rv
= CreateEntryURL(otherEntry
, nullptr, getter_AddRefs(url
));
585 if (NS_FAILED(rv
)) return rv
;
587 nsAutoCString common
;
588 rv
= mJAREntry
->GetCommonBaseSpec(url
, common
);
589 if (NS_FAILED(rv
)) return rv
;
591 rv
= FormatSpec(common
, commonSpec
);
596 nsJARURI::GetRelativeSpec(nsIURI
* uriToCompare
, nsACString
& relativeSpec
) {
597 GetSpec(relativeSpec
);
599 NS_ENSURE_ARG_POINTER(uriToCompare
);
601 nsCOMPtr
<nsIJARURI
> otherJARURI(do_QueryInterface(uriToCompare
));
607 nsCOMPtr
<nsIURI
> otherJARFile
;
608 nsresult rv
= otherJARURI
->GetJARFile(getter_AddRefs(otherJARFile
));
609 if (NS_FAILED(rv
)) return rv
;
612 rv
= mJARFile
->Equals(otherJARFile
, &equal
);
613 if (NS_FAILED(rv
)) return rv
;
616 // We live in different JAR files. Nothing in common.
620 // Same JAR file. Compare the JAREntrys
621 nsAutoCString otherEntry
;
622 rv
= otherJARURI
->GetJAREntry(otherEntry
);
623 if (NS_FAILED(rv
)) return rv
;
625 nsCOMPtr
<nsIURL
> url
;
626 rv
= CreateEntryURL(otherEntry
, nullptr, getter_AddRefs(url
));
627 if (NS_FAILED(rv
)) return rv
;
629 nsAutoCString relativeEntrySpec
;
630 rv
= mJAREntry
->GetRelativeSpec(url
, relativeEntrySpec
);
631 if (NS_FAILED(rv
)) return rv
;
633 if (!StringBeginsWith(relativeEntrySpec
, NS_BOGUS_ENTRY_SCHEME
)) {
634 // An actual relative spec!
635 relativeSpec
= relativeEntrySpec
;
640 ////////////////////////////////////////////////////////////////////////////////
641 // nsIJARURI methods:
644 nsJARURI::GetJARFile(nsIURI
** jarFile
) { return GetInnerURI(jarFile
); }
647 nsJARURI::GetJAREntry(nsACString
& entryPath
) {
648 nsAutoCString filePath
;
649 mJAREntry
->GetFilePath(filePath
);
650 NS_ASSERTION(filePath
.Length() > 0, "path should never be empty!");
651 // Trim off the leading '/'
652 entryPath
= Substring(filePath
, 1, filePath
.Length() - 1);
656 nsresult
nsJARURI::SetJAREntry(const nsACString
& entryPath
) {
657 return CreateEntryURL(entryPath
, mCharsetHint
.get(),
658 getter_AddRefs(mJAREntry
));
661 ////////////////////////////////////////////////////////////////////////////////
664 nsJARURI::GetInnerURI(nsIURI
** aURI
) {
665 nsCOMPtr
<nsIURI
> uri
= mJARFile
;
671 nsJARURI::GetInnermostURI(nsIURI
** uri
) {
672 return NS_ImplGetInnermostURI(this, uri
);
675 void nsJARURI::Serialize(URIParams
& aParams
) {
678 SerializeURI(mJARFile
, params
.jarFile());
679 SerializeURI(mJAREntry
, params
.jarEntry());
680 params
.charset() = mCharsetHint
;
685 bool nsJARURI::Deserialize(const URIParams
& aParams
) {
686 if (aParams
.type() != URIParams::TJARURIParams
) {
687 NS_ERROR("Received unknown parameters from the other process!");
691 const JARURIParams
& params
= aParams
.get_JARURIParams();
693 nsCOMPtr
<nsIURI
> file
= DeserializeURI(params
.jarFile());
695 NS_ERROR("Couldn't deserialize jar file URI!");
699 nsCOMPtr
<nsIURI
> entry
= DeserializeURI(params
.jarEntry());
701 NS_ERROR("Couldn't deserialize jar entry URI!");
705 nsCOMPtr
<nsIURL
> entryURL
= do_QueryInterface(entry
);
707 NS_ERROR("Couldn't QI jar entry URI to nsIURL!");
712 mJAREntry
.swap(entryURL
);
713 mCharsetHint
= params
.charset();