Bug 1913176 - Set micro surveys off by default in tests r=aaronmt
[gecko.git] / dom / fetch / BodyExtractor.cpp
blob0f8ad673d0713495202acaa53e944ec9e8112ae4
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 "BodyExtractor.h"
8 #include "mozilla/dom/File.h"
9 #include "mozilla/dom/FormData.h"
10 #include "mozilla/dom/ShadowRoot.h"
11 #include "mozilla/dom/TypedArray.h"
12 #include "mozilla/dom/URLSearchParams.h"
13 #include "mozilla/dom/XMLHttpRequest.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsContentUtils.h"
16 #include "nsDOMSerializer.h"
17 #include "nsIGlobalObject.h"
18 #include "nsIInputStream.h"
19 #include "nsIOutputStream.h"
20 #include "nsIStorageStream.h"
21 #include "nsStringStream.h"
23 namespace mozilla::dom {
25 static nsresult GetBufferDataAsStream(Vector<uint8_t>&& aData,
26 nsIInputStream** aResult,
27 uint64_t* aContentLength,
28 nsACString& aContentType,
29 nsACString& aCharset) {
30 aContentType.SetIsVoid(true);
31 aCharset.Truncate();
33 *aContentLength = aData.length();
35 nsCOMPtr<nsIInputStream> stream;
36 nsresult rv = NS_NewByteInputStream(
37 getter_AddRefs(stream),
38 AsChars(Span(aData.extractOrCopyRawBuffer(), *aContentLength)),
39 NS_ASSIGNMENT_ADOPT);
40 NS_ENSURE_SUCCESS(rv, rv);
42 stream.forget(aResult);
44 return NS_OK;
47 template <>
48 nsresult BodyExtractor<const ArrayBuffer>::GetAsStream(
49 nsIInputStream** aResult, uint64_t* aContentLength,
50 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
51 Maybe<Vector<uint8_t>> body = mBody->CreateFromData<Vector<uint8_t>>();
52 if (body.isNothing()) {
53 return NS_ERROR_OUT_OF_MEMORY;
55 return GetBufferDataAsStream(body.extract(), aResult, aContentLength,
56 aContentTypeWithCharset, aCharset);
59 template <>
60 nsresult BodyExtractor<const ArrayBufferView>::GetAsStream(
61 nsIInputStream** aResult, uint64_t* aContentLength,
62 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
63 Maybe<Vector<uint8_t>> body = mBody->CreateFromData<Vector<uint8_t>>();
64 if (body.isNothing()) {
65 return NS_ERROR_OUT_OF_MEMORY;
67 return GetBufferDataAsStream(body.extract(), aResult, aContentLength,
68 aContentTypeWithCharset, aCharset);
71 template <>
72 nsresult BodyExtractor<Document>::GetAsStream(
73 nsIInputStream** aResult, uint64_t* aContentLength,
74 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
75 NS_ENSURE_STATE(mBody);
76 aCharset.AssignLiteral("UTF-8");
78 nsresult rv;
79 nsCOMPtr<nsIStorageStream> storStream;
80 rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(storStream));
81 NS_ENSURE_SUCCESS(rv, rv);
83 nsCOMPtr<nsIOutputStream> output;
84 rv = storStream->GetOutputStream(0, getter_AddRefs(output));
85 NS_ENSURE_SUCCESS(rv, rv);
87 if (mBody->IsHTMLDocument()) {
88 aContentTypeWithCharset.AssignLiteral("text/html;charset=UTF-8");
90 nsString serialized;
91 if (!nsContentUtils::SerializeNodeToMarkup(mBody, true, serialized, false,
92 {})) {
93 return NS_ERROR_OUT_OF_MEMORY;
96 nsAutoCString utf8Serialized;
97 if (!AppendUTF16toUTF8(serialized, utf8Serialized, fallible)) {
98 return NS_ERROR_OUT_OF_MEMORY;
101 uint32_t written;
102 rv = output->Write(utf8Serialized.get(), utf8Serialized.Length(), &written);
103 NS_ENSURE_SUCCESS(rv, rv);
105 MOZ_ASSERT(written == utf8Serialized.Length());
106 } else {
107 aContentTypeWithCharset.AssignLiteral("application/xml;charset=UTF-8");
109 auto serializer = MakeUnique<nsDOMSerializer>();
111 // Make sure to use the encoding we'll send
112 ErrorResult res;
113 serializer->SerializeToStream(*mBody, output, u"UTF-8"_ns, res);
114 if (NS_WARN_IF(res.Failed())) {
115 return res.StealNSResult();
119 output->Close();
121 uint32_t length;
122 rv = storStream->GetLength(&length);
123 NS_ENSURE_SUCCESS(rv, rv);
124 *aContentLength = length;
126 rv = storStream->NewInputStream(0, aResult);
127 NS_ENSURE_SUCCESS(rv, rv);
128 return NS_OK;
131 template <>
132 nsresult BodyExtractor<const nsAString>::GetAsStream(
133 nsIInputStream** aResult, uint64_t* aContentLength,
134 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
135 nsCString encoded;
136 if (!CopyUTF16toUTF8(*mBody, encoded, fallible)) {
137 return NS_ERROR_OUT_OF_MEMORY;
140 uint32_t encodedLength = encoded.Length();
141 nsresult rv = NS_NewCStringInputStream(aResult, std::move(encoded));
142 if (NS_WARN_IF(NS_FAILED(rv))) {
143 return rv;
146 *aContentLength = encodedLength;
147 aContentTypeWithCharset.AssignLiteral("text/plain;charset=UTF-8");
148 aCharset.AssignLiteral("UTF-8");
149 return NS_OK;
152 template <>
153 nsresult BodyExtractor<nsIInputStream>::GetAsStream(
154 nsIInputStream** aResult, uint64_t* aContentLength,
155 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
156 aContentTypeWithCharset.AssignLiteral("text/plain");
157 aCharset.Truncate();
159 nsresult rv = mBody->Available(aContentLength);
160 NS_ENSURE_SUCCESS(rv, rv);
162 nsCOMPtr<nsIInputStream> stream(mBody);
163 stream.forget(aResult);
164 return NS_OK;
167 template <>
168 nsresult BodyExtractor<const Blob>::GetAsStream(
169 nsIInputStream** aResult, uint64_t* aContentLength,
170 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
171 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
172 aCharset);
175 template <>
176 nsresult BodyExtractor<const FormData>::GetAsStream(
177 nsIInputStream** aResult, uint64_t* aContentLength,
178 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
179 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
180 aCharset);
183 template <>
184 nsresult BodyExtractor<const URLSearchParams>::GetAsStream(
185 nsIInputStream** aResult, uint64_t* aContentLength,
186 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
187 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
188 aCharset);
191 } // namespace mozilla::dom