floodesh-lib
Version:
core library for floodesh, which contains core request, response and context class, also used for flowesh
325 lines (274 loc) • 5.69 kB
JavaScript
'use strict';
/**
* Module dependencies.
*/
const contentType = require('content-type');
const qs = require('querystring');
const typeis = require('type-is');
/**
* Prototype.
*/
module.exports = {
/**
* Return request header.
*
* @return {Object}
* @api public
*/
get header() {
return this.headers;
},
/**
* Return request header, alias as request.header
*
* @return {Object}
* @api public
*/
get headers() {
return this.req._headers;
},
/**
* Get request URL.
*
* @return {String}
* @api public
*/
get url() {
return this.href;
},
/**
* Get origin of URL.
*
* @return {String}
* @api public
*/
get origin() {
return `${this.protocol}//${this.host}`;
},
/**
* Get full request URL.
*
* @return {String}
* @api public
*/
get href() {
return this.req.uri.href;
},
/**
* Get request method.
*
* @return {String}
* @api public
*/
get method() {
return this.req.method;
},
/**
* Get request pathname.
*
* @return {String}
* @api public
*/
get path() {
return this.req.uri.pathname;
},
/**
* Get parsed query-string.
*
* @return {Object}
* @api public
*/
get query() {
const str = this.querystring;
const c = this._querycache = this._querycache || {};
return c[str] || (c[str] = qs.parse(str));
},
/**
* Get query string.
*
* @return {String}
* @api public
*/
get querystring() {
if (!this.req) return '';
return this.req.uri.query || '';
},
/**
* Get the search string. Same as the querystring
* except it includes the leading ?.
*
* @return {String}
* @api public
*/
get search() {
if (!this.querystring) return '';
return `?${this.querystring}`;
},
/**
* Parse the "Host" header field host
*
* @return {String} hostname:port
* @api public
*/
get host() {
return this.req.uri.host;
},
/**
* Parse the "Host" header field hostname
* and support X-Forwarded-Host when a
* proxy is enabled.
*
* @return {String} hostname
* @api public
*/
get hostname() {
return this.req.uri.hostname;
},
/**
* Check if the request is idempotent.
*
* @return {Boolean}
* @api public
*/
get idempotent() {
const methods = ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'];
return !!~methods.indexOf(this.method);
},
/**
* Get the charset when present or undefined.
*
* @return {String}
* @api public
*/
get charset() {
const type = this.get('Content-Type');
if (!type) return '';
return contentType.parse(type).parameters.charset || '';
},
/**
* Return parsed Content-Length when present.
*
* @return {Number}
* @api public
*/
get length() {
const len = this.get('Content-Length');
if (len == '') return;
return ~~len;
},
/**
* Return the protocol string "http:" or "https:"
*
* @return {String}
* @api public
*/
get protocol() {
return this.req.uri.protocol;
},
/**
* Short-hand for:
*
* this.protocol == 'https'
*
* @return {Boolean}
* @api public
*/
get secure() {
return 'https' == this.protocol;
},
/**
* Check if the incoming request contains the "Content-Type"
* header field, and it contains any of the give mime `type`s.
* If there is no request body, `null` is returned.
* If there is no content type, `false` is returned.
* Otherwise, it returns the first `type` that matches.
*
* Examples:
*
* // With Content-Type: text/html; charset=utf-8
* this.is('html'); // => 'html'
* this.is('text/html'); // => 'text/html'
* this.is('text/*', 'application/json'); // => 'text/html'
*
* // When Content-Type is application/json
* this.is('json', 'urlencoded'); // => 'json'
* this.is('application/json'); // => 'application/json'
* this.is('html', 'application/*'); // => 'application/json'
*
* this.is('html'); // => false
*
* @param {String|Array} types...
* @return {String|false|null}
* @api public
*/
is(types) {
if (!types) return typeis(this.req);
if (!Array.isArray(types)) types = [].slice.call(arguments);
return typeis(this.req, types);
},
/**
* Return the request mime type void of
* parameters such as "charset".
*
* @return {String}
* @api public
*/
get type() {
const type = this.get('Content-Type');
if (!type) return '';
return type.split(';')[0];
},
/**
* Return request header.
*
* The `Referrer` header field is special-cased,
* both `Referrer` and `Referer` are interchangeable.
*
* Examples:
*
* this.get('Content-Type');
* // => "text/plain"
*
* this.get('content-type');
* // => "text/plain"
*
* this.get('Something');
* // => undefined
*
* @param {String} field
* @return {String}
* @api public
*/
get(field) {
switch (field = field.toLowerCase()) {
case 'referer':
case 'referrer':
return this.headers.referrer || this.headers.referer || '';
default:
return this.headers[field] || '';
}
},
/**
* Inspect implementation.
*
* @return {Object}
* @api public
*/
inspect() {
if (!this.req) return;
return this.toJSON();
},
/**
* Return JSON representation.
*
* @return {Object}
* @api public
*/
toJSON() {
return {
method: this.method,
url: this.url,
header: this.header
};
}
};