Backed out changeset 2a94e8bad21e (bug 1874716) for causing CXX related build bustage...
[gecko.git] / dom / fetch / BodyExtractor.cpp
blobf6ad111e30b16712a8d66104a0814538461eba26
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/TypedArray.h"
11 #include "mozilla/dom/URLSearchParams.h"
12 #include "mozilla/dom/XMLHttpRequest.h"
13 #include "mozilla/UniquePtr.h"
14 #include "nsContentUtils.h"
15 #include "nsDOMSerializer.h"
16 #include "nsIGlobalObject.h"
17 #include "nsIInputStream.h"
18 #include "nsIOutputStream.h"
19 #include "nsIStorageStream.h"
20 #include "nsStringStream.h"
22 namespace mozilla::dom {
24 static nsresult GetBufferDataAsStream(Vector<uint8_t>&& aData,
25 nsIInputStream** aResult,
26 uint64_t* aContentLength,
27 nsACString& aContentType,
28 nsACString& aCharset) {
29 aContentType.SetIsVoid(true);
30 aCharset.Truncate();
32 *aContentLength = aData.length();
34 nsCOMPtr<nsIInputStream> stream;
35 nsresult rv = NS_NewByteInputStream(
36 getter_AddRefs(stream),
37 AsChars(Span(aData.extractOrCopyRawBuffer(), *aContentLength)),
38 NS_ASSIGNMENT_ADOPT);
39 NS_ENSURE_SUCCESS(rv, rv);
41 stream.forget(aResult);
43 return NS_OK;
46 template <>
47 nsresult BodyExtractor<const ArrayBuffer>::GetAsStream(
48 nsIInputStream** aResult, uint64_t* aContentLength,
49 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
50 Maybe<Vector<uint8_t>> body = mBody->CreateFromData<Vector<uint8_t>>();
51 if (body.isNothing()) {
52 return NS_ERROR_OUT_OF_MEMORY;
54 return GetBufferDataAsStream(body.extract(), aResult, aContentLength,
55 aContentTypeWithCharset, aCharset);
58 template <>
59 nsresult BodyExtractor<const ArrayBufferView>::GetAsStream(
60 nsIInputStream** aResult, uint64_t* aContentLength,
61 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
62 Maybe<Vector<uint8_t>> body = mBody->CreateFromData<Vector<uint8_t>>();
63 if (body.isNothing()) {
64 return NS_ERROR_OUT_OF_MEMORY;
66 return GetBufferDataAsStream(body.extract(), aResult, aContentLength,
67 aContentTypeWithCharset, aCharset);
70 template <>
71 nsresult BodyExtractor<Document>::GetAsStream(
72 nsIInputStream** aResult, uint64_t* aContentLength,
73 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
74 NS_ENSURE_STATE(mBody);
75 aCharset.AssignLiteral("UTF-8");
77 nsresult rv;
78 nsCOMPtr<nsIStorageStream> storStream;
79 rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(storStream));
80 NS_ENSURE_SUCCESS(rv, rv);
82 nsCOMPtr<nsIOutputStream> output;
83 rv = storStream->GetOutputStream(0, getter_AddRefs(output));
84 NS_ENSURE_SUCCESS(rv, rv);
86 if (mBody->IsHTMLDocument()) {
87 aContentTypeWithCharset.AssignLiteral("text/html;charset=UTF-8");
89 nsString serialized;
90 if (!nsContentUtils::SerializeNodeToMarkup(mBody, true, serialized)) {
91 return NS_ERROR_OUT_OF_MEMORY;
94 nsAutoCString utf8Serialized;
95 if (!AppendUTF16toUTF8(serialized, utf8Serialized, fallible)) {
96 return NS_ERROR_OUT_OF_MEMORY;
99 uint32_t written;
100 rv = output->Write(utf8Serialized.get(), utf8Serialized.Length(), &written);
101 NS_ENSURE_SUCCESS(rv, rv);
103 MOZ_ASSERT(written == utf8Serialized.Length());
104 } else {
105 aContentTypeWithCharset.AssignLiteral("application/xml;charset=UTF-8");
107 auto serializer = MakeUnique<nsDOMSerializer>();
109 // Make sure to use the encoding we'll send
110 ErrorResult res;
111 serializer->SerializeToStream(*mBody, output, u"UTF-8"_ns, res);
112 if (NS_WARN_IF(res.Failed())) {
113 return res.StealNSResult();
117 output->Close();
119 uint32_t length;
120 rv = storStream->GetLength(&length);
121 NS_ENSURE_SUCCESS(rv, rv);
122 *aContentLength = length;
124 rv = storStream->NewInputStream(0, aResult);
125 NS_ENSURE_SUCCESS(rv, rv);
126 return NS_OK;
129 template <>
130 nsresult BodyExtractor<const nsAString>::GetAsStream(
131 nsIInputStream** aResult, uint64_t* aContentLength,
132 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
133 nsCString encoded;
134 if (!CopyUTF16toUTF8(*mBody, encoded, fallible)) {
135 return NS_ERROR_OUT_OF_MEMORY;
138 uint32_t encodedLength = encoded.Length();
139 nsresult rv = NS_NewCStringInputStream(aResult, std::move(encoded));
140 if (NS_WARN_IF(NS_FAILED(rv))) {
141 return rv;
144 *aContentLength = encodedLength;
145 aContentTypeWithCharset.AssignLiteral("text/plain;charset=UTF-8");
146 aCharset.AssignLiteral("UTF-8");
147 return NS_OK;
150 template <>
151 nsresult BodyExtractor<nsIInputStream>::GetAsStream(
152 nsIInputStream** aResult, uint64_t* aContentLength,
153 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
154 aContentTypeWithCharset.AssignLiteral("text/plain");
155 aCharset.Truncate();
157 nsresult rv = mBody->Available(aContentLength);
158 NS_ENSURE_SUCCESS(rv, rv);
160 nsCOMPtr<nsIInputStream> stream(mBody);
161 stream.forget(aResult);
162 return NS_OK;
165 template <>
166 nsresult BodyExtractor<const Blob>::GetAsStream(
167 nsIInputStream** aResult, uint64_t* aContentLength,
168 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
169 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
170 aCharset);
173 template <>
174 nsresult BodyExtractor<const FormData>::GetAsStream(
175 nsIInputStream** aResult, uint64_t* aContentLength,
176 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
177 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
178 aCharset);
181 template <>
182 nsresult BodyExtractor<const URLSearchParams>::GetAsStream(
183 nsIInputStream** aResult, uint64_t* aContentLength,
184 nsACString& aContentTypeWithCharset, nsACString& aCharset) const {
185 return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
186 aCharset);
189 } // namespace mozilla::dom