Issue #1442 - Part 10c - Use application/octet-stream for arrayBuffer in sendBeacon. https://bugzilla.mozilla.org/show_bug.cgi?id=1329298 Pre-requisite for Part 11.

This commit is contained in:
Brian Smith 2023-09-27 23:40:02 -05:00 • committed by roytam1
commit 772ab8ac41
3 changed files with 25 additions and 12 deletions

View file

@ -864,37 +864,37 @@ Navigator::SendBeacon(const nsAString& aUrl,
ErrorResult& aRv) ErrorResult& aRv)
{ {
if (aData.IsNull()) { if (aData.IsNull()) {
return SendBeaconInternal(aUrl, nullptr, /* isBlob */ false, aRv); return SendBeaconInternal(aUrl, nullptr, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsArrayBuffer()) { if (aData.Value().IsArrayBuffer()) {
BodyExtractor<const ArrayBuffer> body(&aData.Value().GetAsArrayBuffer()); BodyExtractor<const ArrayBuffer> body(&aData.Value().GetAsArrayBuffer());
return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsArrayBufferView()) { if (aData.Value().IsArrayBufferView()) {
BodyExtractor<const ArrayBufferView> body(&aData.Value().GetAsArrayBufferView()); BodyExtractor<const ArrayBufferView> body(&aData.Value().GetAsArrayBufferView());
return SendBeaconInternal(aUrl, &body, /* isBlob*/ false, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsBlob()) { if (aData.Value().IsBlob()) {
BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsBlob()); BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsBlob());
return SendBeaconInternal(aUrl, &body, /* isBlob */ true, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsFormData()) { if (aData.Value().IsFormData()) {
BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsFormData()); BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsFormData());
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsUSVString()) { if (aData.Value().IsUSVString()) {
BodyExtractor<const nsAString> body(&aData.Value().GetAsUSVString()); BodyExtractor<const nsAString> body(&aData.Value().GetAsUSVString());
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
if (aData.Value().IsURLSearchParams()) { if (aData.Value().IsURLSearchParams()) {
BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsURLSearchParams()); BodyExtractor<nsIXHRSendable> body(&aData.Value().GetAsURLSearchParams());
return SendBeaconInternal(aUrl, &body, /* isBlob */ false, aRv); return SendBeaconInternal(aUrl, &body, eBeaconTypeOther, aRv);
} }
MOZ_CRASH("Invalid data type."); MOZ_CRASH("Invalid data type.");
@ -904,7 +904,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
bool bool
Navigator::SendBeaconInternal(const nsAString& aUrl, Navigator::SendBeaconInternal(const nsAString& aUrl,
BodyExtractorBase* aBody, BodyExtractorBase* aBody,
bool aIsBlob, BeaconType aType,
ErrorResult& aRv) ErrorResult& aRv)
{ {
if (!mWindow) { if (!mWindow) {
@ -947,7 +947,7 @@ Navigator::SendBeaconInternal(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 = aIsBlob nsSecurityFlags securityFlags = aType == eBeaconTypeBlob
? 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;
@ -987,6 +987,12 @@ Navigator::SendBeaconInternal(const nsAString& aUrl,
return false; return false;
} }
if (aType == eBeaconTypeArrayBuffer) {
MOZ_ASSERT(contentTypeWithCharset.IsEmpty());
MOZ_ASSERT(charset.IsEmpty());
contentTypeWithCharset.Assign("application/octet-stream");
}
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(channel); nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(channel);
if (!uploadChannel) { if (!uploadChannel) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);

View file

@ -256,9 +256,17 @@ 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);
// This enum helps SendBeaconInternal to apply different behaviors to body
// types.
enum BeaconType {
eBeaconTypeBlob,
eBeaconTypeArrayBuffer,
eBeaconTypeOther
};
bool SendBeaconInternal(const nsAString& aUrl, bool SendBeaconInternal(const nsAString& aUrl,
BodyExtractorBase* aBody, BodyExtractorBase* aBody,
bool aIsBlob, BeaconType aType,
ErrorResult& aRv); ErrorResult& aRv);
RefPtr<nsMimeTypeArray> mMimeTypes; RefPtr<nsMimeTypeArray> mMimeTypes;

View file

@ -88,8 +88,7 @@ function handleRequest(request, response) {
data += charcode; data += charcode;
} }
var mimetype = request.hasHeader("Content-Type") var mimetype = request.getHeader("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) {