|
|
@@ -1,5 +1,5 @@
|
|
|
const { expect } = require('chai')
|
|
|
-const { FetchError, AbortError } = require('node-fetch')
|
|
|
+const { FetchError } = require('node-fetch')
|
|
|
const { Readable } = require('stream')
|
|
|
const { once } = require('events')
|
|
|
const { TestServer } = require('./helpers/TestServer')
|
|
|
@@ -15,6 +15,8 @@ const {
|
|
|
CustomHttpsAgent,
|
|
|
} = require('../..')
|
|
|
|
|
|
+const AbortError = 'The user aborted a request'
|
|
|
+
|
|
|
const HTTP_PORT = 30001
|
|
|
const HTTPS_PORT = 30002
|
|
|
|
|
|
@@ -48,6 +50,10 @@ describe('fetch-utils', function () {
|
|
|
this.httpsUrl = path => `https://example.com:${HTTPS_PORT}${path}`
|
|
|
})
|
|
|
|
|
|
+ beforeEach(function () {
|
|
|
+ this.server.lastReq = undefined
|
|
|
+ })
|
|
|
+
|
|
|
after(async function () {
|
|
|
await this.server.stop()
|
|
|
})
|
|
|
@@ -135,7 +141,7 @@ describe('fetch-utils', function () {
|
|
|
await expectRequestAborted(this.server.lastReq)
|
|
|
})
|
|
|
|
|
|
- it('aborts the request when the request body is destroyed', async function () {
|
|
|
+ it('aborts the request when the request body is destroyed before transfer', async function () {
|
|
|
const stream = Readable.from(infiniteIterator())
|
|
|
const promise = fetchStream(this.url('/hang'), {
|
|
|
method: 'POST',
|
|
|
@@ -143,6 +149,20 @@ describe('fetch-utils', function () {
|
|
|
})
|
|
|
stream.destroy()
|
|
|
await expect(promise).to.be.rejectedWith(AbortError)
|
|
|
+ await wait(80)
|
|
|
+ expect(this.server.lastReq).to.be.undefined
|
|
|
+ })
|
|
|
+
|
|
|
+ it('aborts the request when the request body is destroyed during transfer', async function () {
|
|
|
+ const stream = Readable.from(infiniteIterator())
|
|
|
+ // Note: this test won't work on `/hang`
|
|
|
+ const promise = fetchStream(this.url('/sink'), {
|
|
|
+ method: 'POST',
|
|
|
+ body: stream,
|
|
|
+ })
|
|
|
+ await once(this.server.events, 'request-received')
|
|
|
+ stream.destroy()
|
|
|
+ await expect(promise).to.be.rejectedWith(AbortError)
|
|
|
await expectRequestAborted(this.server.lastReq)
|
|
|
})
|
|
|
|
|
|
@@ -164,6 +184,7 @@ describe('fetch-utils', function () {
|
|
|
const stream = Readable.from(infiniteIterator())
|
|
|
await expect(
|
|
|
fetchStream(this.url('/hang'), {
|
|
|
+ method: 'POST',
|
|
|
body: stream,
|
|
|
signal: AbortSignal.timeout(10),
|
|
|
})
|
|
|
@@ -178,7 +199,7 @@ describe('fetch-utils', function () {
|
|
|
await expectRequestAborted(this.server.lastReq)
|
|
|
})
|
|
|
|
|
|
- it('aborts the request when the request body is destroyed', async function () {
|
|
|
+ it('aborts the request when the request body is destroyed before transfer', async function () {
|
|
|
const stream = Readable.from(infiniteIterator())
|
|
|
const promise = fetchNothing(this.url('/hang'), {
|
|
|
method: 'POST',
|
|
|
@@ -186,6 +207,20 @@ describe('fetch-utils', function () {
|
|
|
})
|
|
|
stream.destroy()
|
|
|
await expect(promise).to.be.rejectedWith(AbortError)
|
|
|
+ expect(this.server.lastReq).to.be.undefined
|
|
|
+ })
|
|
|
+
|
|
|
+ it('aborts the request when the request body is destroyed during transfer', async function () {
|
|
|
+ const stream = Readable.from(infiniteIterator())
|
|
|
+ // Note: this test won't work on `/hang`
|
|
|
+ const promise = fetchNothing(this.url('/sink'), {
|
|
|
+ method: 'POST',
|
|
|
+ body: stream,
|
|
|
+ })
|
|
|
+ await once(this.server.events, 'request-received')
|
|
|
+ stream.destroy()
|
|
|
+ await expect(promise).to.be.rejectedWith(AbortError)
|
|
|
+ await wait(80)
|
|
|
await expectRequestAborted(this.server.lastReq)
|
|
|
})
|
|
|
|
|
|
@@ -212,6 +247,7 @@ describe('fetch-utils', function () {
|
|
|
const stream = Readable.from(infiniteIterator())
|
|
|
await expect(
|
|
|
fetchNothing(this.url('/hang'), {
|
|
|
+ method: 'POST',
|
|
|
body: stream,
|
|
|
signal: AbortSignal.timeout(10),
|
|
|
})
|
|
|
@@ -331,7 +367,14 @@ async function* infiniteIterator() {
|
|
|
|
|
|
async function expectRequestAborted(req) {
|
|
|
if (!req.destroyed) {
|
|
|
- await once(req, 'close')
|
|
|
+ try {
|
|
|
+ await once(req, 'close')
|
|
|
+ } catch (err) {
|
|
|
+ // `once` throws if req emits an 'error' event
|
|
|
+ // For example, with `Error: aborted` when the request is aborted.
|
|
|
+ }
|
|
|
expect(req.destroyed).to.be.true
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
|