Bug 1712930 - Part 6: Get rid of NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D116080
This commit is contained in:
Edgar Chen 2021-05-28 21:12:13 +00:00
parent 5b4acdb4c5
commit 18ac9679bb
6 changed files with 92 additions and 85 deletions

View File

@ -299,7 +299,6 @@ const ErrorCodes = {
NS_ERROR_DOM_INVALID_HEADER_NAME: 0x805303f9,
NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT: 0x805303fa,
NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED: 0x805303fb,
NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING: 0x805303fc,
NS_ERROR_DOM_JS_DECODING_ERROR: 0x80530402,
NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT: 0x80530403,
NS_ERROR_DOM_IMAGE_INVALID_REQUEST: 0x80530404,

View File

@ -139,7 +139,6 @@ DOM4_MSG_DEF(SyntaxError, "Invalid header name.", NS_ERROR_DOM_INVALID_HEADER_NA
/* XMLHttpRequest errors. */
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest has an invalid context.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT)
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest state must be OPENED.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED)
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest must not be sending.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING)
/* Image decode errors. */
DOM4_MSG_DEF(EncodingError, "Node bound to inactive document.", NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT)

View File

@ -2819,51 +2819,51 @@ void XMLHttpRequestMainThread::Send(
NOT_CALLABLE_IN_SYNC_SEND_RV
if (aData.IsNull()) {
aRv = SendInternal(nullptr);
SendInternal(nullptr, false, aRv);
return;
}
if (aData.Value().IsDocument()) {
BodyExtractor<Document> body(&aData.Value().GetAsDocument());
aRv = SendInternal(&body, true);
SendInternal(&body, true, aRv);
return;
}
if (aData.Value().IsBlob()) {
BodyExtractor<const Blob> body(&aData.Value().GetAsBlob());
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
return;
}
if (aData.Value().IsArrayBuffer()) {
BodyExtractor<const ArrayBuffer> body(&aData.Value().GetAsArrayBuffer());
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
return;
}
if (aData.Value().IsArrayBufferView()) {
BodyExtractor<const ArrayBufferView> body(
&aData.Value().GetAsArrayBufferView());
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
return;
}
if (aData.Value().IsFormData()) {
BodyExtractor<const FormData> body(&aData.Value().GetAsFormData());
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
return;
}
if (aData.Value().IsURLSearchParams()) {
BodyExtractor<const URLSearchParams> body(
&aData.Value().GetAsURLSearchParams());
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
return;
}
if (aData.Value().IsUSVString()) {
BodyExtractor<const nsAString> body(&aData.Value().GetAsUSVString());
aRv = SendInternal(&body, true);
SendInternal(&body, true, aRv);
return;
}
}
@ -2885,25 +2885,31 @@ nsresult XMLHttpRequestMainThread::MaybeSilentSendFailure(nsresult aRv) {
return NS_OK;
}
nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
bool aBodyIsDocumentOrString) {
void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
bool aBodyIsDocumentOrString,
ErrorResult& aRv) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
if (!mPrincipal) {
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
// Step 1
if (mState != XMLHttpRequest_Binding::OPENED) {
return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED;
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED);
return;
}
// Step 2
if (mFlagSend) {
return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING;
aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
return;
}
nsresult rv = CheckCurrentGlobalCorrectness();
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT;
if (NS_FAILED(CheckCurrentGlobalCorrectness())) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT);
return;
}
// If open() failed to create the channel, then throw a network error
@ -2911,13 +2917,15 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
// we have internal code relying on the channel being created in open().
if (!mChannel) {
mFlagSend = true; // so CloseRequestWithError sets us to DONE.
return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
return;
}
// non-GET requests aren't allowed for blob.
if (IsBlobURI(mRequestURL) && !mRequestMethod.EqualsLiteral("GET")) {
mFlagSend = true; // so CloseRequestWithError sets us to DONE.
return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
return;
}
// XXX We should probably send a warning to the JS console
@ -2938,9 +2946,11 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
nsAutoCString charset;
nsAutoCString defaultContentType;
uint64_t size_u64;
rv = aBody->GetAsStream(getter_AddRefs(uploadStream), &size_u64,
defaultContentType, charset);
NS_ENSURE_SUCCESS(rv, rv);
aRv = aBody->GetAsStream(getter_AddRefs(uploadStream), &size_u64,
defaultContentType, charset);
if (aRv.Failed()) {
return;
}
// make sure it fits within js MAX_SAFE_INTEGER
mUploadTotal =
@ -2993,8 +3003,8 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
nsCOMPtr<nsIURI> uri;
nsAutoCString scheme;
rv = mChannel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
aRv = mChannel->GetURI(getter_AddRefs(uri));
if (!aRv.Failed()) {
uri->GetScheme(scheme);
if (scheme.LowerCaseEqualsLiteral("jar")) {
mIsMappedArrayBuffer = true;
@ -3002,8 +3012,10 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
}
}
rv = InitiateFetch(uploadStream.forget(), mUploadTotal, uploadContentType);
NS_ENSURE_SUCCESS(rv, rv);
aRv = InitiateFetch(uploadStream.forget(), mUploadTotal, uploadContentType);
if (aRv.Failed()) {
return;
}
// Start our timeout
mRequestSentTime = PR_Now();
@ -3035,30 +3047,32 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
SuspendEventDispatching();
StopProgressEventTimer();
auto scopeExit = MakeScopeExit([&] {
UnsuppressEventHandlingAndResume();
ResumeEventDispatching();
});
SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
if (syncTimeoutType == eErrorOrExpired) {
Abort();
rv = NS_ERROR_DOM_NETWORK_ERR;
aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
return;
}
if (NS_SUCCEEDED(rv)) {
nsAutoSyncOperation sync(mSuspendedDoc,
SyncOperationBehavior::eSuspendInput);
if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
rv = NS_ERROR_UNEXPECTED;
}
// Time expired... We should throw.
if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
rv = NS_ERROR_DOM_NETWORK_ERR;
}
nsAutoSyncOperation sync(mSuspendedDoc,
SyncOperationBehavior::eSuspendInput);
if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
CancelSyncTimeoutTimer();
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
UnsuppressEventHandlingAndResume();
ResumeEventDispatching();
// Time expired... We should throw.
if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
CancelSyncTimeoutTimer();
aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
return;
}
} else {
// Now that we've successfully opened the channel, we can change state. Note
// that this needs to come after the AsyncOpen() and rv check, because this
@ -3080,10 +3094,8 @@ nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
}
if (!mChannel) {
return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
}
return rv;
}
// http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-setrequestheader
@ -3100,7 +3112,7 @@ void XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
// Step 2
if (mFlagSend) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING);
aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
return;
}
@ -3230,26 +3242,26 @@ bool XMLHttpRequestMainThread::MozBackgroundRequest() const {
return mFlagBackgroundRequest;
}
nsresult XMLHttpRequestMainThread::SetMozBackgroundRequest(
bool aMozBackgroundRequest) {
void XMLHttpRequestMainThread::SetMozBackgroundRequestExternal(
bool aMozBackgroundRequest, ErrorResult& aRv) {
if (!IsSystemXHR()) {
return NS_ERROR_DOM_SECURITY_ERR;
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
if (mState != XMLHttpRequest_Binding::UNSENT) {
// Can't change this while we're in the middle of something.
return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING;
aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
return;
}
mFlagBackgroundRequest = aMozBackgroundRequest;
return NS_OK;
}
void XMLHttpRequestMainThread::SetMozBackgroundRequest(
bool aMozBackgroundRequest, ErrorResult& aRv) {
// No errors for this webIDL method on main-thread.
SetMozBackgroundRequest(aMozBackgroundRequest);
SetMozBackgroundRequestExternal(aMozBackgroundRequest, IgnoreErrors());
}
void XMLHttpRequestMainThread::SetOriginStack(
@ -3284,7 +3296,7 @@ void XMLHttpRequestMainThread::SetWithCredentials(bool aWithCredentials,
if ((mState != XMLHttpRequest_Binding::UNSENT &&
mState != XMLHttpRequest_Binding::OPENED) ||
mFlagSend || mIsAnon) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING);
aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
return;
}

View File

@ -298,8 +298,8 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
virtual ~XMLHttpRequestMainThread();
nsresult MaybeSilentSendFailure(nsresult aRv);
nsresult SendInternal(const BodyExtractorBase* aBody,
bool aBodyIsDocumentOrString = false);
void SendInternal(const BodyExtractorBase* aBody,
bool aBodyIsDocumentOrString, ErrorResult& aRv);
bool IsCrossSiteCORSRequest() const;
bool IsDeniedCrossSiteCORSRequest();
@ -318,7 +318,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
virtual void SendInputStream(nsIInputStream* aInputStream,
ErrorResult& aRv) override {
BodyExtractor<nsIInputStream> body(aInputStream);
aRv = SendInternal(&body);
SendInternal(&body, false, aRv);
}
void RequestErrorSteps(const ProgressEventType aEventType,
@ -393,7 +393,8 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
virtual bool MozBackgroundRequest() const override;
nsresult SetMozBackgroundRequest(bool aMozBackgroundRequest);
void SetMozBackgroundRequestExternal(bool aMozBackgroundRequest,
ErrorResult& aRv);
virtual void SetMozBackgroundRequest(bool aMozBackgroundRequest,
ErrorResult& aRv) override;

View File

@ -532,6 +532,7 @@ class SetBackgroundRequestRunnable final
~SetBackgroundRequestRunnable() = default;
virtual void RunOnMainThread(ErrorResult& aRv) override {
// XXXedgar, do we intend to ignore the errors?
mProxy->mXHR->SetMozBackgroundRequest(mValue, aRv);
}
};
@ -695,12 +696,12 @@ class OpenRunnable final : public WorkerThreadProxySyncRunnable {
WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
mProxy->mWorkerPrivate = mWorkerPrivate;
aRv = MainThreadRunInternal();
MainThreadRunInternal(aRv);
mProxy->mWorkerPrivate = oldWorker;
}
nsresult MainThreadRunInternal();
void MainThreadRunInternal(ErrorResult& aRv);
};
class SetRequestHeaderRunnable final : public WorkerThreadProxySyncRunnable {
@ -1206,40 +1207,41 @@ void AbortRunnable::RunOnMainThread(ErrorResult& aRv) {
mProxy->Reset();
}
nsresult OpenRunnable::MainThreadRunInternal() {
void OpenRunnable::MainThreadRunInternal(ErrorResult& aRv) {
if (!mProxy->Init()) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mBackgroundRequest) {
nsresult rv = mProxy->mXHR->SetMozBackgroundRequest(mBackgroundRequest);
NS_ENSURE_SUCCESS(rv, rv);
mProxy->mXHR->SetMozBackgroundRequestExternal(mBackgroundRequest, aRv);
if (aRv.Failed()) {
return;
}
}
if (mOriginStack) {
mProxy->mXHR->SetOriginStack(std::move(mOriginStack));
}
ErrorResult rv;
if (mWithCredentials) {
mProxy->mXHR->SetWithCredentials(mWithCredentials, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
mProxy->mXHR->SetWithCredentials(mWithCredentials, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (mTimeout) {
mProxy->mXHR->SetTimeout(mTimeout, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
mProxy->mXHR->SetTimeout(mTimeout, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (!mMimeTypeOverride.IsVoid()) {
mProxy->mXHR->OverrideMimeType(mMimeTypeOverride, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
mProxy->mXHR->OverrideMimeType(mMimeTypeOverride, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
@ -1248,25 +1250,20 @@ nsresult OpenRunnable::MainThreadRunInternal() {
mProxy->mXHR->Open(
mMethod, mURL, true, mUser.WasPassed() ? mUser.Value() : VoidString(),
mPassword.WasPassed() ? mPassword.Value() : VoidString(), rv);
mPassword.WasPassed() ? mPassword.Value() : VoidString(), aRv);
MOZ_ASSERT(mProxy->mInOpen);
mProxy->mInOpen = false;
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (mSource) {
mProxy->mXHR->SetSource(std::move(mSource));
}
mProxy->mXHR->SetResponseType(mResponseType, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
return NS_OK;
mProxy->mXHR->SetResponseType(mResponseType, aRv);
}
void SendRunnable::RunOnMainThread(ErrorResult& aRv) {

View File

@ -715,7 +715,6 @@ with modules["DOM"]:
errors["NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT"] = FAILURE(1018)
errors["NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED"] = FAILURE(1019)
errors["NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING"] = FAILURE(1020)
# When manipulating the bytecode cache with the JS API, some transcoding
# errors, such as a different bytecode format can cause failures of the