summaryrefslogtreecommitdiffstats
path: root/dom/xhr
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xhr')
-rw-r--r--dom/xhr/XMLHttpRequestMainThread.cpp69
-rw-r--r--dom/xhr/XMLHttpRequestMainThread.h5
-rw-r--r--dom/xhr/XMLHttpRequestWorker.cpp50
-rw-r--r--dom/xhr/XMLHttpRequestWorker.h7
-rw-r--r--dom/xhr/tests/mochitest.ini7
5 files changed, 105 insertions, 33 deletions
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
index a47a01aa0..4fd34a993 100644
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -1081,10 +1081,75 @@ XMLHttpRequestMainThread::CloseRequestWithError(const ProgressEventType aType)
}
void
-XMLHttpRequestMainThread::Abort(ErrorResult& arv)
+XMLHttpRequestMainThread::RequestErrorSteps(const ProgressEventType aEventType,
+ const nsresult aOptionalException,
+ ErrorResult& aRv)
+{
+ // Step 1
+ mState = State::done;
+
+ StopProgressEventTimer();
+
+ // Step 2
+ mFlagSend = false;
+
+ // Step 3
+ ResetResponse();
+
+ // If we're in the destructor, don't risk dispatching an event.
+ if (mFlagDeleted) {
+ mFlagSyncLooping = false;
+ return;
+ }
+
+ // Step 4
+ if (mFlagSynchronous && NS_FAILED(aOptionalException)) {
+ aRv.Throw(aOptionalException);
+ return;
+ }
+
+ // Step 5
+ FireReadystatechangeEvent();
+
+ // Step 6
+ if (mUpload && !mUploadComplete) {
+
+ // Step 6-1
+ mUploadComplete = true;
+
+ // Step 6-2
+ if (mFlagHadUploadListenersOnSend) {
+
+ // Steps 6-3, 6-4 (loadend is fired for us)
+ DispatchProgressEvent(mUpload, aEventType, 0, -1);
+ }
+ }
+
+ // Steps 7 and 8 (loadend is fired for us)
+ DispatchProgressEvent(this, aEventType, 0, -1);
+}
+
+void
+XMLHttpRequestMainThread::Abort(ErrorResult& aRv)
{
mFlagAborted = true;
- CloseRequestWithError(ProgressEventType::abort);
+
+ // Step 1
+ CloseRequest();
+
+ // Step 2
+ if ((mState == State::opened && mFlagSend) ||
+ mState == State::headers_received ||
+ mState == State::loading) {
+ RequestErrorSteps(ProgressEventType::abort, NS_OK, aRv);
+ }
+
+ // Step 3
+ if (mState == State::done) {
+ ChangeState(State::unsent, false); // no ReadystateChange event
+ }
+
+ mFlagSyncLooping = false;
}
NS_IMETHODIMP
diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h
index c9bcddf99..68499874a 100644
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -397,6 +397,11 @@ public:
}
void
+ RequestErrorSteps(const ProgressEventType aEventType,
+ const nsresult aOptionalException,
+ ErrorResult& aRv);
+
+ void
Abort() {
ErrorResult rv;
Abort(rv);
diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp
index 93b93a2b1..c9e892f26 100644
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -208,9 +208,9 @@ public:
}
void
- Dispatch(ErrorResult& aRv)
+ Dispatch(Status aFailStatus, ErrorResult& aRv)
{
- WorkerMainThreadRunnable::Dispatch(aRv);
+ WorkerMainThreadRunnable::Dispatch(aFailStatus, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@@ -1633,11 +1633,10 @@ XMLHttpRequestWorker::ReleaseProxy(ReleaseType aType)
new SyncTeardownRunnable(mWorkerPrivate, mProxy);
mProxy = nullptr;
- ErrorResult forAssertionsOnly;
- runnable->Dispatch(forAssertionsOnly);
- if (forAssertionsOnly.Failed()) {
- NS_ERROR("Failed to dispatch teardown runnable!");
- }
+ IgnoredErrorResult forAssertionsOnly;
+ // This runnable _must_ be executed.
+ runnable->Dispatch(Dead, forAssertionsOnly);
+ MOZ_DIAGNOSTIC_ASSERT(!forAssertionsOnly.Failed());
}
}
}
@@ -1669,7 +1668,9 @@ XMLHttpRequestWorker::MaybeDispatchPrematureAbortEvents(ErrorResult& aRv)
// Only send readystatechange event when state changed.
bool isStateChanged = false;
- if (mStateData.mReadyState != 4) {
+ if ((mStateData.mReadyState == 1 && mStateData.mFlagSend) ||
+ mStateData.mReadyState == 2 ||
+ mStateData.mReadyState == 3) {
isStateChanged = true;
mStateData.mReadyState = 4;
}
@@ -1802,8 +1803,12 @@ XMLHttpRequestWorker::SendInternal(SendRunnable* aRunnable,
nsCOMPtr<nsIEventTarget> syncLoopTarget;
bool isSyncXHR = mProxy->mIsSyncXHR;
if (isSyncXHR) {
- autoSyncLoop.emplace(mWorkerPrivate);
- syncLoopTarget = autoSyncLoop->EventTarget();
+ autoSyncLoop.emplace(mWorkerPrivate, Terminating);
+ syncLoopTarget = autoSyncLoop->GetEventTarget();
+ if (!syncLoopTarget) {
+ aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return;
+ }
}
mProxy->mOuterChannelId++;
@@ -1811,7 +1816,9 @@ XMLHttpRequestWorker::SendInternal(SendRunnable* aRunnable,
aRunnable->SetSyncLoopTarget(syncLoopTarget);
aRunnable->SetHaveUploadListeners(hasUploadListeners);
- aRunnable->Dispatch(aRv);
+ mStateData.mFlagSend = true;
+
+ aRunnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
// Dispatch() may have spun the event loop and we may have already unrooted.
// If so we don't want autoUnpin to try again.
@@ -1837,6 +1844,7 @@ XMLHttpRequestWorker::SendInternal(SendRunnable* aRunnable,
if (!autoSyncLoop->Run() && !aRv.Failed()) {
aRv.Throw(NS_ERROR_FAILURE);
}
+ mStateData.mFlagSend = false;
}
bool
@@ -1884,7 +1892,7 @@ XMLHttpRequestWorker::Open(const nsACString& aMethod,
mTimeout, mResponseType);
++mProxy->mOpenCount;
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
if (mProxy && !--mProxy->mOpenCount) {
ReleaseProxy();
@@ -1921,7 +1929,7 @@ XMLHttpRequestWorker::SetRequestHeader(const nsACString& aHeader,
RefPtr<SetRequestHeaderRunnable> runnable =
new SetRequestHeaderRunnable(mWorkerPrivate, mProxy, aHeader, aValue);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
void
@@ -1944,7 +1952,7 @@ XMLHttpRequestWorker::SetTimeout(uint32_t aTimeout, ErrorResult& aRv)
RefPtr<SetTimeoutRunnable> runnable =
new SetTimeoutRunnable(mWorkerPrivate, mProxy, aTimeout);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
void
@@ -1967,7 +1975,7 @@ XMLHttpRequestWorker::SetWithCredentials(bool aWithCredentials, ErrorResult& aRv
RefPtr<SetWithCredentialsRunnable> runnable =
new SetWithCredentialsRunnable(mWorkerPrivate, mProxy, aWithCredentials);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
void
@@ -1992,7 +2000,7 @@ XMLHttpRequestWorker::SetMozBackgroundRequest(bool aBackgroundRequest,
RefPtr<SetBackgroundRequestRunnable> runnable =
new SetBackgroundRequestRunnable(mWorkerPrivate, mProxy,
aBackgroundRequest);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
XMLHttpRequestUpload*
@@ -2260,7 +2268,7 @@ XMLHttpRequestWorker::Abort(ErrorResult& aRv)
mProxy->mOuterEventStreamId++;
RefPtr<AbortRunnable> runnable = new AbortRunnable(mWorkerPrivate, mProxy);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
void
@@ -2283,7 +2291,7 @@ XMLHttpRequestWorker::GetResponseHeader(const nsACString& aHeader,
RefPtr<GetResponseHeaderRunnable> runnable =
new GetResponseHeaderRunnable(mWorkerPrivate, mProxy, aHeader,
responseHeader);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
return;
}
@@ -2309,7 +2317,7 @@ XMLHttpRequestWorker::GetAllResponseHeaders(nsACString& aResponseHeaders,
nsCString responseHeaders;
RefPtr<GetAllResponseHeadersRunnable> runnable =
new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
return;
}
@@ -2341,7 +2349,7 @@ XMLHttpRequestWorker::OverrideMimeType(const nsAString& aMimeType, ErrorResult&
RefPtr<OverrideMimeTypeRunnable> runnable =
new OverrideMimeTypeRunnable(mWorkerPrivate, mProxy, aMimeType);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
}
void
@@ -2377,7 +2385,7 @@ XMLHttpRequestWorker::SetResponseType(XMLHttpRequestResponseType aResponseType,
RefPtr<SetResponseTypeRunnable> runnable =
new SetResponseTypeRunnable(mWorkerPrivate, mProxy, aResponseType);
- runnable->Dispatch(aRv);
+ runnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
return;
}
diff --git a/dom/xhr/XMLHttpRequestWorker.h b/dom/xhr/XMLHttpRequestWorker.h
index 90232fe85..c6647f8f3 100644
--- a/dom/xhr/XMLHttpRequestWorker.h
+++ b/dom/xhr/XMLHttpRequestWorker.h
@@ -34,15 +34,16 @@ public:
uint32_t mStatus;
nsCString mStatusText;
uint16_t mReadyState;
+ bool mFlagSend;
JS::Heap<JS::Value> mResponse;
nsresult mResponseTextResult;
nsresult mStatusResult;
nsresult mResponseResult;
StateData()
- : mStatus(0), mReadyState(0), mResponse(JS::UndefinedValue()),
- mResponseTextResult(NS_OK), mStatusResult(NS_OK),
- mResponseResult(NS_OK)
+ : mStatus(0), mReadyState(0), mFlagSend(false),
+ mResponse(JS::UndefinedValue()), mResponseTextResult(NS_OK),
+ mStatusResult(NS_OK), mResponseResult(NS_OK)
{ }
void trace(JSTracer* trc);
diff --git a/dom/xhr/tests/mochitest.ini b/dom/xhr/tests/mochitest.ini
index 35ba1e3db..a2a52787a 100644
--- a/dom/xhr/tests/mochitest.ini
+++ b/dom/xhr/tests/mochitest.ini
@@ -68,13 +68,11 @@ support-files =
[test_bug1300552.html]
[test_html_in_xhr.html]
[test_relativeLoad.html]
-skip-if = buildapp == 'b2g' # b2g(Failed to load script: relativeLoad_import.js) b2g-debug(Failed to load script: relativeLoad_import.js) b2g-desktop(Failed to load script: relativeLoad_import.js)
[test_sync_xhr_timer.xhtml]
skip-if = toolkit == 'android'
[test_sync_xhr_unload.html]
[test_temporaryFileBlob.html]
[test_worker_terminateSyncXHR.html]
-skip-if = buildapp == 'b2g'
[test_worker_xhr.html]
[test_worker_xhr2.html]
[test_worker_xhr_3rdparty.html]
@@ -82,7 +80,6 @@ skip-if = buildapp == 'b2g'
[test_worker_xhr_headers.html]
[test_worker_xhr_implicit_cancel.html]
[test_worker_xhr_parameters.html]
-skip-if = buildapp == 'b2g'
[test_worker_xhr_responseURL.html]
[test_worker_xhr_system.html]
[test_worker_xhr_timeout.html]
@@ -96,17 +93,13 @@ skip-if = toolkit == 'android'
[test_XHR_header.html]
[test_XHR_onuploadprogress.html]
[test_xhr_overridemimetype_throws_on_invalid_state.html]
-skip-if = buildapp == 'b2g' # Requires webgl support
[test_XHR_parameters.html]
-skip-if = buildapp == 'b2g' # b2g(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-debug(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-desktop(86 total, 4 failing - testing mozAnon - got false, expected true)
[test_xhr_progressevents.html]
skip-if = toolkit == 'android'
[test_xhr_send.html]
[test_xhr_send_readystate.html]
[test_XHR_system.html]
-skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(12 total, 2 failing - .mozSystem == true - got false, expected true + ) b2g-desktop(12 total, 2 failing - .mozSystem == true - got false, expected true + )
[test_XHR_timeout.html]
-skip-if = buildapp == 'b2g' || (android_version == '18' && debug) # b2g(flaky on B2G, bug 960743) b2g-debug(flaky on B2G, bug 960743) b2g-desktop(flaky on B2G, bug 960743)
support-files = test_XHR_timeout.js
[test_xhr_withCredentials.html]
[test_XHRDocURI.html]