'use strict' const { test } = require('tap') const { Client, errors } = require('..') const { createServer } = require('http') const { Readable } = require('stream') const FakeTimers = require('@sinonjs/fake-timers') const timers = require('../lib/timers') test('refresh timeout on pause', (t) => { t.plan(1) const server = createServer((req, res) => { res.flushHeaders() }) t.teardown(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 500 }) t.teardown(client.destroy.bind(client)) client.dispatch({ path: '/', method: 'GET' }, { onConnect () { }, onHeaders (statusCode, headers, resume) { setTimeout(() => { resume() }, 1000) return false }, onData () { }, onComplete () { }, onError (err) { t.type(err, errors.BodyTimeoutError) } }) }) }) test('start headers timeout after request body', (t) => { t.plan(2) const clock = FakeTimers.install() t.teardown(clock.uninstall.bind(clock)) const orgTimers = { ...timers } Object.assign(timers, { setTimeout, clearTimeout }) t.teardown(() => { Object.assign(timers, orgTimers) }) const server = createServer((req, res) => { }) t.teardown(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0, headersTimeout: 100 }) t.teardown(client.destroy.bind(client)) const body = new Readable({ read () {} }) client.dispatch({ path: '/', body, method: 'GET' }, { onConnect () { process.nextTick(() => { clock.tick(200) }) queueMicrotask(() => { body.push(null) body.on('end', () => { clock.tick(200) }) }) }, onHeaders (statusCode, headers, resume) { }, onData () { }, onComplete () { }, onError (err) { t.equal(body.readableEnded, true) t.type(err, errors.HeadersTimeoutError) } }) }) }) test('start headers timeout after async iterator request body', (t) => { t.plan(1) const clock = FakeTimers.install() t.teardown(clock.uninstall.bind(clock)) const orgTimers = { ...timers } Object.assign(timers, { setTimeout, clearTimeout }) t.teardown(() => { Object.assign(timers, orgTimers) }) const server = createServer((req, res) => { }) t.teardown(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0, headersTimeout: 100 }) t.teardown(client.destroy.bind(client)) let res const body = (async function * () { await new Promise((resolve) => { res = resolve }) process.nextTick(() => { clock.tick(200) }) })() client.dispatch({ path: '/', body, method: 'GET' }, { onConnect () { process.nextTick(() => { clock.tick(200) }) queueMicrotask(() => { res() }) }, onHeaders (statusCode, headers, resume) { }, onData () { }, onComplete () { }, onError (err) { t.type(err, errors.HeadersTimeoutError) } }) }) }) test('parser resume with no body timeout', (t) => { t.plan(1) const server = createServer((req, res) => { res.end('asd') }) t.teardown(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0 }) t.teardown(client.destroy.bind(client)) client.dispatch({ path: '/', method: 'GET' }, { onConnect () { }, onHeaders (statusCode, headers, resume) { setTimeout(resume, 2000) return false }, onData () { }, onComplete () { t.pass() }, onError (err) { t.error(err) } }) }) })