diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index d1af772ba3..6509d8231f 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -864,37 +864,37 @@ Navigator::SendBeacon(const nsAString& aUrl, ErrorResult& aRv) { if (aData.IsNull()) { - return SendBeaconInternal(aUrl, nullptr, /* isBlob */ false, aRv); + return SendBeaconInternal(aUrl, nullptr, eBeaconTypeOther, aRv); } if (aData.Value().IsArrayBuffer()) { BodyExtractor body(&aData.Value().GetAsArrayBuffer()); - return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } if (aData.Value().IsArrayBufferView()) { BodyExtractor body(&aData.Value().GetAsArrayBufferView()); - return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } if (aData.Value().IsBlob()) { BodyExtractor body(&aData.Value().GetAsBlob()); - return SendBeaconInternal(aUrl, &body, /* isBlob */ true, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } if (aData.Value().IsFormData()) { BodyExtractor body(&aData.Value().GetAsFormData()); - return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } if (aData.Value().IsUSVString()) { BodyExtractor body(&aData.Value().GetAsUSVString()); - return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } if (aData.Value().IsURLSearchParams()) { BodyExtractor body(&aData.Value().GetAsURLSearchParams()); - return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); + return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv); } MOZ_CRASH("Invalid data type."); @@ -904,7 +904,7 @@ Navigator::SendBeacon(const nsAString& aUrl, bool Navigator::SendBeaconInternal(const nsAString& aUrl, BodyExtractorBase* aBody, - bool aIsBlob, + BeaconType aType, ErrorResult& aRv) { if (!mWindow) { @@ -947,7 +947,7 @@ Navigator::SendBeaconInternal(const nsAString& aUrl, nsIChannel::LOAD_CLASSIFY_URI; // No need to use CORS for sendBeacon unless it's a BLOB - nsSecurityFlags securityFlags = aIsBlob + nsSecurityFlags securityFlags = aType == eBeaconTypeBlob ? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS; securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE; @@ -987,6 +987,12 @@ Navigator::SendBeaconInternal(const nsAString& aUrl, return false; } + if (aType == eBeaconTypeArrayBuffer) { + MOZ_ASSERT(contentTypeWithCharset.IsEmpty()); + MOZ_ASSERT(charset.IsEmpty()); + contentTypeWithCharset.Assign("application/octet-stream"); + } + nsCOMPtr uploadChannel = do_QueryInterface(channel); if (!uploadChannel) { aRv.Throw(NS_ERROR_FAILURE); diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index 16fcd4d440..f121af383c 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -256,9 +256,17 @@ private: bool CheckPermission(const char* type); static bool CheckPermission(nsPIDOMWindowInner* aWindow, const char* aType); + // This enum helps SendBeaconInternal to apply different behaviors to body + // types. + enum BeaconType { + eBeaconTypeBlob, + eBeaconTypeArrayBuffer, + eBeaconTypeOther + }; + bool SendBeaconInternal(const nsAString& aUrl, BodyExtractorBase* aBody, - bool aIsBlob, + BeaconType aType, ErrorResult& aRv); RefPtr mMimeTypes; diff --git a/dom/tests/mochitest/beacon/beacon-handler.sjs b/dom/tests/mochitest/beacon/beacon-handler.sjs index e4a98f7202..4c51d371d8 100644 --- a/dom/tests/mochitest/beacon/beacon-handler.sjs +++ b/dom/tests/mochitest/beacon/beacon-handler.sjs @@ -88,8 +88,7 @@ function handleRequest(request, response) { data += charcode; } - var mimetype = request.hasHeader("Content-Type") - ? request.getHeader("Content-Type") : "application/octet-stream"; + var mimetype = request.getHeader("Content-Type"); // check to see if this is form data. if (mimetype.indexOf("multipart/form-data") != -1) {