164 lines
22 KiB
JavaScript
164 lines
22 KiB
JavaScript
|
|
"use strict";
|
||
|
|
|
||
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
||
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
||
|
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||
|
|
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
||
|
|
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
||
|
|
const Stream = require('stream');
|
||
|
|
const net = require('net');
|
||
|
|
const tls = require('tls');
|
||
|
|
// eslint-disable-next-line node/no-deprecated-api
|
||
|
|
const _require = require('url'),
|
||
|
|
parse = _require.parse;
|
||
|
|
const process = require('process');
|
||
|
|
const semverGte = require('semver/functions/gte');
|
||
|
|
let http2;
|
||
|
|
if (semverGte(process.version, 'v10.10.0')) http2 = require('http2');else throw new Error('superagent: this version of Node.js does not support http2');
|
||
|
|
const _http2$constants = http2.constants,
|
||
|
|
HTTP2_HEADER_PATH = _http2$constants.HTTP2_HEADER_PATH,
|
||
|
|
HTTP2_HEADER_STATUS = _http2$constants.HTTP2_HEADER_STATUS,
|
||
|
|
HTTP2_HEADER_METHOD = _http2$constants.HTTP2_HEADER_METHOD,
|
||
|
|
HTTP2_HEADER_AUTHORITY = _http2$constants.HTTP2_HEADER_AUTHORITY,
|
||
|
|
HTTP2_HEADER_HOST = _http2$constants.HTTP2_HEADER_HOST,
|
||
|
|
HTTP2_HEADER_SET_COOKIE = _http2$constants.HTTP2_HEADER_SET_COOKIE,
|
||
|
|
NGHTTP2_CANCEL = _http2$constants.NGHTTP2_CANCEL;
|
||
|
|
function setProtocol(protocol) {
|
||
|
|
return {
|
||
|
|
request(options) {
|
||
|
|
return new Request(protocol, options);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
class Request extends Stream {
|
||
|
|
constructor(protocol, options) {
|
||
|
|
super();
|
||
|
|
const defaultPort = protocol === 'https:' ? 443 : 80;
|
||
|
|
const defaultHost = 'localhost';
|
||
|
|
const port = options.port || defaultPort;
|
||
|
|
const host = options.host || defaultHost;
|
||
|
|
delete options.port;
|
||
|
|
delete options.host;
|
||
|
|
this.method = options.method;
|
||
|
|
this.path = options.path;
|
||
|
|
this.protocol = protocol;
|
||
|
|
this.host = host;
|
||
|
|
delete options.method;
|
||
|
|
delete options.path;
|
||
|
|
const sessionOptions = _objectSpread({}, options);
|
||
|
|
if (options.socketPath) {
|
||
|
|
sessionOptions.socketPath = options.socketPath;
|
||
|
|
sessionOptions.createConnection = this.createUnixConnection.bind(this);
|
||
|
|
}
|
||
|
|
this._headers = {};
|
||
|
|
const session = http2.connect(`${protocol}//${host}:${port}`, sessionOptions);
|
||
|
|
this.setHeader('host', `${host}:${port}`);
|
||
|
|
session.on('error', error => this.emit('error', error));
|
||
|
|
this.session = session;
|
||
|
|
}
|
||
|
|
createUnixConnection(authority, options) {
|
||
|
|
switch (this.protocol) {
|
||
|
|
case 'http:':
|
||
|
|
return net.connect(options.socketPath);
|
||
|
|
case 'https:':
|
||
|
|
options.ALPNProtocols = ['h2'];
|
||
|
|
options.servername = this.host;
|
||
|
|
options.allowHalfOpen = true;
|
||
|
|
return tls.connect(options.socketPath, options);
|
||
|
|
default:
|
||
|
|
throw new Error('Unsupported protocol', this.protocol);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
setNoDelay(bool) {
|
||
|
|
// We can not use setNoDelay with HTTP/2.
|
||
|
|
// Node 10 limits http2session.socket methods to ones safe to use with HTTP/2.
|
||
|
|
// See also https://nodejs.org/api/http2.html#http2_http2session_socket
|
||
|
|
}
|
||
|
|
getFrame() {
|
||
|
|
if (this.frame) {
|
||
|
|
return this.frame;
|
||
|
|
}
|
||
|
|
const method = {
|
||
|
|
[HTTP2_HEADER_PATH]: this.path,
|
||
|
|
[HTTP2_HEADER_METHOD]: this.method
|
||
|
|
};
|
||
|
|
let headers = this.mapToHttp2Header(this._headers);
|
||
|
|
headers = Object.assign(headers, method);
|
||
|
|
const frame = this.session.request(headers);
|
||
|
|
frame.once('response', (headers, flags) => {
|
||
|
|
headers = this.mapToHttpHeader(headers);
|
||
|
|
frame.headers = headers;
|
||
|
|
frame.statusCode = headers[HTTP2_HEADER_STATUS];
|
||
|
|
frame.status = frame.statusCode;
|
||
|
|
this.emit('response', frame);
|
||
|
|
});
|
||
|
|
this._headerSent = true;
|
||
|
|
frame.once('drain', () => this.emit('drain'));
|
||
|
|
frame.on('error', error => this.emit('error', error));
|
||
|
|
frame.on('close', () => this.session.close());
|
||
|
|
this.frame = frame;
|
||
|
|
return frame;
|
||
|
|
}
|
||
|
|
mapToHttpHeader(headers) {
|
||
|
|
const keys = Object.keys(headers);
|
||
|
|
const http2Headers = {};
|
||
|
|
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
|
||
|
|
let key = _keys[_i];
|
||
|
|
let value = headers[key];
|
||
|
|
key = key.toLowerCase();
|
||
|
|
switch (key) {
|
||
|
|
case HTTP2_HEADER_SET_COOKIE:
|
||
|
|
value = Array.isArray(value) ? value : [value];
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
http2Headers[key] = value;
|
||
|
|
}
|
||
|
|
return http2Headers;
|
||
|
|
}
|
||
|
|
mapToHttp2Header(headers) {
|
||
|
|
const keys = Object.keys(headers);
|
||
|
|
const http2Headers = {};
|
||
|
|
for (var _i2 = 0, _keys2 = keys; _i2 < _keys2.length; _i2++) {
|
||
|
|
let key = _keys2[_i2];
|
||
|
|
let value = headers[key];
|
||
|
|
key = key.toLowerCase();
|
||
|
|
switch (key) {
|
||
|
|
case HTTP2_HEADER_HOST:
|
||
|
|
key = HTTP2_HEADER_AUTHORITY;
|
||
|
|
value = /^http:\/\/|^https:\/\//.test(value) ? parse(value).host : value;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
http2Headers[key] = value;
|
||
|
|
}
|
||
|
|
return http2Headers;
|
||
|
|
}
|
||
|
|
setHeader(name, value) {
|
||
|
|
this._headers[name.toLowerCase()] = value;
|
||
|
|
}
|
||
|
|
getHeader(name) {
|
||
|
|
return this._headers[name.toLowerCase()];
|
||
|
|
}
|
||
|
|
write(data, encoding) {
|
||
|
|
const frame = this.getFrame();
|
||
|
|
return frame.write(data, encoding);
|
||
|
|
}
|
||
|
|
pipe(stream, options) {
|
||
|
|
const frame = this.getFrame();
|
||
|
|
return frame.pipe(stream, options);
|
||
|
|
}
|
||
|
|
end(data) {
|
||
|
|
const frame = this.getFrame();
|
||
|
|
frame.end(data);
|
||
|
|
}
|
||
|
|
abort(data) {
|
||
|
|
const frame = this.getFrame();
|
||
|
|
frame.close(NGHTTP2_CANCEL);
|
||
|
|
this.session.destroy();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
exports.setProtocol = setProtocol;
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJTdHJlYW0iLCJyZXF1aXJlIiwibmV0IiwidGxzIiwiX3JlcXVpcmUiLCJwYXJzZSIsInByb2Nlc3MiLCJzZW12ZXJHdGUiLCJodHRwMiIsInZlcnNpb24iLCJFcnJvciIsIl9odHRwMiRjb25zdGFudHMiLCJjb25zdGFudHMiLCJIVFRQMl9IRUFERVJfUEFUSCIsIkhUVFAyX0hFQURFUl9TVEFUVVMiLCJIVFRQMl9IRUFERVJfTUVUSE9EIiwiSFRUUDJfSEVBREVSX0FVVEhPUklUWSIsIkhUVFAyX0hFQURFUl9IT1NUIiwiSFRUUDJfSEVBREVSX1NFVF9DT09LSUUiLCJOR0hUVFAyX0NBTkNFTCIsInNldFByb3RvY29sIiwicHJvdG9jb2wiLCJyZXF1ZXN0Iiwib3B0aW9ucyIsIlJlcXVlc3QiLCJjb25zdHJ1Y3RvciIsImRlZmF1bHRQb3J0IiwiZGVmYXVsdEhvc3QiLCJwb3J0IiwiaG9zdCIsIm1ldGhvZCIsInBhdGgiLCJzZXNzaW9uT3B0aW9ucyIsIl9vYmplY3RTcHJlYWQiLCJzb2NrZXRQYXRoIiwiY3JlYXRlQ29ubmVjdGlvbiIsImNyZWF0ZVVuaXhDb25uZWN0aW9uIiwiYmluZCIsIl9oZWFkZXJzIiwic2Vzc2lvbiIsImNvbm5lY3QiLCJzZXRIZWFkZXIiLCJvbiIsImVycm9yIiwiZW1pdCIsImF1dGhvcml0eSIsIkFMUE5Qcm90b2NvbHMiLCJzZXJ2ZXJuYW1lIiwiYWxsb3dIYWxmT3BlbiIsInNldE5vRGVsYXkiLCJib29sIiwiZ2V0RnJhbWUiLCJmcmFtZSIsImhlYWRlcnMiLCJtYXBUb0h0dHAySGVhZGVyIiwiT2JqZWN0IiwiYXNzaWduIiwib25jZSIsImZsYWdzIiwibWFwVG9IdHRwSGVhZGVyIiwic3RhdHVzQ29kZSIsInN0YXR1cyIsIl9oZWFkZXJTZW50IiwiY2xvc2UiLCJrZXlzIiwiaHR0cDJIZWFkZXJzIiwiX2kiLCJfa2V5cyIsImxlbmd0aCIsImtleSIsInZhbHVlIiwidG9Mb3dlckNhc2UiLCJBcnJheSIsImlzQXJyYXkiLCJfaTIiLCJfa2V5czIiLCJ0ZXN0IiwibmFtZSIsImdldEhlYWRlciIsIndyaXRlIiwiZGF0YSIsImVuY29kaW5nIiwicGlwZSIsInN0cmVhbSIsImVuZCIsImFib3J0IiwiZGVzdHJveSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbm9kZS9odHRwMndyYXBwZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG5jb25zdCBuZXQgPSByZXF1aXJlKCduZXQnKTtcbmNvbnN0IHRscyA9IHJlcXVpcmUoJ3RscycpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vZGUvbm8tZGVwcmVjYXRlZC1hcGlcbmNvbnN0IHsgcGFyc2UgfSA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcHJvY2VzcyA9IHJlcXVpcmUoJ3Byb2Nlc3MnKTtcbmNvbnN0IHNlbXZlckd0ZSA9IHJlcXVpcmUoJ3NlbXZlci9mdW5jdGlvbnMvZ3RlJyk7XG5cbmxldCBodHRwMjtcblxuaWYgKHNlbXZlckd0ZShwcm9jZXNzLnZlcnNpb24sICd2MTAuMTAuMCcpKSBodHRwMiA9IHJlcXVpcmUoJ2h0dHAyJyk7XG5lbHNlXG4gIHRocm93IG5ldyBFcnJvcignc3VwZXJhZ2VudDogdGhpcyB2ZXJzaW9uIG9mIE5vZGUuanMgZG9lcyBub3Qgc3VwcG9ydCBodHRwMicpO1xuXG5jb25zdCB7XG4gIEhUVFAyX0hFQURFUl9QQVRILFxuICBIVFRQMl9IRUFERVJfU1RBVFVTLFxuICBIVFRQMl9IRUFERVJfTUVUSE9ELFxuICBIVFRQMl9IRUFERVJfQVVUSE9SSVRZLFxuICBIVFRQMl9IRUFERVJfSE9TVCxcbiAgSFRUUDJfSEVBREVSX1NFVF9DT09LSUUsXG4gIE5HSFRUUDJfQ0FOQ0VMXG59ID0gaHR0cDIuY29uc3RhbnRzO1xuXG5mdW5jdGlvbiBzZXRQcm90b2NvbChwcm90b2NvbCkge1xuICByZXR1cm4ge1xuICAgIHJlcXVlc3Qob3B0aW9ucykge1xuICAgICAgcmV0dXJuIG5ldyBSZXF1ZXN0KHByb3RvY29sLCBvcHRpb25zKTtcbiAgICB9XG4gIH07XG59XG5cbmNsYXNzIFJlcXVlc3QgZXh0ZW5kcyBTdHJlYW0ge1xuICBjb25zdHJ1Y3Rvcihwcm90b2NvbCwgb3B0aW9ucykge1xuICAgIHN1cGVyKCk7XG4gICAgY29uc3QgZGVmYXVsdFBvcnQgPSBwcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MDtcbiAgICBjb25zdCBkZWZhdWx0SG9zdCA9ICdsb2NhbGhvc3QnO1xuICAgIGNvbnN0IHBvcnQgPSBvcHRpb25zLnBvcnQgfHwgZGVmYXVsdFBvcnQ7XG4gICAgY29uc3QgaG9zdCA9IG9wdGlvbnMuaG9zdCB8fCBkZWZhdWx0SG9zdDtcblxuICAgIGRlbGV0ZSBvcHRpb25zLnBvcnQ7XG4gICAgZGVsZXRlIG9wdGlvbnMuaG9zdDtcblxuICAgIHRoaXMubWV0aG9kID0gb3B0aW9ucy5tZXRob2Q7XG4gICAgdGhpcy5wYXRoID0gb3B0aW9ucy5wYXRoO1xuICAgIHRoaXMucHJvdG9jb2wgPSBwcm90b2NvbDtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuXG4gICAgZGVsZXRlIG9wdGlvbnMubWV0aG9kO1xuICAgIGRlbGV0ZSBvcHRpb25zLnBhdGg7XG5cbiAgICBjb25zdCBzZXNzaW9uT3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9O1xuICAgIGlmIChvcHRpb25zLnNvY2tldFBhdGgpIHtcbiAgICAgIHNlc3Npb25PcHRpb25zLnNvY2tldFBhdGggPSBvcHRpb25zLnNvY2tldFBhdGg7XG4gICAgICBzZXNzaW9uT3B0aW9ucy5jcmVhdGVDb25uZWN0aW9uID0gdGhpcy5jcmVhdGVVbml4Q29ubmVjdGlvbi5iaW5kKHRoaXMpO1xuICAgIH1cblxuICAgIHRoaXMuX2hlYWRlcnMgPSB7fTtcblxuICAgIGNvbnN0IHNlc3Npb24gPSBodHRwMi5jb25uZWN0KFxuICAgICAgYCR7cHJvdG9jb2x9Ly8ke2hvc3R9OiR7cG9ydH1gLFxuICAgICAgc2Vzc2lvbk9wdGlvbnNcbiAgICApO1xuICAgIHRoaXMuc2V0SGVhZGVyKCdob3N0JywgYCR7aG9zdH06JHtwb3J0fWApO1xuXG4gICAgc2Vzc2lvbi5vbignZXJyb3InLCAoZXJyb3IpID0+IHRoaXMuZW1pdCgnZXJyb3InLCBlcnJvcikpO1xuXG4gICAgdGhpcy5zZXNzaW9uID0gc2Vzc2lvbjtcbiAgfVxuXG4gIGNyZWF0ZVVuaXhDb25uZWN0aW9uKGF1dGhvcml0eSwgb3B0aW9ucykge1xuICAgIHN3aXRjaCAodGhpcy5wcm90b2NvbCkge1xuICAgICAgY2FzZSAnaHR0cDonOlxuICAgICAgICByZXR1cm4gbmV0LmNvbm5lY3Qob3B0aW9ucy5zb2NrZXRQYXRoKTtcbiAgICAgIGNhc2U
|