Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / url / URLSearchParams.cpp
blobc141766e8321e2343a0e8741fb2d6f4778880eb3
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 "mozilla/dom/URLSearchParams.h"
9 // XXX encoding_rs.h is not self-contained, this order is required
10 #include "mozilla/Encoding.h"
11 #include "encoding_rs.h"
13 #include <new>
14 #include <type_traits>
15 #include <utility>
16 #include "js/StructuredClone.h"
17 #include "mozilla/ArrayIterator.h"
18 #include "mozilla/Attributes.h"
19 #include "mozilla/ErrorResult.h"
20 #include "mozilla/MacroForEach.h"
21 #include "mozilla/NotNull.h"
22 #include "mozilla/dom/BindingDeclarations.h"
23 #include "mozilla/dom/Record.h"
24 #include "mozilla/dom/StructuredCloneHolder.h"
25 #include "mozilla/dom/URLSearchParamsBinding.h"
26 #include "mozilla/fallible.h"
27 #include "nsDOMString.h"
28 #include "nsError.h"
29 #include "nsIGlobalObject.h"
30 #include "nsLiteralString.h"
31 #include "nsPrintfCString.h"
32 #include "nsString.h"
33 #include "nsStringFlags.h"
34 #include "nsStringIterator.h"
35 #include "nsStringStream.h"
36 #include "nsURLHelper.h"
38 namespace mozilla::dom {
40 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URLSearchParams, mParent, mObserver)
41 NS_IMPL_CYCLE_COLLECTING_ADDREF(URLSearchParams)
42 NS_IMPL_CYCLE_COLLECTING_RELEASE(URLSearchParams)
44 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URLSearchParams)
45 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
46 NS_INTERFACE_MAP_ENTRY(nsISupports)
47 NS_INTERFACE_MAP_END
49 URLSearchParams::URLSearchParams(nsISupports* aParent,
50 URLSearchParamsObserver* aObserver)
51 : mParams(new URLParams()), mParent(aParent), mObserver(aObserver) {}
53 URLSearchParams::~URLSearchParams() { DeleteAll(); }
55 JSObject* URLSearchParams::WrapObject(JSContext* aCx,
56 JS::Handle<JSObject*> aGivenProto) {
57 return URLSearchParams_Binding::Wrap(aCx, this, aGivenProto);
60 /* static */
61 already_AddRefed<URLSearchParams> URLSearchParams::Constructor(
62 const GlobalObject& aGlobal,
63 const UTF8StringSequenceSequenceOrUTF8StringUTF8StringRecordOrUTF8String&
64 aInit,
65 ErrorResult& aRv) {
66 RefPtr<URLSearchParams> sp =
67 new URLSearchParams(aGlobal.GetAsSupports(), nullptr);
69 if (aInit.IsUTF8String()) {
70 const auto& input = aInit.GetAsUTF8String();
71 if (StringBeginsWith(input, "?"_ns)) {
72 sp->ParseInput(Substring(input, 1, input.Length() - 1));
73 } else {
74 sp->ParseInput(input);
76 } else if (aInit.IsUTF8StringSequenceSequence()) {
77 const Sequence<Sequence<nsCString>>& list =
78 aInit.GetAsUTF8StringSequenceSequence();
79 for (uint32_t i = 0; i < list.Length(); ++i) {
80 const Sequence<nsCString>& item = list[i];
81 if (item.Length() != 2) {
82 nsPrintfCString err("Expected 2 items in pair but got %zu",
83 item.Length());
84 aRv.ThrowTypeError(err);
85 return nullptr;
87 sp->Append(item[0], item[1]);
89 } else if (aInit.IsUTF8StringUTF8StringRecord()) {
90 const Record<nsCString, nsCString>& record =
91 aInit.GetAsUTF8StringUTF8StringRecord();
92 for (auto& entry : record.Entries()) {
93 sp->Append(entry.mKey, entry.mValue);
95 } else {
96 MOZ_CRASH("This should not happen.");
99 return sp.forget();
102 void URLSearchParams::ParseInput(const nsACString& aInput) {
103 mParams->ParseInput(aInput);
106 uint32_t URLSearchParams::Size() const { return mParams->Length(); }
108 void URLSearchParams::Get(const nsACString& aName, nsACString& aRetval) {
109 return mParams->Get(aName, aRetval);
112 void URLSearchParams::GetAll(const nsACString& aName,
113 nsTArray<nsCString>& aRetval) {
114 return mParams->GetAll(aName, aRetval);
117 void URLSearchParams::Set(const nsACString& aName, const nsACString& aValue) {
118 mParams->Set(aName, aValue);
119 NotifyObserver();
122 void URLSearchParams::Append(const nsACString& aName,
123 const nsACString& aValue) {
124 mParams->Append(aName, aValue);
125 NotifyObserver();
128 bool URLSearchParams::Has(const nsACString& aName,
129 const Optional<nsACString>& aValue) {
130 if (!aValue.WasPassed()) {
131 return mParams->Has(aName);
133 return mParams->Has(aName, aValue.Value());
136 void URLSearchParams::Delete(const nsACString& aName,
137 const Optional<nsACString>& aValue) {
138 if (!aValue.WasPassed()) {
139 mParams->Delete(aName);
140 NotifyObserver();
141 return;
143 mParams->Delete(aName, aValue.Value());
144 NotifyObserver();
147 void URLSearchParams::DeleteAll() { mParams->DeleteAll(); }
149 void URLSearchParams::Serialize(nsACString& aValue) const {
150 mParams->Serialize(aValue, true);
153 // TODO(emilio): Allow stringifier attributes with CString return values.
154 void URLSearchParams::Stringify(nsAString& aValue) const {
155 nsAutoCString serialized;
156 mParams->Serialize(serialized, true);
157 CopyUTF8toUTF16(serialized, aValue);
160 void URLSearchParams::NotifyObserver() {
161 if (mObserver) {
162 mObserver->URLSearchParamsUpdated(this);
166 uint32_t URLSearchParams::GetIterableLength() const {
167 return mParams->Length();
170 const nsACString& URLSearchParams::GetKeyAtIndex(uint32_t aIndex) const {
171 return mParams->GetKeyAtIndex(aIndex);
174 const nsACString& URLSearchParams::GetValueAtIndex(uint32_t aIndex) const {
175 return mParams->GetValueAtIndex(aIndex);
178 void URLSearchParams::Sort(ErrorResult& aRv) {
179 mParams->Sort();
180 NotifyObserver();
183 // contentTypeWithCharset can be set to the contentType or
184 // contentType+charset based on what the spec says.
185 // See: https://fetch.spec.whatwg.org/#concept-bodyinit-extract
186 nsresult URLSearchParams::GetSendInfo(nsIInputStream** aBody,
187 uint64_t* aContentLength,
188 nsACString& aContentTypeWithCharset,
189 nsACString& aCharset) const {
190 aContentTypeWithCharset.AssignLiteral(
191 "application/x-www-form-urlencoded;charset=UTF-8");
192 aCharset.AssignLiteral("UTF-8");
194 nsAutoCString serialized;
195 Serialize(serialized);
196 *aContentLength = serialized.Length();
197 return NS_NewCStringInputStream(aBody, std::move(serialized));
200 } // namespace mozilla::dom