Backed out changeset 6e6d55b02d19 (bug 1285036)

This commit is contained in:
Sebastian Hengst
2016-07-28 18:13:13 +02:00
parent 191ee0d512
commit a2c9cc9a48
2 changed files with 350 additions and 230 deletions

View File

@@ -2106,167 +2106,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;
}
NS_ConvertUTF16toUTF8 utf8Serialized(serialized);
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");
nsCString converted = NS_ConvertUTF16toUTF8(*mBody);
*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::InitChannel() XMLHttpRequestMainThread::InitChannel()
{ {
@@ -2342,31 +2181,154 @@ XMLHttpRequestMainThread::InitChannel()
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP static nsresult
XMLHttpRequestMainThread::Send(nsIVariant* aVariant) GetRequestBodyInternal(nsIDOMDocument* aDoc, nsIInputStream** aResult,
uint64_t* aContentLength, nsACString& aContentType,
nsACString& aCharset)
{ {
if (!aVariant) { nsCOMPtr<nsIDocument> doc(do_QueryInterface(aDoc));
return SendInternal(nullptr); NS_ENSURE_STATE(doc);
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 (doc->IsHTMLDocument()) {
aContentType.AssignLiteral("text/html");
nsString serialized;
if (!nsContentUtils::SerializeNodeToMarkup(doc, true, serialized)) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ConvertUTF16toUTF8 utf8Serialized(serialized);
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(aDoc, output, aCharset);
NS_ENSURE_SUCCESS(rv, rv);
} }
output->Close();
uint32_t length;
rv = storStream->GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
*aContentLength = length;
return storStream->NewInputStream(0, aResult);
}
static nsresult
GetRequestBodyInternal(const nsAString& aString, nsIInputStream** aResult,
uint64_t* aContentLength, nsACString& aContentType,
nsACString& aCharset)
{
aContentType.AssignLiteral("text/plain");
aCharset.AssignLiteral("UTF-8");
nsCString converted = NS_ConvertUTF16toUTF8(aString);
*aContentLength = converted.Length();
return NS_NewCStringInputStream(aResult, converted);
}
static nsresult
GetRequestBodyInternal(nsIInputStream* aStream, nsIInputStream** aResult,
uint64_t* aContentLength, nsACString& aContentType,
nsACString& aCharset)
{
aContentType.AssignLiteral("text/plain");
aCharset.Truncate();
nsresult rv = aStream->Available(aContentLength);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = aStream);
return NS_OK;
}
static nsresult
GetRequestBodyInternal(URLSearchParams* aURLSearchParams,
nsIInputStream** aResult, uint64_t* aContentLength,
nsACString& aContentType, nsACString& aCharset)
{
return aURLSearchParams->GetSendInfo(aResult, aContentLength,
aContentType, aCharset);
}
static nsresult
GetRequestBodyInternal(nsIXHRSendable* aSendable, nsIInputStream** aResult,
uint64_t* aContentLength, nsACString& aContentType,
nsACString& aCharset)
{
return aSendable->GetSendInfo(aResult, aContentLength, aContentType, aCharset);
}
// Used for array buffers and array buffer views
static nsresult
GetRequestBodyInternal(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;
}
static nsresult
GetRequestBodyInternal(nsIVariant* aBody, nsIInputStream** aResult,
uint64_t* aContentLength, nsACString& aContentType,
nsACString& aCharset)
{
*aResult = nullptr;
uint16_t dataType; uint16_t dataType;
nsresult rv = aVariant->GetDataType(&dataType); nsresult rv = aBody->GetDataType(&dataType);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (dataType == nsIDataType::VTYPE_INTERFACE || if (dataType == nsIDataType::VTYPE_INTERFACE ||
dataType == nsIDataType::VTYPE_INTERFACE_IS) { dataType == nsIDataType::VTYPE_INTERFACE_IS) {
nsCOMPtr<nsISupports> supports; nsCOMPtr<nsISupports> supports;
nsID *iid; nsID *iid;
rv = aVariant->GetAsInterface(&iid, getter_AddRefs(supports)); rv = aBody->GetAsInterface(&iid, getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
free(iid); free(iid);
// document? // document?
nsCOMPtr<nsIDocument> doc = do_QueryInterface(supports); nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(supports);
if (doc) { if (doc) {
RequestBody<nsIDocument> body(doc); return GetRequestBodyInternal(doc, aResult, aContentLength, aContentType,
return SendInternal(&body); aCharset);
} }
// nsISupportsString? // nsISupportsString?
@@ -2374,56 +2336,153 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant)
if (wstr) { if (wstr) {
nsAutoString string; nsAutoString string;
wstr->GetData(string); wstr->GetData(string);
RequestBody<const nsAString> body(&string);
return SendInternal(&body); return GetRequestBodyInternal(string, aResult, aContentLength,
aContentType, aCharset);
} }
// nsIInputStream? // nsIInputStream?
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(supports); nsCOMPtr<nsIInputStream> stream = do_QueryInterface(supports);
if (stream) { if (stream) {
RequestBody<nsIInputStream> body(stream); return GetRequestBodyInternal(stream, aResult, aContentLength,
return SendInternal(&body); aContentType, aCharset);
} }
// nsIXHRSendable? // nsIXHRSendable?
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports); nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
if (sendable) { if (sendable) {
RequestBody<nsIXHRSendable> body(sendable); return GetRequestBodyInternal(sendable, aResult, aContentLength,
return SendInternal(&body); aContentType, aCharset);
} }
// ArrayBuffer? // ArrayBuffer?
JSContext* rootingCx = nsContentUtils::RootingCx(); JSContext* rootingCx = nsContentUtils::RootingCx();
JS::Rooted<JS::Value> realVal(rootingCx); JS::Rooted<JS::Value> realVal(rootingCx);
nsresult rv = aVariant->GetAsJSVal(&realVal); nsresult rv = aBody->GetAsJSVal(&realVal);
if (NS_SUCCEEDED(rv) && !realVal.isPrimitive()) { if (NS_SUCCEEDED(rv) && !realVal.isPrimitive()) {
JS::Rooted<JSObject*> obj(rootingCx, realVal.toObjectOrNull()); JS::Rooted<JSObject*> obj(rootingCx, realVal.toObjectOrNull());
RootedTypedArray<ArrayBuffer> buf(rootingCx); RootedTypedArray<ArrayBuffer> buf(rootingCx);
if (buf.Init(obj)) { if (buf.Init(obj)) {
RequestBody<const ArrayBuffer> body(&buf); buf.ComputeLengthAndData();
return SendInternal(&body); return GetRequestBodyInternal(buf.Data(), buf.Length(), aResult,
aContentLength, aContentType, aCharset);
} }
} }
} else if (dataType == nsIDataType::VTYPE_VOID || }
else if (dataType == nsIDataType::VTYPE_VOID ||
dataType == nsIDataType::VTYPE_EMPTY) { dataType == nsIDataType::VTYPE_EMPTY) {
return SendInternal(nullptr); // Makes us act as if !aBody, don't upload anything
aContentType.AssignLiteral("text/plain");
aCharset.AssignLiteral("UTF-8");
*aContentLength = 0;
return NS_OK;
} }
char16_t* data = nullptr; char16_t* data = nullptr;
uint32_t len = 0; uint32_t len = 0;
rv = aVariant->GetAsWStringWithSize(&len, &data); rv = aBody->GetAsWStringWithSize(&len, &data);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsString string; nsString string;
string.Adopt(data, len); string.Adopt(data, len);
RequestBody<const nsAString> body(&string); return GetRequestBodyInternal(string, aResult, aContentLength, aContentType,
return SendInternal(&body); aCharset);
}
/* static */
nsresult
XMLHttpRequestMainThread::GetRequestBody(nsIVariant* aVariant,
const Nullable<RequestBody>& aBody,
nsIInputStream** aResult,
uint64_t* aContentLength,
nsACString& aContentType,
nsACString& aCharset)
{
// null the content type and charset by default, as per XHR spec step 4
aContentType.SetIsVoid(true);
aCharset.SetIsVoid(true);
if (aVariant) {
return GetRequestBodyInternal(aVariant, aResult, aContentLength,
aContentType, aCharset);
}
const RequestBody& body = aBody.Value();
RequestBody::Value value = body.GetValue();
switch (body.GetType()) {
case XMLHttpRequestMainThread::RequestBody::eArrayBuffer:
{
const ArrayBuffer* buffer = value.mArrayBuffer;
buffer->ComputeLengthAndData();
return GetRequestBodyInternal(buffer->Data(), buffer->Length(), aResult,
aContentLength, aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eArrayBufferView:
{
const ArrayBufferView* view = value.mArrayBufferView;
view->ComputeLengthAndData();
return GetRequestBodyInternal(view->Data(), view->Length(), aResult,
aContentLength, aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eBlob:
{
nsresult rv;
nsCOMPtr<nsIDOMBlob> blob = value.mBlob;
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(blob, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return GetRequestBodyInternal(sendable, aResult, aContentLength,
aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eDocument:
{
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(value.mDocument);
return GetRequestBodyInternal(document, aResult, aContentLength,
aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eDOMString:
{
return GetRequestBodyInternal(*value.mString, aResult, aContentLength,
aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eFormData:
{
MOZ_ASSERT(value.mFormData);
return GetRequestBodyInternal(value.mFormData, aResult, aContentLength,
aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eURLSearchParams:
{
MOZ_ASSERT(value.mURLSearchParams);
return GetRequestBodyInternal(value.mURLSearchParams, aResult,
aContentLength, aContentType, aCharset);
}
case XMLHttpRequestMainThread::RequestBody::eInputStream:
{
return GetRequestBodyInternal(value.mStream, aResult, aContentLength,
aContentType, aCharset);
}
default:
{
return NS_ERROR_FAILURE;
}
}
NS_NOTREACHED("Default cases exist for a reason");
return NS_OK;
}
NS_IMETHODIMP
XMLHttpRequestMainThread::Send(nsIVariant *aBody)
{
return Send(aBody, Nullable<RequestBody>());
} }
nsresult nsresult
XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody) XMLHttpRequestMainThread::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
{ {
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
@@ -2502,7 +2561,7 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
mErrorLoad = false; mErrorLoad = false;
mLoadLengthComputable = false; mLoadLengthComputable = false;
mLoadTotal = 0; mLoadTotal = 0;
if (aBody && httpChannel && if ((aVariant || !aBody.IsNull()) && httpChannel &&
!method.LowerCaseEqualsLiteral("get") && !method.LowerCaseEqualsLiteral("get") &&
!method.LowerCaseEqualsLiteral("head")) { !method.LowerCaseEqualsLiteral("head")) {
@@ -2511,8 +2570,8 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
nsCOMPtr<nsIInputStream> postDataStream; nsCOMPtr<nsIInputStream> postDataStream;
uint64_t size_u64; uint64_t size_u64;
rv = aBody->GetAsStream(getter_AddRefs(postDataStream), rv = GetRequestBody(aVariant, aBody, getter_AddRefs(postDataStream),
&size_u64, defaultContentType, charset); &size_u64, defaultContentType, charset);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// make sure it fits within js MAX_SAFE_INTEGER // make sure it fits within js MAX_SAFE_INTEGER
@@ -2520,7 +2579,7 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
net::InScriptableRange(size_u64) ? static_cast<int64_t>(size_u64) : -1; net::InScriptableRange(size_u64) ? static_cast<int64_t>(size_u64) : -1;
if (postDataStream) { if (postDataStream) {
// If author set no Content-Type, use the default from GetAsStream(). // If author set no Content-Type, use the default from GetRequestBody().
nsAutoCString contentType; nsAutoCString contentType;
GetAuthorRequestHeaderValue("content-type", contentType); GetAuthorRequestHeaderValue("content-type", contentType);
@@ -2774,6 +2833,7 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
mWaitingForOnStopRequest = true; mWaitingForOnStopRequest = true;
// Step 8
mFlagSend = true; mFlagSend = true;
// If we're synchronous, spin an event loop here and wait // If we're synchronous, spin an event loop here and wait
@@ -2832,7 +2892,8 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
if (mUpload && mUpload->HasListenersFor(nsGkAtoms::onprogress)) { if (mUpload && mUpload->HasListenersFor(nsGkAtoms::onprogress)) {
StartProgressEventTimer(); StartProgressEventTimer();
} }
DispatchProgressEvent(this, ProgressEventType::loadstart, false, 0, 0); DispatchProgressEvent(this, ProgressEventType::loadstart, false,
0, 0);
if (mUpload && !mUploadComplete) { if (mUpload && !mUploadComplete) {
DispatchProgressEvent(mUpload, ProgressEventType::loadstart, true, DispatchProgressEvent(mUpload, ProgressEventType::loadstart, true,
0, mUploadTotal); 0, mUploadTotal);

View File

@@ -238,34 +238,100 @@ public:
private: private:
virtual ~XMLHttpRequestMainThread(); virtual ~XMLHttpRequestMainThread();
class RequestBodyBase class RequestBody
{ {
public: public:
virtual nsresult GetAsStream(nsIInputStream** aResult, RequestBody() : mType(eUninitialized)
{
}
explicit RequestBody(const ArrayBuffer* aArrayBuffer) : mType(eArrayBuffer)
{
mValue.mArrayBuffer = aArrayBuffer;
}
explicit RequestBody(const ArrayBufferView* aArrayBufferView) : mType(eArrayBufferView)
{
mValue.mArrayBufferView = aArrayBufferView;
}
explicit RequestBody(Blob& aBlob) : mType(eBlob)
{
mValue.mBlob = &aBlob;
}
explicit RequestBody(mozilla::dom::URLSearchParams& aURLSearchParams) :
mType(eURLSearchParams)
{
mValue.mURLSearchParams = &aURLSearchParams;
}
explicit RequestBody(nsIDocument* aDocument) : mType(eDocument)
{
mValue.mDocument = aDocument;
}
explicit RequestBody(const nsAString& aString) : mType(eDOMString)
{
mValue.mString = &aString;
}
explicit RequestBody(FormData& aFormData) : mType(eFormData)
{
mValue.mFormData = &aFormData;
}
explicit RequestBody(nsIInputStream* aStream) : mType(eInputStream)
{
mValue.mStream = aStream;
}
enum Type {
eUninitialized,
eArrayBuffer,
eArrayBufferView,
eBlob,
eDocument,
eDOMString,
eFormData,
eInputStream,
eURLSearchParams
};
union Value {
const ArrayBuffer* mArrayBuffer;
const ArrayBufferView* mArrayBufferView;
Blob* mBlob;
nsIDocument* mDocument;
const nsAString* mString;
FormData* mFormData;
nsIInputStream* mStream;
URLSearchParams* mURLSearchParams;
};
Type GetType() const
{
MOZ_ASSERT(mType != eUninitialized);
return mType;
}
Value GetValue() const
{
MOZ_ASSERT(mType != eUninitialized);
return mValue;
}
private:
Type mType;
Value mValue;
};
static nsresult GetRequestBody(nsIVariant* aVariant,
const Nullable<RequestBody>& aBody,
nsIInputStream** aResult,
uint64_t* aContentLength, uint64_t* aContentLength,
nsACString& aContentType, nsACString& aContentType,
nsACString& aCharset) const nsACString& aCharset);
{
NS_ASSERTION(false, "RequestBodyBase should not be used directly.");
return NS_ERROR_FAILURE;
}
};
template<typename Type> nsresult Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody);
class RequestBody final : public RequestBodyBase nsresult Send(const Nullable<RequestBody>& aBody)
{ {
Type* mBody; return Send(nullptr, aBody);
public: }
explicit RequestBody(Type* aBody) : mBody(aBody) nsresult Send(const RequestBody& aBody)
{ {
} return Send(Nullable<RequestBody>(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();
@@ -279,44 +345,39 @@ public:
virtual void virtual void
Send(JSContext* /*aCx*/, ErrorResult& aRv) override Send(JSContext* /*aCx*/, ErrorResult& aRv) override
{ {
aRv = SendInternal(nullptr); aRv = Send(Nullable<RequestBody>());
} }
virtual void virtual void
Send(JSContext* /*aCx*/, const ArrayBuffer& aArrayBuffer, Send(JSContext* /*aCx*/, const ArrayBuffer& aArrayBuffer,
ErrorResult& aRv) override ErrorResult& aRv) override
{ {
RequestBody<const ArrayBuffer> body(&aArrayBuffer); aRv = Send(RequestBody(&aArrayBuffer));
aRv = SendInternal(&body);
} }
virtual void virtual void
Send(JSContext* /*aCx*/, const ArrayBufferView& aArrayBufferView, Send(JSContext* /*aCx*/, const ArrayBufferView& aArrayBufferView,
ErrorResult& aRv) override ErrorResult& aRv) override
{ {
RequestBody<const ArrayBufferView> body(&aArrayBufferView); aRv = Send(RequestBody(&aArrayBufferView));
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); aRv = Send(RequestBody(aBlob));
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); aRv = Send(RequestBody(aURLSearchParams));
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); aRv = Send(RequestBody(&aDoc));
aRv = SendInternal(&body);
} }
virtual void virtual void
@@ -324,17 +385,16 @@ public:
{ {
if (DOMStringIsNull(aString)) { if (DOMStringIsNull(aString)) {
Send(aCx, aRv); Send(aCx, aRv);
} else { }
RequestBody<const nsAString> body(&aString); else {
aRv = SendInternal(&body); aRv = Send(RequestBody(aString));
} }
} }
virtual void virtual void
Send(JSContext* /*aCx*/, FormData& aFormData, ErrorResult& aRv) override Send(JSContext* /*aCx*/, FormData& aFormData, ErrorResult& aRv) override
{ {
RequestBody<FormData> body(&aFormData); aRv = Send(RequestBody(aFormData));
aRv = SendInternal(&body);
} }
virtual void virtual void
@@ -358,8 +418,7 @@ public:
} }
return; return;
} }
RequestBody<nsIInputStream> body(aStream); aRv = Send(RequestBody(aStream));
aRv = SendInternal(&body);
} }
void void