jsOMS/Uri/HttpUri.js
Dennis Eichhorn 7b75ec58f7
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CI / general_module_workflow_js (push) Has been cancelled
fix permissions
2025-04-02 14:15:07 +00:00

356 lines
7.1 KiB
JavaScript

import { jsOMS } from '../Utils/oLib.js';
/**
* Http Uri.
*
* This class is for creating, modifying and analyzing http uris.
*
* @copyright Dennis Eichhorn
* @license OMS License 2.2
* @version 1.0.0
* @since 1.0.0
*/
export class HttpUri
{
/**
* @constructor
*
* @param {string} uri Http uri
*
* @since 1.0.0
*/
constructor (uri)
{
/** @type {string} uri */
this.uri = '';
/** @type {string} scheme */
this.scheme = '';
/** @type {string} host */
this.host = '';
/** @type {string} port */
this.port = '';
/** @type {string} user */
this.user = '';
/** @type {string} pass */
this.pass = '';
/** @type {null|Object} query */
this.query = null;
/** @type {null|string} queryString */
this.queryString = '';
/** @type {string} fragment */
this.fragment = '';
/** @type {string} base */
this.base = '';
/** @type {string} root */
this.root = '/';
this.set(uri);
};
/**
* Parse uri
*
* @param {string} str Url to parse
* @param {string} [mode] Parsing mode
*
* @return {Object}
*
* @throws {Error}
*
* @todo The default parser fails for uris which have a query without a value but a fragment e.g. ?debug#something.
* In such a case something#something is returned as fragment instead of just #something or something
*
* @since 1.0.0
*/
static parseUrl (str, mode = 'php')
{
const key = [
'source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port',
'relative', 'path', 'directory', 'file', 'query', 'fragment'
];
/* eslint-disable max-len */
const parser = {
php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
};
/* eslint-enable max-len */
if (!Object.prototype.hasOwnProperty.call(parser, mode)) {
throw new Error('Unexpected parsing mode.', 'UriFactory', 52);
}
const m = parser[mode].exec(str);
const uri = {};
let i = 14;
while (--i) {
if (m[i]) {
uri[key[i]] = m[i];
}
}
delete uri.source;
return uri;
};
/**
* Get Uri query parameters.
*
* @param {string} query Uri query
* @param {string} name Name of the query to return
*
* @return {string}
*
* @since 1.0.0
*/
static getUriQueryParameter (query, name)
{
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp('[\\?&]*' + name + '=([^&#]*)');
const results = regex.exec(query);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};
/**
* Get all uri query parameters.
*
* @param {string} query Uri query
*
* @return {Object}
*
* @since 1.0.0
*/
static getAllUriQueryParameters (query)
{
const params = {};
let keyValPairs = [];
let pairNum = null;
if (query.length) {
keyValPairs = query.split('&');
for (pairNum in keyValPairs) {
if (!Object.prototype.hasOwnProperty.call(keyValPairs, pairNum)) {
continue;
}
const key = keyValPairs[pairNum].split('=')[0];
if (!key.length) {
continue;
}
if (typeof params[key] === 'undefined') {
params[key] = [];
}
params[key].push(keyValPairs[pairNum].split('=')[1]);
}
}
return params;
};
/**
* Set uri.
*
* @param {string} uri Uri string
*
* @return {void}
*
* @since 1.0.0
*/
set (uri)
{
this.uri = uri;
const parsed = HttpUri.parseUrl(this.uri, 'php');
this.scheme = parsed.scheme;
this.host = parsed.host;
this.port = parsed.port;
this.user = parsed.user;
this.pass = parsed.pass;
this.path = parsed.path;
if (this.path.endsWith('.php')) {
this.path = this.path.substr(0, -4);
}
this.queryString = typeof parsed.query !== 'undefined' ? parsed.query : [];
if (this.queryString !== null) {
this.query = HttpUri.getAllUriQueryParameters(this.queryString);
}
this.fragment = typeof parsed.fragment !== 'undefined' ? parsed.fragment : '';
this.base = this.scheme + '://' + this.host + this.root;
};
/**
* Set root path.
*
* @param {string} rootPath Uri root path
*
* @return {void}
*
* @since 1.0.0
*/
setRootPath (rootPath)
{
this.root = rootPath;
this.set(this.uri);
};
getRootPath ()
{
return this.root;
}
/**
* Get Uri base
*
* @return {string}
*
* @since 1.0.0
*/
getBase ()
{
return this.base;
};
/**
* Get Uri scheme
*
* @return {string}
*
* @since 1.0.0
*/
getScheme ()
{
return this.scheme;
};
/**
* Get Uri host
*
* @return {string}
*
* @since 1.0.0
*/
getHost ()
{
return this.host;
};
/**
* Get Uri port
*
* @return {string}
*
* @since 1.0.0
*/
getPort ()
{
return this.port;
};
/**
* Get Uri user
*
* @return {string}
*
* @since 1.0.0
*/
getUser ()
{
return this.user;
};
/**
* Get Uri pass
*
* @return {string}
*
* @since 1.0.0
*/
getPass ()
{
return this.pass;
};
/**
* Get Uri query
*
* @return {string}
*
* @since 1.0.0
*/
getQuery ()
{
return this.queryString;
};
/**
* Get Uri
*
* @return {string}
*
* @since 1.0.0
*/
getUri ()
{
return this.uri;
};
/**
* Get Uri fragment
*
* @return {string}
*
* @since 1.0.0
*/
getFragment ()
{
return this.fragment;
};
/**
* Get Uri path
*
* @return {string}
*
* @since 1.0.0
*/
getPath ()
{
return this.path;
};
/**
* Get Uri path offset
*
* @return {number}
*
* @since 1.0.0
*/
getPathOffset ()
{
return jsOMS.substr_count(this.root, '/') - 1;
};
};