Source: lib/server/request.js

/*jshint laxcomma: true, smarttabs: true, node:true, esnext:true*/
'use strict';
/**
 * Simple wrapper around the http request object to avoid deopts
 * @module skyring/lib/server/request
 * @author Eric Satterwhite
 * @since 1.0.0
 * @requires url
 * @requires querystring
 */

const {Url} = require('url')
    , qs = require('querystring')
    , cache = new WeakMap()
    , pathexp = /^(\/\/?(?!\/)[^\?#\s]*)(\?[^#\s]*)?$/
    ;

/**
 * @constructor
 * @alias skyring/lib/server/request
 * @param {IncommingMessage} req An {@link https://nodejs.org/api/http.html#http_class_http_incomingmessage|IncomingMessage}
 * from the node http module
 */
function Request(req) {

  this.query   = Object.create(null);
  this.path    = null;
  this._body   = false;
  this.body    = null;
  this.timers  = null;
  this.res     = null;
  this.headers = req.headers;

  const parsed = parseurl(req);
  if (parsed) {
    this.query = parsed.query;
    this.path = parsed.pathname;
  }
}
/**
 * Returns the value of a header, if it exists
 * @param {String} header The name of the header to lookup
 * @returns {String} The request header, if set
 */
Request.prototype.get = function get( key ) {
  const _key = key.toLowerCase();
  const headers = this.headers || {};
  switch (_key) {
    case 'referrer':
    case 'referer':
      return headers.referrer || headers.referer;
    default:
      return headers[_key];
  }
};

function parseurl( req ) {
  const url = req.url;
  if (!url) return url;

  if ( cache.has(req) ) return cache.get(req);
  const parsed = fastparse(url);
  cache.set(req, parsed);
  return parsed;
}

function fastparse( str ) {
  const simple = typeof str === 'string' && pathexp.exec( str );

  if ( simple ) {
    const pathname = simple[1];
    const search = simple[2] || null;
    const url = new Url();
    url.path = str;
    url.href = str;
    url.pathname = pathname;
    url.search = search;
    url.query = url.search ? qs.parse( search.substr( 1 ) ) : Object.create(null);
    return url;
  }

  return parseurl( str, true );
}

module.exports = Request;