text: "use strict";
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  var Stream = require('stream');
  
  var util = require('util');
  
  var net = require('net');
  
  var tls = require('tls'); // eslint-disable-next-line node/no-deprecated-api
  
  
  var _require = require('url'),
      parse = _require.parse;
  
  var semver = require('semver');
  
  var http2;
  if (semver.gte(process.version, 'v10.10.0')) http2 = require('http2');else throw new Error('superagent: this version of Node.js does not support http2');
  var _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: function request(options) {
        return new Request(protocol, options);
      }
    };
  }
  
  function Request(protocol, options) {
    var _this = this;
  
    Stream.call(this);
    var defaultPort = protocol === 'https:' ? 443 : 80;
    var defaultHost = 'localhost';
    var port = options.port || defaultPort;
    var 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;
  
    var sessionOptions = _objectSpread({}, options);
  
    if (options.socketPath) {
      sessionOptions.socketPath = options.socketPath;
      sessionOptions.createConnection = this.createUnixConnection.bind(this);
    }
  
    this._headers = {};
    var session = http2.connect("".concat(protocol, "//").concat(host, ":").concat(port), sessionOptions);
    this.setHeader('host', "".concat(host, ":").concat(port));
    session.on('error', function (err) {
      return _this.emit('error', err);
    });
    this.session = session;
  }
  /**
   * Inherit from `Stream` (which inherits from `EventEmitter`).
   */
  
  
  util.inherits(Request, Stream);
  
  Request.prototype.createUnixConnection = function (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);
    }
  }; // eslint-disable-next-line no-unused-vars
  
  
  Request.prototype.setNoDelay = function (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
  };
  
  Request.prototype.getFrame = function () {
    var _method,
        _this2 = this;
  
    if (this.frame) {
      return this.frame;
    }
  
    var method = (_method = {}, _defineProperty(_method, HTTP2_HEADER_PATH, this.path), _defineProperty(_method, HTTP2_HEADER_METHOD, this.method), _method);
    var headers = this.mapToHttp2Header(this._headers);
    headers = Object.assign(headers, method);
    var frame = this.session.request(headers); // eslint-disable-next-line no-unused-vars
  
    frame.once('response', function (headers, flags) {
      headers = _this2.mapToHttpHeader(headers);
      frame.headers = headers;
      frame.statusCode = headers[HTTP2_HEADER_STATUS];
      frame.status = frame.statusCode;
  
      _this2.emit('response', frame);
    });
    this._headerSent = true;
    frame.once('drain', function () {
      return _this2.emit('drain');
    });
    frame.on('error', function (err) {
      return _this2.emit('error', err);
    });
    frame.on('close', function () {
      return _this2.session.close();
    });
    this.frame = frame;
    return frame;
  };
  
  Request.prototype.mapToHttpHeader = function (headers) {
    var keys = Object.keys(headers);
    var http2Headers = {};
  
    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      var 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;
  };
  
  Request.prototype.mapToHttp2Header = function (headers) {
    var keys = Object.keys(headers);
    var http2Headers = {};
  
    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      var 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;
  };
  
  Request.prototype.setHeader = function (name, value) {
    this._headers[name.toLowerCase()] = value;
  };
  
  Request.prototype.getHeader = function (name) {
    return this._headers[name.toLowerCase()];
  };
  
  Request.prototype.write = function (data, encoding) {
    var frame = this.getFrame();
    return frame.write(data, encoding);
  };
  
  Request.prototype.pipe = function (stream, options) {
    var frame = this.getFrame();
    return frame.pipe(stream, options);
  };
  
  Request.prototype.end = function (data) {
    var frame = this.getFrame();
    frame.end(data);
  }; // eslint-disable-next-line no-unused-vars
  
  
  Request.prototype.abort = function (data) {
    var frame = this.getFrame();
    frame.close(NGHTTP2_CANCEL);
    this.session.destroy();
  };
  
  exports.setProtocol = setProtocol;