Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

add support for signal request option #399

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/request/interfaces.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AbortSignal } from '@dojo/shim/AbortController';
import { IterableIterator } from '@dojo/shim/iterator';
import Task from '../async/Task';
import UrlSearchParams, { ParamList } from '../UrlSearchParams';
Expand Down Expand Up @@ -57,6 +58,10 @@ export interface RequestOptions {
* Password for HTTP authentication
*/
password?: string;
/**
* Abort signal, allowing for cancelable requests
*/
signal?: AbortSignal;
/**
* Number of milliseconds before the request times out and is canceled
*/
Expand Down
4 changes: 4 additions & 0 deletions src/request/providers/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ export default function node(url: string, options: NodeRequestOptions = {}): Upl
throw error;
});

if (options.signal) {
options.signal.addEventListener('abort', () => requestTask.cancel());
}

requestTask.upload = new Observable<number>((observer) => uploadObserverPool.add(observer));

return requestTask;
Expand Down
4 changes: 4 additions & 0 deletions src/request/providers/xhr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ export default function xhr(url: string, options: XhrRequestOptions = {}): Uploa
setOnError(request, reject);
}, abort);

if (options.signal) {
options.signal.addEventListener('abort', () => task.cancel());
}

request.open(options.method, requestUrl, !options.blockMainThread, options.user, options.password);

if (has('filereader') && has('blob')) {
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/request/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import * as zlib from 'zlib';
import { Response } from '../../../src/request/interfaces';
import { default as nodeRequest, NodeResponse } from '../../../src/request/providers/node';
import TimeoutError from '../../../src/request/TimeoutError';
import { State } from '../../../src/async/Task';
import AbortController from '@dojo/shim/AbortController';

const serverPort = 8124;
const serverUrl = 'http://localhost:' + serverPort;
Expand Down Expand Up @@ -463,6 +465,20 @@ registerSuite('request/node', {
);
},

signal(this: any) {
const dfd = this.async();
const url = getRequestUrl('foo.json');
const controller = new AbortController();
const { signal } = controller;
const request = nodeRequest(url, { signal });
request.finally(
dfd.callback(() => {
assert.strictEqual(request.state, State.Canceled);
})
);
controller.abort();
},

'user and password': {
both(this: any): void {
const user = 'user name';
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/request/xhr.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const { registerSuite } = intern.getInterface('object');
const { assert } = intern.getPlugin('chai');

import AbortController from '@dojo/shim/AbortController';
import xhrRequest, { XhrResponse } from '../../../src/request/providers/xhr';
import { Response } from '../../../src/request/interfaces';
import UrlSearchParams from '../../../src/UrlSearchParams';
import has from '../../../src/has';
import Promise from '@dojo/shim/Promise';
import { State } from '../../../src/async/Task';

let echoServerAvailable = false;
registerSuite('request/providers/xhr', {
Expand Down Expand Up @@ -94,6 +96,23 @@ registerSuite('request/providers/xhr', {
);
},

'"signal"'(this: any) {
if (!echoServerAvailable) {
this.skip('No echo server available');
}
const dfd = this.async();
const controller = new AbortController();
const { signal } = controller;
const request = xhrRequest('/__echo/foo.json', { signal, timeout: 100 });
request.finally(
dfd.callback(() => {
assert.strictEqual(request.state, State.Canceled);
})
);

controller.abort();
},

'user and password'(this: any) {
if (!echoServerAvailable) {
this.skip('No echo server available');
Expand Down