UNPKG

jii

Version:

Jii - Full-Stack JavaScript Framework

299 lines (261 loc) 9.84 kB
/** * @author <a href="http://www.affka.ru">Vladimir Kozhin</a> * @license MIT */ 'use strict'; const Jii = require('../../index'); const InvalidConfigException = require('../../exceptions/InvalidConfigException'); const _trimStart = require('lodash/trimStart'); const _isEmpty = require('lodash/isEmpty'); const _each = require('lodash/each'); const _values = require('lodash/values'); const HttpRequest = require('../../base/HttpRequest'); class Request extends HttpRequest { preInit(httpMessage) { this._referrer = null; this._languages = null; this._contentTypes = null; this._securePort = null; this._serverName = null; this._cookies = null; this._url = null; this._queryString = null; this._bodyParams = null; if (!httpMessage.method) { throw new InvalidConfigException('Not found param `method` in http message.'); } if (!httpMessage.headers) { throw new InvalidConfigException('Not found `headers` in http message.'); } this._httpMessage = httpMessage; super.preInit(); } /** * Returns the method of the current request (e.g. GET, POST, HEAD, PUT, PATCH, DELETE). * @return {string} */ getMethod() { return this._httpMessage.method; } /** * Returns whether this is an AJAX (XMLHttpRequest) request. * @return boolean whether this is an AJAX (XMLHttpRequest) request. */ isAjax() { var xhr = this._httpMessage.headers['X-Requested-With'] || ''; return xhr.toLowerCase() === 'xmlhttprequest'; } /** * Returns whether this is an Adobe Flash or Flex request. * @return boolean whether this is an Adobe Flash or Adobe Flex request. */ isFlash() { var userAgent = this._httpMessage.headers['user-agent'] || ''; return userAgent && (userAgent.indexOf('Shockwave') !== -1 || userAgent.indexOf('Flash') !== -1); } /** * Returns the request parameters given in the request body. * * Request parameters are determined using the parsers configured in [[parsers]] property. * @return {object} the request parameters given in the request body. */ getBodyParams() { if (this._bodyParams === null) { // @todo Change this code, when delete express this._bodyParams = this._httpMessage.body || {}; } return this._bodyParams; } /** * Sets the request body parameters. * @param {object} values the request body parameters (name-value pairs) */ setBodyParams(values) { this._bodyParams = values; } /** * Returns the currently requested absolute URL. * This is a shortcut to the concatenation of [[hostInfo]] and [[url]]. * @return {string} The currently requested absolute URL. */ getAbsoluteUrl() { return this.getHostInfo() + this.getUrl(); } /** * Returns the currently requested relative URL. * This refers to the portion of the URL that is after the [[hostInfo]] part. * It includes the [[queryString]] part if any. * @return {string} The currently requested relative URL. Note that the URI returned is URL-encoded. */ getUrl() { if (this._url === null) { this._url = this._httpMessage.url; } return this._url; } /** * Sets the currently requested relative URL. * The URI must refer to the portion that is after [[hostInfo]]. * Note that the URI should be URL-encoded. * @param {string} value The request URI to be set */ setUrl(value) { this._url = _trimStart(value, '/'); } /** * Returns part of the request URL that is after the question mark. * @return {string} Part of the request URL that is after the question mark */ getQueryString() { if (this._queryString === null) { this._queryString = this._httpMessage._parsedUrl.query; } return this._queryString; } /** * Returns the server name. * @return {string} Server name */ getServerName() { if (this._serverName === null) { this._serverName = this._httpMessage.headers.host.replace(/:[0-9]+$/, ''); } return this._serverName; } /** * Returns the URL referrer, null if not present * @return string URL referrer, null if not present */ getReferrer() { if (this._referrer === null) { var headers = this.getHeaders(); this._referrer = headers.get('referrer') || headers.get('referer') || null; } return this._referrer; } /** * Returns the user agent, null if not present. * @return string user agent, null if not present */ getUserAgent() { return this._httpMessage.headers['user-agent']; } /** * Returns the user IP address. * @return string user IP address */ getUserIP() { return this._httpMessage.headers['x-real-ip'] || this._httpMessage.remoteAddress || null; } /** * Returns the user host name, null if it cannot be determined. * @return string user host name, null if cannot be determined */ getUserHost() { // @todo return this.getUserIP(); } getContentType() { // @todo return null; } /** * Returns the content types accepted by the end user. * This is determined by the `Accept` HTTP header. * @return {array} The content types ordered by the preference level. The first element * represents the most preferred content type. */ getAcceptableContentTypes() { if (this._contentTypes === null) { var acceptHeader = this._httpMessage.headers.accept; this._contentTypes = acceptHeader ? this._parseAcceptHeader(acceptHeader) : []; } return this._contentTypes; } /** * @param {array} value The content types that are accepted by the end user. They should * be ordered by the preference level. */ setAcceptableContentTypes(value) { this._contentTypes = value; } /** * Returns the languages accepted by the end user. * This is determined by the `Accept-Language` HTTP header. * @return {array} The languages ordered by the preference level. The first element * represents the most preferred language. */ getAcceptableLanguages() { if (this._languages === null) { if (this._httpMessage.accept) { this._languages = this._parseAcceptHeader(this._httpMessage.accept); } this._languages = []; } return this._languages; } /** * @param {array} value The languages that are accepted by the end user. They should * be ordered by the preference level. */ setAcceptableLanguages(value) { this._languages = value; } /** * Returns the user-preferred language that should be used by this application. * The language resolution is based on the user preferred languages and the languages * supported by the application. The method will try to find the best match. * @param {object} languages A list of the languages supported by the application. * If empty, this method will return the first language returned by [[getAcceptableLanguages()]]. * @return {string} The language that the application should use. Null is returned if both [[getAcceptableLanguages()]] * and `languages` are empty. */ getPreferredLanguage(languages) { var acceptedLanguages = this.getAcceptableLanguages(); var finedLanguage = null; if (_isEmpty(languages)) { return acceptedLanguages.length > 0 ? acceptedLanguages[0] : null; } _each(acceptedLanguages, acceptedLanguage => { acceptedLanguage = acceptedLanguage.replace('_', '-').toLowerCase(); _each(languages, language => { language = language.replace('_', '-').toLowerCase(); // en-us==en-us, en==en-us, en-us==en if (language === acceptedLanguage || acceptedLanguage.indexOf(language + '-') === 0 || language.indexOf(acceptedLanguage + '-') === 0) { finedLanguage = language; return false; } }); }); return finedLanguage || _values(languages)[0]; } getCookies() { if (this._cookies === null) { this._cookies = this._httpMessage.cookies || {}; } return this._cookies; } _parseParams() { // @todo Change this code, when delete express return this._httpMessage.query; } /** * Parses the given `Accept` (or `Accept-Language`) header. * This method will return the accepted values ordered by their preference level. * @param {string} header The header to be parsed * @return {array} The accept values ordered by their preference level. */ _parseAcceptHeader(header) { } _parseHeaders() { return this._httpMessage.headers; } _parseHostInfo() { var http = this.isSecureConnection() ? 'https' : 'http'; return http + '://' + this._httpMessage.headers.host; } _parsePathInfo() { return _trimStart(this._httpMessage._parsedUrl.pathname, '/'); } } module.exports = Request;