mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-06 07:17:30 +09:00
Issue #1442 - Part 10a - Unify body extraction in Fetch/Beacon/XHR. https://bugzilla.mozilla.org/show_bug.cgi?id=1329298 Pre-requisite for Part 11.
This commit is contained in:
parent
3979e4847c
commit
a4146b60a4
15 changed files with 439 additions and 447 deletions
|
|
@ -398,7 +398,7 @@ FormData::Constructor(const GlobalObject& aGlobal,
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||||
nsACString& aContentType, nsACString& aCharset)
|
nsACString& aContentTypeWithCharset, nsACString& aCharset)
|
||||||
{
|
{
|
||||||
FSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
|
FSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@ FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.GetContentType(aContentType);
|
fs.GetContentType(aContentTypeWithCharset);
|
||||||
aCharset.Truncate();
|
aCharset.Truncate();
|
||||||
*aContentLength = 0;
|
*aContentLength = 0;
|
||||||
NS_ADDREF(*aBody = fs.GetSubmissionBody(aContentLength));
|
NS_ADDREF(*aBody = fs.GetSubmissionBody(aContentLength));
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@
|
||||||
#include "nsPluginArray.h"
|
#include "nsPluginArray.h"
|
||||||
#include "nsMimeTypeArray.h"
|
#include "nsMimeTypeArray.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "mozilla/dom/BodyExtractor.h"
|
||||||
#include "mozilla/dom/DesktopNotification.h"
|
#include "mozilla/dom/DesktopNotification.h"
|
||||||
|
#include "mozilla/dom/FetchBinding.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
#include "nsGeolocation.h"
|
#include "nsGeolocation.h"
|
||||||
#include "nsIClassOfService.h"
|
#include "nsIClassOfService.h"
|
||||||
|
|
@ -857,7 +859,51 @@ BeaconStreamListener::OnDataAvailable(nsIRequest *aRequest,
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Navigator::SendBeacon(const nsAString& aUrl,
|
Navigator::SendBeacon(const nsAString& aUrl,
|
||||||
const Nullable<ArrayBufferViewOrBlobOrStringOrFormData>& aData,
|
const Nullable<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aData,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
if (aData.IsNull()) {
|
||||||
|
return SendBeaconInternal(aUrl, nullptr, /* isBlob */ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsArrayBuffer()) {
|
||||||
|
BodyExtractor<const ArrayBuffer> body(&aData.Value().GetAsArrayBuffer());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsArrayBufferView()) {
|
||||||
|
BodyExtractor<const ArrayBufferView> body(&aData.Value().GetAsArrayBufferView());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsBlob()) {
|
||||||
|
BodyExtractor<Blob> body(&aData.Value().GetAsBlob());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob */ true, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsFormData()) {
|
||||||
|
BodyExtractor<FormData> body(&aData.Value().GetAsFormData());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsUSVString()) {
|
||||||
|
BodyExtractor<const nsAString> body(&aData.Value().GetAsUSVString());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData.Value().IsURLSearchParams()) {
|
||||||
|
BodyExtractor<URLSearchParams> body(&aData.Value().GetAsURLSearchParams());
|
||||||
|
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_CRASH("Invalid data type.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Navigator::SendBeaconInternal(const nsAString& aUrl,
|
||||||
|
BodyExtractorBase* aBody,
|
||||||
|
bool aIsBlob,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
if (!mWindow) {
|
if (!mWindow) {
|
||||||
|
|
@ -900,7 +946,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||||
nsIChannel::LOAD_CLASSIFY_URI;
|
nsIChannel::LOAD_CLASSIFY_URI;
|
||||||
|
|
||||||
// No need to use CORS for sendBeacon unless it's a BLOB
|
// No need to use CORS for sendBeacon unless it's a BLOB
|
||||||
nsSecurityFlags securityFlags = (!aData.IsNull() && aData.Value().IsBlob())
|
nsSecurityFlags securityFlags = aIsBlob
|
||||||
? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS
|
? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS
|
||||||
: nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
|
: nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
|
||||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||||
|
|
@ -928,67 +974,15 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||||
}
|
}
|
||||||
httpChannel->SetReferrer(documentURI);
|
httpChannel->SetReferrer(documentURI);
|
||||||
|
|
||||||
nsCString mimeType;
|
|
||||||
if (!aData.IsNull()) {
|
|
||||||
nsCOMPtr<nsIInputStream> in;
|
nsCOMPtr<nsIInputStream> in;
|
||||||
|
nsAutoCString contentTypeWithCharset;
|
||||||
if (aData.Value().IsString()) {
|
|
||||||
nsCString stringData = NS_ConvertUTF16toUTF8(aData.Value().GetAsString());
|
|
||||||
nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
rv = strStream->SetData(stringData.BeginReading(), stringData.Length());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mimeType.AssignLiteral("text/plain;charset=UTF-8");
|
|
||||||
in = strStream;
|
|
||||||
|
|
||||||
} else if (aData.Value().IsArrayBufferView()) {
|
|
||||||
|
|
||||||
nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ArrayBufferView& view = aData.Value().GetAsArrayBufferView();
|
|
||||||
view.ComputeLengthAndData();
|
|
||||||
rv = strStream->SetData(reinterpret_cast<char*>(view.Data()),
|
|
||||||
view.Length());
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mimeType.AssignLiteral("application/octet-stream");
|
|
||||||
in = strStream;
|
|
||||||
|
|
||||||
} else if (aData.Value().IsBlob()) {
|
|
||||||
Blob& blob = aData.Value().GetAsBlob();
|
|
||||||
blob.GetInternalStream(getter_AddRefs(in), aRv);
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString type;
|
|
||||||
blob.GetType(type);
|
|
||||||
mimeType = NS_ConvertUTF16toUTF8(type);
|
|
||||||
|
|
||||||
} else if (aData.Value().IsFormData()) {
|
|
||||||
FormData& form = aData.Value().GetAsFormData();
|
|
||||||
uint64_t len;
|
|
||||||
nsAutoCString charset;
|
nsAutoCString charset;
|
||||||
form.GetSendInfo(getter_AddRefs(in),
|
uint64_t length = 0;
|
||||||
&len,
|
|
||||||
mimeType,
|
if (aBody) {
|
||||||
charset);
|
aRv = aBody->GetAsStream(getter_AddRefs(in), &length,
|
||||||
} else {
|
contentTypeWithCharset, charset);
|
||||||
MOZ_ASSERT(false, "switch statements not in sync");
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -997,7 +991,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uploadChannel->ExplicitSetUploadStream(in, mimeType, -1,
|
uploadChannel->ExplicitSetUploadStream(in, contentTypeWithCharset, length,
|
||||||
NS_LITERAL_CSTRING("POST"),
|
NS_LITERAL_CSTRING("POST"),
|
||||||
false);
|
false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,13 @@ class nsIURI;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
class BodyExtractorBase;
|
||||||
class Geolocation;
|
class Geolocation;
|
||||||
class systemMessageCallback;
|
class systemMessageCallback;
|
||||||
class MediaDevices;
|
class MediaDevices;
|
||||||
struct MediaStreamConstraints;
|
struct MediaStreamConstraints;
|
||||||
class WakeLock;
|
class WakeLock;
|
||||||
class ArrayBufferViewOrBlobOrStringOrFormData;
|
class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams;
|
||||||
class ServiceWorkerContainer;
|
class ServiceWorkerContainer;
|
||||||
class DOMRequest;
|
class DOMRequest;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
@ -196,7 +197,7 @@ public:
|
||||||
#endif // MOZ_AUDIO_CHANNEL_MANAGER
|
#endif // MOZ_AUDIO_CHANNEL_MANAGER
|
||||||
|
|
||||||
bool SendBeacon(const nsAString& aUrl,
|
bool SendBeacon(const nsAString& aUrl,
|
||||||
const Nullable<ArrayBufferViewOrBlobOrStringOrFormData>& aData,
|
const Nullable<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aData,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
void MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
||||||
|
|
@ -255,6 +256,11 @@ private:
|
||||||
bool CheckPermission(const char* type);
|
bool CheckPermission(const char* type);
|
||||||
static bool CheckPermission(nsPIDOMWindowInner* aWindow, const char* aType);
|
static bool CheckPermission(nsPIDOMWindowInner* aWindow, const char* aType);
|
||||||
|
|
||||||
|
bool SendBeaconInternal(const nsAString& aUrl,
|
||||||
|
BodyExtractorBase* aBody,
|
||||||
|
bool aIsBlob,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
RefPtr<nsMimeTypeArray> mMimeTypes;
|
RefPtr<nsMimeTypeArray> mMimeTypes;
|
||||||
RefPtr<nsPluginArray> mPlugins;
|
RefPtr<nsPluginArray> mPlugins;
|
||||||
RefPtr<Permissions> mPermissions;
|
RefPtr<Permissions> mPermissions;
|
||||||
|
|
|
||||||
236
dom/fetch/BodyExtractor.cpp
Normal file
236
dom/fetch/BodyExtractor.cpp
Normal file
|
|
@ -0,0 +1,236 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "BodyExtractor.h"
|
||||||
|
#include "mozilla/dom/EncodingUtils.h"
|
||||||
|
#include "mozilla/dom/File.h"
|
||||||
|
#include "mozilla/dom/FormData.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
#include "mozilla/dom/URLSearchParams.h"
|
||||||
|
#include "mozilla/dom/XMLHttpRequest.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsIDOMDocument.h"
|
||||||
|
#include "nsIDOMSerializer.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
|
#include "nsIOutputStream.h"
|
||||||
|
#include "nsIStorageStream.h"
|
||||||
|
#include "nsStringStream.h"
|
||||||
|
#include "nsIUnicodeEncoder.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
GetBufferDataAsStream(const uint8_t* aData, uint32_t aDataLength,
|
||||||
|
nsIInputStream** aResult, uint64_t* aContentLength,
|
||||||
|
nsACString& aContentType, nsACString& aCharset)
|
||||||
|
{
|
||||||
|
aContentType.SetIsVoid(true);
|
||||||
|
aCharset.Truncate();
|
||||||
|
|
||||||
|
*aContentLength = aDataLength;
|
||||||
|
const char* data = reinterpret_cast<const char*>(aData);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
|
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, aDataLength,
|
||||||
|
NS_ASSIGNMENT_COPY);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
stream.forget(aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<const ArrayBuffer>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
mBody->ComputeLengthAndData();
|
||||||
|
return GetBufferDataAsStream(mBody->Data(), mBody->Length(),
|
||||||
|
aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<const ArrayBufferView>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
mBody->ComputeLengthAndData();
|
||||||
|
return GetBufferDataAsStream(mBody->Data(), mBody->Length(),
|
||||||
|
aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<nsIDocument>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(mBody));
|
||||||
|
NS_ENSURE_STATE(domdoc);
|
||||||
|
aCharset.AssignLiteral("UTF-8");
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIStorageStream> storStream;
|
||||||
|
rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(storStream));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIOutputStream> output;
|
||||||
|
rv = storStream->GetOutputStream(0, getter_AddRefs(output));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (mBody->IsHTMLDocument()) {
|
||||||
|
aContentTypeWithCharset.AssignLiteral("text/html;charset=UTF-8");
|
||||||
|
|
||||||
|
nsString serialized;
|
||||||
|
if (!nsContentUtils::SerializeNodeToMarkup(mBody, true, serialized)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString utf8Serialized;
|
||||||
|
if (!AppendUTF16toUTF8(serialized, utf8Serialized, fallible)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t written;
|
||||||
|
rv = output->Write(utf8Serialized.get(), utf8Serialized.Length(), &written);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
MOZ_ASSERT(written == utf8Serialized.Length());
|
||||||
|
} else {
|
||||||
|
aContentTypeWithCharset.AssignLiteral("application/xml;charset=UTF-8");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSerializer> serializer =
|
||||||
|
do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Make sure to use the encoding we'll send
|
||||||
|
rv = serializer->SerializeToStream(domdoc, output, aCharset);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
output->Close();
|
||||||
|
|
||||||
|
uint32_t length;
|
||||||
|
rv = storStream->GetLength(&length);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
*aContentLength = length;
|
||||||
|
|
||||||
|
rv = storStream->NewInputStream(0, aResult);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<const nsAString>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIUnicodeEncoder> encoder =
|
||||||
|
EncodingUtils::EncoderForEncoding("UTF-8");
|
||||||
|
if (!encoder) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t destBufferLen;
|
||||||
|
nsresult rv = encoder->GetMaxLength(mBody->BeginReading(), mBody->Length(),
|
||||||
|
&destBufferLen);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCString encoded;
|
||||||
|
if (!encoded.SetCapacity(destBufferLen, fallible)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* destBuffer = encoded.BeginWriting();
|
||||||
|
int32_t srcLen = (int32_t) mBody->Length();
|
||||||
|
int32_t outLen = destBufferLen;
|
||||||
|
rv = encoder->Convert(mBody->BeginReading(), &srcLen, destBuffer, &outLen);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(outLen <= destBufferLen);
|
||||||
|
encoded.SetLength(outLen);
|
||||||
|
|
||||||
|
rv = NS_NewCStringInputStream(aResult, encoded);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aContentLength = outLen;
|
||||||
|
aContentTypeWithCharset.AssignLiteral("text/plain;charset=UTF-8");
|
||||||
|
aCharset.AssignLiteral("UTF-8");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<nsIInputStream>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
aContentTypeWithCharset.AssignLiteral("text/plain");
|
||||||
|
aCharset.Truncate();
|
||||||
|
|
||||||
|
nsresult rv = mBody->Available(aContentLength);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stream(mBody);
|
||||||
|
stream.forget(aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<Blob>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<FormData>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<URLSearchParams>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> nsresult
|
||||||
|
BodyExtractor<nsIXHRSendable>::GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const
|
||||||
|
{
|
||||||
|
return mBody->GetSendInfo(aResult, aContentLength, aContentTypeWithCharset,
|
||||||
|
aCharset);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
46
dom/fetch/BodyExtractor.h
Normal file
46
dom/fetch/BodyExtractor.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_BodyExtractor_h
|
||||||
|
#define mozilla_dom_BodyExtractor_h
|
||||||
|
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
class nsIInputStream;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class BodyExtractorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual nsresult GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The implementation versions of this template are:
|
||||||
|
// ArrayBuffer, ArrayBufferView, Blob, FormData, nsAString, nsIDocument,
|
||||||
|
// nsIInputStream, nsIXHRSendable, URLSearchParams
|
||||||
|
template<typename Type>
|
||||||
|
class BodyExtractor final : public BodyExtractorBase
|
||||||
|
{
|
||||||
|
Type* mBody;
|
||||||
|
public:
|
||||||
|
explicit BodyExtractor(Type* aBody) : mBody(aBody)
|
||||||
|
{}
|
||||||
|
|
||||||
|
nsresult GetAsStream(nsIInputStream** aResult,
|
||||||
|
uint64_t* aContentLength,
|
||||||
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_dom_BodyExtractor_h
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
#include "nsIStreamLoader.h"
|
#include "nsIStreamLoader.h"
|
||||||
#include "nsIThreadRetargetableRequest.h"
|
#include "nsIThreadRetargetableRequest.h"
|
||||||
#include "nsIUnicodeDecoder.h"
|
#include "nsIUnicodeDecoder.h"
|
||||||
#include "nsIUnicodeEncoder.h"
|
|
||||||
|
|
||||||
#include "nsDOMString.h"
|
#include "nsDOMString.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
@ -24,7 +23,6 @@
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/BodyUtil.h"
|
#include "mozilla/dom/BodyUtil.h"
|
||||||
#include "mozilla/dom/DOMError.h"
|
#include "mozilla/dom/DOMError.h"
|
||||||
#include "mozilla/dom/EncodingUtils.h"
|
|
||||||
#include "mozilla/dom/Exceptions.h"
|
#include "mozilla/dom/Exceptions.h"
|
||||||
#include "mozilla/dom/FetchDriver.h"
|
#include "mozilla/dom/FetchDriver.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
|
|
@ -40,6 +38,7 @@
|
||||||
#include "mozilla/dom/WorkerPrivate.h"
|
#include "mozilla/dom/WorkerPrivate.h"
|
||||||
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
||||||
|
|
||||||
|
#include "BodyExtractor.h"
|
||||||
#include "FetchObserver.h"
|
#include "FetchObserver.h"
|
||||||
#include "InternalRequest.h"
|
#include "InternalRequest.h"
|
||||||
#include "InternalResponse.h"
|
#include "InternalResponse.h"
|
||||||
|
|
@ -725,154 +724,48 @@ WorkerFetchResolver::FlushConsoleReport()
|
||||||
mReporter->FlushConsoleReports(worker->GetDocument());
|
mReporter->FlushConsoleReports(worker->GetDocument());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromArrayBuffer(const ArrayBuffer& aBuffer,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
aBuffer.ComputeLengthAndData();
|
|
||||||
aContentLength = aBuffer.Length();
|
|
||||||
//XXXnsm reinterpret_cast<> is used in DOMParser, should be ok.
|
|
||||||
return NS_NewByteInputStream(aStream,
|
|
||||||
reinterpret_cast<char*>(aBuffer.Data()),
|
|
||||||
aBuffer.Length(), NS_ASSIGNMENT_COPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromArrayBufferView(const ArrayBufferView& aBuffer,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
aBuffer.ComputeLengthAndData();
|
|
||||||
aContentLength = aBuffer.Length();
|
|
||||||
//XXXnsm reinterpret_cast<> is used in DOMParser, should be ok.
|
|
||||||
return NS_NewByteInputStream(aStream,
|
|
||||||
reinterpret_cast<char*>(aBuffer.Data()),
|
|
||||||
aBuffer.Length(), NS_ASSIGNMENT_COPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromBlob(const Blob& aBlob,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
nsCString& aContentType,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
RefPtr<BlobImpl> impl = aBlob.Impl();
|
|
||||||
ErrorResult rv;
|
|
||||||
aContentLength = impl->GetSize(rv);
|
|
||||||
if (NS_WARN_IF(rv.Failed())) {
|
|
||||||
return rv.StealNSResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl->GetInternalStream(aStream, rv);
|
|
||||||
if (NS_WARN_IF(rv.Failed())) {
|
|
||||||
return rv.StealNSResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString type;
|
|
||||||
impl->GetType(type);
|
|
||||||
aContentType = NS_ConvertUTF16toUTF8(type);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromFormData(FormData& aFormData,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
nsCString& aContentType,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
nsAutoCString unusedCharset;
|
|
||||||
return aFormData.GetSendInfo(aStream, &aContentLength,
|
|
||||||
aContentType, unusedCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromUSVString(const nsString& aStr,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
nsCString& aContentType,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIUnicodeEncoder> encoder = EncodingUtils::EncoderForEncoding("UTF-8");
|
|
||||||
if (!encoder) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t destBufferLen;
|
|
||||||
nsresult rv = encoder->GetMaxLength(aStr.get(), aStr.Length(), &destBufferLen);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCString encoded;
|
|
||||||
if (!encoded.SetCapacity(destBufferLen, fallible)) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* destBuffer = encoded.BeginWriting();
|
|
||||||
int32_t srcLen = (int32_t) aStr.Length();
|
|
||||||
int32_t outLen = destBufferLen;
|
|
||||||
rv = encoder->Convert(aStr.get(), &srcLen, destBuffer, &outLen);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(outLen <= destBufferLen);
|
|
||||||
encoded.SetLength(outLen);
|
|
||||||
|
|
||||||
aContentType = NS_LITERAL_CSTRING("text/plain;charset=UTF-8");
|
|
||||||
aContentLength = outLen;
|
|
||||||
|
|
||||||
return NS_NewCStringInputStream(aStream, encoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
ExtractFromURLSearchParams(const URLSearchParams& aParams,
|
|
||||||
nsIInputStream** aStream,
|
|
||||||
nsCString& aContentType,
|
|
||||||
uint64_t& aContentLength)
|
|
||||||
{
|
|
||||||
nsAutoString serialized;
|
|
||||||
aParams.Stringify(serialized);
|
|
||||||
aContentType = NS_LITERAL_CSTRING("application/x-www-form-urlencoded;charset=UTF-8");
|
|
||||||
aContentLength = serialized.Length();
|
|
||||||
return NS_NewCStringInputStream(aStream, NS_ConvertUTF16toUTF8(serialized));
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType,
|
nsCString& aContentTypeWithCharset,
|
||||||
uint64_t& aContentLength)
|
uint64_t& aContentLength)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aStream);
|
MOZ_ASSERT(aStream);
|
||||||
|
nsAutoCString charset;
|
||||||
|
aContentTypeWithCharset.SetIsVoid(true);
|
||||||
|
|
||||||
if (aBodyInit.IsArrayBuffer()) {
|
if (aBodyInit.IsArrayBuffer()) {
|
||||||
const ArrayBuffer& buf = aBodyInit.GetAsArrayBuffer();
|
BodyExtractor<const ArrayBuffer> body(&aBodyInit.GetAsArrayBuffer());
|
||||||
return ExtractFromArrayBuffer(buf, aStream, aContentLength);
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsArrayBufferView()) {
|
if (aBodyInit.IsArrayBufferView()) {
|
||||||
const ArrayBufferView& buf = aBodyInit.GetAsArrayBufferView();
|
BodyExtractor<const ArrayBufferView> body(&aBodyInit.GetAsArrayBufferView());
|
||||||
return ExtractFromArrayBufferView(buf, aStream, aContentLength);
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsBlob()) {
|
if (aBodyInit.IsBlob()) {
|
||||||
const Blob& blob = aBodyInit.GetAsBlob();
|
Blob& blob = aBodyInit.GetAsBlob();
|
||||||
return ExtractFromBlob(blob, aStream, aContentType, aContentLength);
|
BodyExtractor<Blob> body(&blob);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsFormData()) {
|
if (aBodyInit.IsFormData()) {
|
||||||
FormData& form = aBodyInit.GetAsFormData();
|
FormData& formData = aBodyInit.GetAsFormData();
|
||||||
return ExtractFromFormData(form, aStream, aContentType, aContentLength);
|
BodyExtractor<FormData> body(&formData);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsUSVString()) {
|
if (aBodyInit.IsUSVString()) {
|
||||||
nsAutoString str;
|
BodyExtractor<const nsAString> body(&aBodyInit.GetAsUSVString());
|
||||||
str.Assign(aBodyInit.GetAsUSVString());
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
return ExtractFromUSVString(str, aStream, aContentType, aContentLength);
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsURLSearchParams()) {
|
if (aBodyInit.IsURLSearchParams()) {
|
||||||
URLSearchParams& params = aBodyInit.GetAsURLSearchParams();
|
URLSearchParams& usp = aBodyInit.GetAsURLSearchParams();
|
||||||
return ExtractFromURLSearchParams(params, aStream, aContentType, aContentLength);
|
BodyExtractor<URLSearchParams> body(&usp);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_NOTREACHED("Should never reach here");
|
NS_NOTREACHED("Should never reach here");
|
||||||
|
|
@ -882,36 +775,47 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDa
|
||||||
nsresult
|
nsresult
|
||||||
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit,
|
||||||
nsIInputStream** aStream,
|
nsIInputStream** aStream,
|
||||||
nsCString& aContentType,
|
nsCString& aContentTypeWithCharset,
|
||||||
uint64_t& aContentLength)
|
uint64_t& aContentLength)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aStream);
|
MOZ_ASSERT(aStream);
|
||||||
MOZ_ASSERT(!*aStream);
|
MOZ_ASSERT(!*aStream);
|
||||||
|
|
||||||
|
nsAutoCString charset;
|
||||||
|
aContentTypeWithCharset.SetIsVoid(true);
|
||||||
|
|
||||||
if (aBodyInit.IsArrayBuffer()) {
|
if (aBodyInit.IsArrayBuffer()) {
|
||||||
const ArrayBuffer& buf = aBodyInit.GetAsArrayBuffer();
|
BodyExtractor<const ArrayBuffer> body(&aBodyInit.GetAsArrayBuffer());
|
||||||
return ExtractFromArrayBuffer(buf, aStream, aContentLength);
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsArrayBufferView()) {
|
if (aBodyInit.IsArrayBufferView()) {
|
||||||
const ArrayBufferView& buf = aBodyInit.GetAsArrayBufferView();
|
BodyExtractor<const ArrayBufferView> body(&aBodyInit.GetAsArrayBufferView());
|
||||||
return ExtractFromArrayBufferView(buf, aStream, aContentLength);
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsBlob()) {
|
if (aBodyInit.IsBlob()) {
|
||||||
const Blob& blob = aBodyInit.GetAsBlob();
|
Blob& blob = aBodyInit.GetAsBlob();
|
||||||
return ExtractFromBlob(blob, aStream, aContentType, aContentLength);
|
BodyExtractor<Blob> body(&blob);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsFormData()) {
|
if (aBodyInit.IsFormData()) {
|
||||||
FormData& form = aBodyInit.GetAsFormData();
|
FormData& formData = aBodyInit.GetAsFormData();
|
||||||
return ExtractFromFormData(form, aStream, aContentType, aContentLength);
|
BodyExtractor<FormData> body(&formData);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsUSVString()) {
|
if (aBodyInit.IsUSVString()) {
|
||||||
nsAutoString str;
|
BodyExtractor<const nsAString> body(&aBodyInit.GetAsUSVString());
|
||||||
str.Assign(aBodyInit.GetAsUSVString());
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
return ExtractFromUSVString(str, aStream, aContentType, aContentLength);
|
charset);
|
||||||
}
|
}
|
||||||
if (aBodyInit.IsURLSearchParams()) {
|
if (aBodyInit.IsURLSearchParams()) {
|
||||||
URLSearchParams& params = aBodyInit.GetAsURLSearchParams();
|
URLSearchParams& usp = aBodyInit.GetAsURLSearchParams();
|
||||||
return ExtractFromURLSearchParams(params, aStream, aContentType, aContentLength);
|
BodyExtractor<URLSearchParams> body(&usp);
|
||||||
|
return body.GetAsStream(aStream, &aContentLength, aContentTypeWithCharset,
|
||||||
|
charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_NOTREACHED("Should never reach here");
|
NS_NOTREACHED("Should never reach here");
|
||||||
|
|
|
||||||
|
|
@ -580,11 +580,11 @@ Request::Constructor(const GlobalObject& aGlobal,
|
||||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit =
|
const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit =
|
||||||
bodyInitNullable.Value();
|
bodyInitNullable.Value();
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
nsAutoCString contentType;
|
nsAutoCString contentTypeWithCharset;
|
||||||
uint64_t contentLengthUnused;
|
uint64_t contentLengthUnused;
|
||||||
aRv = ExtractByteStreamFromBody(bodyInit,
|
aRv = ExtractByteStreamFromBody(bodyInit,
|
||||||
getter_AddRefs(stream),
|
getter_AddRefs(stream),
|
||||||
contentType,
|
contentTypeWithCharset,
|
||||||
contentLengthUnused);
|
contentLengthUnused);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -592,10 +592,10 @@ Request::Constructor(const GlobalObject& aGlobal,
|
||||||
|
|
||||||
temporaryBody = stream;
|
temporaryBody = stream;
|
||||||
|
|
||||||
if (!contentType.IsVoid() &&
|
if (!contentTypeWithCharset.IsVoid() &&
|
||||||
!requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
!requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
||||||
requestHeaders->Append(NS_LITERAL_CSTRING("Content-Type"),
|
requestHeaders->Append(NS_LITERAL_CSTRING("Content-Type"),
|
||||||
contentType, aRv);
|
contentTypeWithCharset, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
|
|
||||||
|
|
@ -224,22 +224,23 @@ Response::Constructor(const GlobalObject& aGlobal,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> bodyStream;
|
nsCOMPtr<nsIInputStream> bodyStream;
|
||||||
nsCString contentType;
|
nsCString contentTypeWithCharset;
|
||||||
uint64_t bodySize = 0;
|
uint64_t bodySize = 0;
|
||||||
aRv = ExtractByteStreamFromBody(aBody.Value().Value(),
|
aRv = ExtractByteStreamFromBody(aBody.Value().Value(),
|
||||||
getter_AddRefs(bodyStream),
|
getter_AddRefs(bodyStream),
|
||||||
contentType,
|
contentTypeWithCharset,
|
||||||
bodySize);
|
bodySize);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
internalResponse->SetBody(bodyStream, bodySize);
|
internalResponse->SetBody(bodyStream, bodySize);
|
||||||
|
|
||||||
if (!contentType.IsVoid() &&
|
if (!contentTypeWithCharset.IsVoid() &&
|
||||||
!internalResponse->Headers()->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
!internalResponse->Headers()->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
|
||||||
// Ignore Append() failing here.
|
// Ignore Append() failing here.
|
||||||
ErrorResult error;
|
ErrorResult error;
|
||||||
internalResponse->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, error);
|
internalResponse->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"),
|
||||||
|
contentTypeWithCharset, error);
|
||||||
error.SuppressException();
|
error.SuppressException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
|
'BodyExtractor.h',
|
||||||
'ChannelInfo.h',
|
'ChannelInfo.h',
|
||||||
'Fetch.h',
|
'Fetch.h',
|
||||||
'FetchDriver.h',
|
'FetchDriver.h',
|
||||||
|
|
@ -19,6 +20,7 @@ EXPORTS.mozilla.dom += [
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
'BodyExtractor.cpp',
|
||||||
'ChannelInfo.cpp',
|
'ChannelInfo.cpp',
|
||||||
'Fetch.cpp',
|
'Fetch.cpp',
|
||||||
'FetchConsumer.cpp',
|
'FetchConsumer.cpp',
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,8 @@ function handleRequest(request, response) {
|
||||||
data += charcode;
|
data += charcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mimetype = request.getHeader("Content-Type");
|
var mimetype = request.hasHeader("Content-Type")
|
||||||
|
? request.getHeader("Content-Type") : "application/octet-stream";
|
||||||
|
|
||||||
// check to see if this is form data.
|
// check to see if this is form data.
|
||||||
if (mimetype.indexOf("multipart/form-data") != -1) {
|
if (mimetype.indexOf("multipart/form-data") != -1) {
|
||||||
|
|
|
||||||
|
|
@ -575,9 +575,10 @@ URLSearchParams::ReadStructuredClone(JSStructuredCloneReader* aReader)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
URLSearchParams::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
URLSearchParams::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||||
nsACString& aContentType, nsACString& aCharset)
|
nsACString& aContentTypeWithCharset,
|
||||||
|
nsACString& aCharset)
|
||||||
{
|
{
|
||||||
aContentType.AssignLiteral("application/x-www-form-urlencoded");
|
aContentTypeWithCharset.AssignLiteral("application/x-www-form-urlencoded;charset=UTF-8");
|
||||||
aCharset.AssignLiteral("UTF-8");
|
aCharset.AssignLiteral("UTF-8");
|
||||||
|
|
||||||
nsAutoString serialized;
|
nsAutoString serialized;
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@ partial interface Navigator {
|
||||||
partial interface Navigator {
|
partial interface Navigator {
|
||||||
[Throws, Pref="beacon.enabled"]
|
[Throws, Pref="beacon.enabled"]
|
||||||
boolean sendBeacon(DOMString url,
|
boolean sendBeacon(DOMString url,
|
||||||
optional (ArrayBufferView or Blob or DOMString or FormData)? data = null);
|
optional BodyInit? data = null);
|
||||||
};
|
};
|
||||||
|
|
||||||
partial interface Navigator {
|
partial interface Navigator {
|
||||||
|
|
|
||||||
|
|
@ -2298,175 +2298,6 @@ XMLHttpRequestMainThread::ChangeStateToDone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<nsIDocument>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(mBody));
|
|
||||||
NS_ENSURE_STATE(domdoc);
|
|
||||||
aCharset.AssignLiteral("UTF-8");
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIStorageStream> storStream;
|
|
||||||
rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(storStream));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIOutputStream> output;
|
|
||||||
rv = storStream->GetOutputStream(0, getter_AddRefs(output));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (mBody->IsHTMLDocument()) {
|
|
||||||
aContentType.AssignLiteral("text/html");
|
|
||||||
|
|
||||||
nsString serialized;
|
|
||||||
if (!nsContentUtils::SerializeNodeToMarkup(mBody, true, serialized)) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString utf8Serialized;
|
|
||||||
if (!AppendUTF16toUTF8(serialized, utf8Serialized, fallible)) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t written;
|
|
||||||
rv = output->Write(utf8Serialized.get(), utf8Serialized.Length(), &written);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
MOZ_ASSERT(written == utf8Serialized.Length());
|
|
||||||
} else {
|
|
||||||
aContentType.AssignLiteral("application/xml");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSerializer> serializer =
|
|
||||||
do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Make sure to use the encoding we'll send
|
|
||||||
rv = serializer->SerializeToStream(domdoc, output, aCharset);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
output->Close();
|
|
||||||
|
|
||||||
uint32_t length;
|
|
||||||
rv = storStream->GetLength(&length);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
*aContentLength = length;
|
|
||||||
|
|
||||||
rv = storStream->NewInputStream(0, aResult);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<const nsAString>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
aContentType.AssignLiteral("text/plain");
|
|
||||||
aCharset.AssignLiteral("UTF-8");
|
|
||||||
|
|
||||||
nsAutoCString converted;
|
|
||||||
if (!AppendUTF16toUTF8(*mBody, converted, fallible)) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aContentLength = converted.Length();
|
|
||||||
nsresult rv = NS_NewCStringInputStream(aResult, converted);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<nsIInputStream>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
aContentType.AssignLiteral("text/plain");
|
|
||||||
aCharset.Truncate();
|
|
||||||
|
|
||||||
nsresult rv = mBody->Available(aContentLength);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> stream(mBody);
|
|
||||||
stream.forget(aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<Blob>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
return mBody->GetSendInfo(aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<FormData>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
return mBody->GetSendInfo(aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<URLSearchParams>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
return mBody->GetSendInfo(aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<nsIXHRSendable>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
return mBody->GetSendInfo(aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
GetBufferDataAsStream(const uint8_t* aData, uint32_t aDataLength,
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset)
|
|
||||||
{
|
|
||||||
aContentType.SetIsVoid(true);
|
|
||||||
aCharset.Truncate();
|
|
||||||
|
|
||||||
*aContentLength = aDataLength;
|
|
||||||
const char* data = reinterpret_cast<const char*>(aData);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
|
||||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, aDataLength,
|
|
||||||
NS_ASSIGNMENT_COPY);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
stream.forget(aResult);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<const ArrayBuffer>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
mBody->ComputeLengthAndData();
|
|
||||||
return GetBufferDataAsStream(mBody->Data(), mBody->Length(),
|
|
||||||
aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> nsresult
|
|
||||||
XMLHttpRequestMainThread::RequestBody<const ArrayBufferView>::GetAsStream(
|
|
||||||
nsIInputStream** aResult, uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType, nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
mBody->ComputeLengthAndData();
|
|
||||||
return GetBufferDataAsStream(mBody->Data(), mBody->Length(),
|
|
||||||
aResult, aContentLength, aContentType, aCharset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
XMLHttpRequestMainThread::CreateChannel()
|
XMLHttpRequestMainThread::CreateChannel()
|
||||||
{
|
{
|
||||||
|
|
@ -2793,7 +2624,7 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant)
|
||||||
// document?
|
// document?
|
||||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(supports);
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(supports);
|
||||||
if (doc) {
|
if (doc) {
|
||||||
RequestBody<nsIDocument> body(doc);
|
BodyExtractor<nsIDocument> body(doc);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2802,21 +2633,21 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant)
|
||||||
if (wstr) {
|
if (wstr) {
|
||||||
nsAutoString string;
|
nsAutoString string;
|
||||||
wstr->GetData(string);
|
wstr->GetData(string);
|
||||||
RequestBody<const nsAString> body(&string);
|
BodyExtractor<const nsAString> body(&string);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIInputStream?
|
// nsIInputStream?
|
||||||
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(supports);
|
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(supports);
|
||||||
if (stream) {
|
if (stream) {
|
||||||
RequestBody<nsIInputStream> body(stream);
|
BodyExtractor<nsIInputStream> body(stream);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIXHRSendable?
|
// nsIXHRSendable?
|
||||||
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
|
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
|
||||||
if (sendable) {
|
if (sendable) {
|
||||||
RequestBody<nsIXHRSendable> body(sendable);
|
BodyExtractor<nsIXHRSendable> body(sendable);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2829,7 +2660,7 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant)
|
||||||
JS::Rooted<JSObject*> obj(rootingCx, realVal.toObjectOrNull());
|
JS::Rooted<JSObject*> obj(rootingCx, realVal.toObjectOrNull());
|
||||||
RootedSpiderMonkeyInterface<ArrayBuffer> buf(rootingCx);
|
RootedSpiderMonkeyInterface<ArrayBuffer> buf(rootingCx);
|
||||||
if (buf.Init(obj)) {
|
if (buf.Init(obj)) {
|
||||||
RequestBody<const ArrayBuffer> body(&buf);
|
BodyExtractor<const ArrayBuffer> body(&buf);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2846,12 +2677,12 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant)
|
||||||
nsString string;
|
nsString string;
|
||||||
string.Adopt(data, len);
|
string.Adopt(data, len);
|
||||||
|
|
||||||
RequestBody<const nsAString> body(&string);
|
BodyExtractor<const nsAString> body(&string);
|
||||||
return SendInternal(&body);
|
return SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
|
XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
|
|
@ -2917,13 +2748,6 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
|
||||||
mAuthorRequestHeaders.Get("content-type", uploadContentType);
|
mAuthorRequestHeaders.Get("content-type", uploadContentType);
|
||||||
if (uploadContentType.IsVoid()) {
|
if (uploadContentType.IsVoid()) {
|
||||||
uploadContentType = defaultContentType;
|
uploadContentType = defaultContentType;
|
||||||
|
|
||||||
if (!charset.IsEmpty()) {
|
|
||||||
// If we are providing the default content type, then we also need to
|
|
||||||
// provide a charset declaration.
|
|
||||||
uploadContentType.Append(NS_LITERAL_CSTRING(";charset="));
|
|
||||||
uploadContentType.Append(charset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to set a charset for streams.
|
// We don't want to set a charset for streams.
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
#include "mozilla/dom/MutableBlobStorage.h"
|
#include "mozilla/dom/MutableBlobStorage.h"
|
||||||
|
#include "mozilla/dom/BodyExtractor.h"
|
||||||
#include "mozilla/dom/TypedArray.h"
|
#include "mozilla/dom/TypedArray.h"
|
||||||
#include "mozilla/dom/XMLHttpRequest.h"
|
#include "mozilla/dom/XMLHttpRequest.h"
|
||||||
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
||||||
|
|
@ -288,34 +289,7 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual ~XMLHttpRequestMainThread();
|
virtual ~XMLHttpRequestMainThread();
|
||||||
|
|
||||||
class RequestBodyBase
|
nsresult SendInternal(const BodyExtractorBase* aBody);
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual nsresult GetAsStream(nsIInputStream** aResult,
|
|
||||||
uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType,
|
|
||||||
nsACString& aCharset) const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(false, "RequestBodyBase should not be used directly.");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
class RequestBody final : public RequestBodyBase
|
|
||||||
{
|
|
||||||
Type* mBody;
|
|
||||||
public:
|
|
||||||
explicit RequestBody(Type* aBody) : mBody(aBody)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
nsresult GetAsStream(nsIInputStream** aResult,
|
|
||||||
uint64_t* aContentLength,
|
|
||||||
nsACString& aContentType,
|
|
||||||
nsACString& aCharset) const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult SendInternal(const RequestBodyBase* aBody);
|
|
||||||
|
|
||||||
bool IsCrossSiteCORSRequest() const;
|
bool IsCrossSiteCORSRequest() const;
|
||||||
bool IsDeniedCrossSiteCORSRequest();
|
bool IsDeniedCrossSiteCORSRequest();
|
||||||
|
|
@ -336,7 +310,7 @@ public:
|
||||||
Send(JSContext* /*aCx*/, const ArrayBuffer& aArrayBuffer,
|
Send(JSContext* /*aCx*/, const ArrayBuffer& aArrayBuffer,
|
||||||
ErrorResult& aRv) override
|
ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<const ArrayBuffer> body(&aArrayBuffer);
|
BodyExtractor<const ArrayBuffer> body(&aArrayBuffer);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,28 +318,28 @@ public:
|
||||||
Send(JSContext* /*aCx*/, const ArrayBufferView& aArrayBufferView,
|
Send(JSContext* /*aCx*/, const ArrayBufferView& aArrayBufferView,
|
||||||
ErrorResult& aRv) override
|
ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<const ArrayBufferView> body(&aArrayBufferView);
|
BodyExtractor<const ArrayBufferView> body(&aArrayBufferView);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
Send(JSContext* /*aCx*/, Blob& aBlob, ErrorResult& aRv) override
|
Send(JSContext* /*aCx*/, Blob& aBlob, ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<Blob> body(&aBlob);
|
BodyExtractor<Blob> body(&aBlob);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Send(JSContext* /*aCx*/, URLSearchParams& aURLSearchParams,
|
virtual void Send(JSContext* /*aCx*/, URLSearchParams& aURLSearchParams,
|
||||||
ErrorResult& aRv) override
|
ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<URLSearchParams> body(&aURLSearchParams);
|
BodyExtractor<URLSearchParams> body(&aURLSearchParams);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
Send(JSContext* /*aCx*/, nsIDocument& aDoc, ErrorResult& aRv) override
|
Send(JSContext* /*aCx*/, nsIDocument& aDoc, ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<nsIDocument> body(&aDoc);
|
BodyExtractor<nsIDocument> body(&aDoc);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +349,7 @@ public:
|
||||||
if (DOMStringIsNull(aString)) {
|
if (DOMStringIsNull(aString)) {
|
||||||
Send(aCx, aRv);
|
Send(aCx, aRv);
|
||||||
} else {
|
} else {
|
||||||
RequestBody<const nsAString> body(&aString);
|
BodyExtractor<const nsAString> body(&aString);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +357,7 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
Send(JSContext* /*aCx*/, FormData& aFormData, ErrorResult& aRv) override
|
Send(JSContext* /*aCx*/, FormData& aFormData, ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
RequestBody<FormData> body(&aFormData);
|
BodyExtractor<FormData> body(&aFormData);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,7 +365,7 @@ public:
|
||||||
Send(JSContext* aCx, nsIInputStream* aStream, ErrorResult& aRv) override
|
Send(JSContext* aCx, nsIInputStream* aStream, ErrorResult& aRv) override
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aStream, "Null should go to string version");
|
NS_ASSERTION(aStream, "Null should go to string version");
|
||||||
RequestBody<nsIInputStream> body(aStream);
|
BodyExtractor<nsIInputStream> body(aStream);
|
||||||
aRv = SendInternal(&body);
|
aRv = SendInternal(&body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -326,9 +326,12 @@ interface nsIXMLHttpRequest : nsISupports
|
||||||
|
|
||||||
[uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
[uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
||||||
interface nsIXHRSendable : nsISupports {
|
interface nsIXHRSendable : nsISupports {
|
||||||
|
// contentTypeWithCharset can be set to the contentType or
|
||||||
|
// contentType+charset based on what the spec says.
|
||||||
|
// See: https://fetch.spec.whatwg.org/#concept-bodyinit-extract
|
||||||
void getSendInfo(out nsIInputStream body,
|
void getSendInfo(out nsIInputStream body,
|
||||||
out uint64_t contentLength,
|
out uint64_t contentLength,
|
||||||
out ACString contentType,
|
out ACString contentTypeWithCharset,
|
||||||
out ACString charset);
|
out ACString charset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue