diff options
Diffstat (limited to 'dom/xhr')
-rw-r--r-- | dom/xhr/XMLHttpRequestMainThread.cpp | 192 | ||||
-rw-r--r-- | dom/xhr/XMLHttpRequestMainThread.h | 52 | ||||
-rw-r--r-- | dom/xhr/nsIXMLHttpRequest.idl | 5 |
3 files changed, 25 insertions, 224 deletions
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index d97476ef61..a89af3c370 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -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 XMLHttpRequestMainThread::CreateChannel() { @@ -2792,7 +2623,7 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant) // document? nsCOMPtr<nsIDocument> doc = do_QueryInterface(supports); if (doc) { - RequestBody<nsIDocument> body(doc); + BodyExtractor<nsIDocument> body(doc); return SendInternal(&body); } @@ -2801,21 +2632,21 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant) if (wstr) { nsAutoString string; wstr->GetData(string); - RequestBody<const nsAString> body(&string); + BodyExtractor<const nsAString> body(&string); return SendInternal(&body); } // nsIInputStream? nsCOMPtr<nsIInputStream> stream = do_QueryInterface(supports); if (stream) { - RequestBody<nsIInputStream> body(stream); + BodyExtractor<nsIInputStream> body(stream); return SendInternal(&body); } // nsIXHRSendable? nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports); if (sendable) { - RequestBody<nsIXHRSendable> body(sendable); + BodyExtractor<nsIXHRSendable> body(sendable); return SendInternal(&body); } @@ -2826,9 +2657,9 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant) nsresult rv = aVariant->GetAsJSVal(&realVal); if (NS_SUCCEEDED(rv) && !realVal.isPrimitive()) { JS::Rooted<JSObject*> obj(rootingCx, realVal.toObjectOrNull()); - RootedTypedArray<ArrayBuffer> buf(rootingCx); + RootedSpiderMonkeyInterface<ArrayBuffer> buf(rootingCx); if (buf.Init(obj)) { - RequestBody<const ArrayBuffer> body(&buf); + BodyExtractor<const ArrayBuffer> body(&buf); return SendInternal(&body); } } @@ -2845,12 +2676,12 @@ XMLHttpRequestMainThread::Send(nsIVariant* aVariant) nsString string; string.Adopt(data, len); - RequestBody<const nsAString> body(&string); + BodyExtractor<const nsAString> body(&string); return SendInternal(&body); } nsresult -XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody) +XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody) { NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED); @@ -2916,13 +2747,6 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody) mAuthorRequestHeaders.Get("content-type", uploadContentType); if (uploadContentType.IsVoid()) { 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. diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h index 4a6eeec2ef..f2145605ef 100644 --- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -34,7 +34,11 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/NotNull.h" #include "mozilla/dom/MutableBlobStorage.h" +#include "mozilla/dom/BodyExtractor.h" #include "mozilla/dom/TypedArray.h" +#include "mozilla/dom/File.h" +#include "mozilla/dom/FormData.h" +#include "mozilla/dom/URLSearchParams.h" #include "mozilla/dom/XMLHttpRequest.h" #include "mozilla/dom/XMLHttpRequestBinding.h" #include "mozilla/dom/XMLHttpRequestEventTarget.h" @@ -54,11 +58,8 @@ class nsIJSID; namespace mozilla { namespace dom { -class Blob; class BlobSet; class DOMString; -class FormData; -class URLSearchParams; class XMLHttpRequestUpload; struct OriginAttributesDictionary; @@ -288,34 +289,7 @@ public: private: virtual ~XMLHttpRequestMainThread(); - class RequestBodyBase - { - 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); + nsresult SendInternal(const BodyExtractorBase* aBody); bool IsCrossSiteCORSRequest() const; bool IsDeniedCrossSiteCORSRequest(); @@ -336,7 +310,7 @@ public: Send(JSContext* /*aCx*/, const ArrayBuffer& aArrayBuffer, ErrorResult& aRv) override { - RequestBody<const ArrayBuffer> body(&aArrayBuffer); + BodyExtractor<const ArrayBuffer> body(&aArrayBuffer); aRv = SendInternal(&body); } @@ -344,28 +318,28 @@ public: Send(JSContext* /*aCx*/, const ArrayBufferView& aArrayBufferView, ErrorResult& aRv) override { - RequestBody<const ArrayBufferView> body(&aArrayBufferView); + BodyExtractor<const ArrayBufferView> body(&aArrayBufferView); aRv = SendInternal(&body); } virtual void Send(JSContext* /*aCx*/, Blob& aBlob, ErrorResult& aRv) override { - RequestBody<Blob> body(&aBlob); + BodyExtractor<nsIXHRSendable> body(&aBlob); aRv = SendInternal(&body); } virtual void Send(JSContext* /*aCx*/, URLSearchParams& aURLSearchParams, ErrorResult& aRv) override { - RequestBody<URLSearchParams> body(&aURLSearchParams); + BodyExtractor<nsIXHRSendable> body(&aURLSearchParams); aRv = SendInternal(&body); } virtual void Send(JSContext* /*aCx*/, nsIDocument& aDoc, ErrorResult& aRv) override { - RequestBody<nsIDocument> body(&aDoc); + BodyExtractor<nsIDocument> body(&aDoc); aRv = SendInternal(&body); } @@ -375,7 +349,7 @@ public: if (DOMStringIsNull(aString)) { Send(aCx, aRv); } else { - RequestBody<const nsAString> body(&aString); + BodyExtractor<const nsAString> body(&aString); aRv = SendInternal(&body); } } @@ -383,7 +357,7 @@ public: virtual void Send(JSContext* /*aCx*/, FormData& aFormData, ErrorResult& aRv) override { - RequestBody<FormData> body(&aFormData); + BodyExtractor<nsIXHRSendable> body(&aFormData); aRv = SendInternal(&body); } @@ -391,7 +365,7 @@ public: Send(JSContext* aCx, nsIInputStream* aStream, ErrorResult& aRv) override { NS_ASSERTION(aStream, "Null should go to string version"); - RequestBody<nsIInputStream> body(aStream); + BodyExtractor<nsIInputStream> body(aStream); aRv = SendInternal(&body); } diff --git a/dom/xhr/nsIXMLHttpRequest.idl b/dom/xhr/nsIXMLHttpRequest.idl index 53e80bab70..5505bd47ee 100644 --- a/dom/xhr/nsIXMLHttpRequest.idl +++ b/dom/xhr/nsIXMLHttpRequest.idl @@ -326,9 +326,12 @@ interface nsIXMLHttpRequest : nsISupports [uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)] 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, out uint64_t contentLength, - out ACString contentType, + out ACString contentTypeWithCharset, out ACString charset); }; |