Skip to content
Permalink
ffd96b38fb
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Robert Brignull replace jest with ava
Latest commit 0347b72 May 4, 2020 History
0 contributors

Users who have contributed to this file

93 lines (72 sloc) 2.26 KB
'use strict';
const {PassThrough} = require('stream');
const duplexer3 = require('duplexer3');
const requestAsEventEmitter = require('./request-as-event-emitter');
const {HTTPError, ReadError} = require('./errors');
module.exports = options => {
const input = new PassThrough();
const output = new PassThrough();
const proxy = duplexer3(input, output);
const piped = new Set();
let isFinished = false;
options.retry.retries = () => 0;
if (options.body) {
proxy.write = () => {
throw new Error('Got\'s stream is not writable when the `body` option is used');
};
}
const emitter = requestAsEventEmitter(options, input);
// Cancels the request
proxy._destroy = emitter.abort;
emitter.on('response', response => {
const {statusCode} = response;
response.on('error', error => {
proxy.emit('error', new ReadError(error, options));
});
if (options.throwHttpErrors && statusCode !== 304 && (statusCode < 200 || statusCode > 299)) {
proxy.emit('error', new HTTPError(response, options), null, response);
return;
}
isFinished = true;
response.pipe(output);
for (const destination of piped) {
if (destination.headersSent) {
continue;
}
for (const [key, value] of Object.entries(response.headers)) {
// Got gives *decompressed* data. Overriding `content-encoding` header would result in an error.
// It's not possible to decompress already decompressed data, is it?
const allowed = options.decompress ? key !== 'content-encoding' : true;
if (allowed) {
destination.setHeader(key, value);
}
}
destination.statusCode = response.statusCode;
}
proxy.emit('response', response);
});
[
'error',
'request',
'redirect',
'uploadProgress',
'downloadProgress'
].forEach(event => emitter.on(event, (...args) => proxy.emit(event, ...args)));
const pipe = proxy.pipe.bind(proxy);
const unpipe = proxy.unpipe.bind(proxy);
proxy.pipe = (destination, options) => {
if (isFinished) {
throw new Error('Failed to pipe. The response has been emitted already.');
}
const result = pipe(destination, options);
if (Reflect.has(destination, 'setHeader')) {
piped.add(destination);
}
return result;
};
proxy.unpipe = stream => {
piped.delete(stream);
return unpipe(stream);
};
return proxy;
};