UNPKG

@nasriya/hypercloud

Version:

Nasriya HyperCloud is a lightweight Node.js HTTP2 framework.

143 lines (142 loc) 6.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const handlerHelpers_1 = require("./assets/handlerHelpers"); const request_1 = __importDefault(require("./assets/request")); const response_1 = __importDefault(require("./assets/response")); const tldts_1 = __importDefault(require("tldts")); const tls_1 = require("tls"); const helpers_1 = __importDefault(require("../../utils/helpers")); class Initializer { /** * A function to initialize the request, parse some data, and so on. * @param {HyperCloudServer} server * @param {http2.Http2ServerRequest} req * @param {object} options Initialization options * @param {string[]} [options.trusted_proxies] The IP address of the trusted proxy. This is needed in order to get the correct IP address of the client * @returns {Promise<HyperCloudRequest>} */ async createRequest(server, req, options) { /**@type {InitializedRequest} */ const request = Object.seal({ server, id: null, ip: await (0, handlerHelpers_1.getClientIP)(req, options?.trusted_proxies || []), protocol: null, host: null, subDomain: null, domain: null, baseUrl: null, path: [], query: {}, href: null, bodyType: null, body: null, cookies: (0, handlerHelpers_1.cookieParser)(req.headers['cookie']), params: {} }); // @ts-ignore request.id = req.id; request.protocol = (() => { if (req.socket instanceof tls_1.TLSSocket) { return req.socket.encrypted ? 'https' : 'http'; } else { return 'http'; } })(); request.host = (() => { const authority = req.headers[':authority']; if (helpers_1.default.is.validString(authority)) { return authority; } if (helpers_1.default.is.validString(req.headers.host)) { return req.headers.host; } return 'UnknownHost'; })(); request.baseUrl = `${request.protocol}://${request.host}`; request.href = `${request.baseUrl}${req.url}`; const parsed = new URL(request.href); request.query = Object.fromEntries(parsed.searchParams); request.path = parsed.pathname.split('/').filter(i => i.length > 0); const parsedTldts = tldts_1.default.parse(request.href); if (typeof parsedTldts.domain === 'string') { request.domain = parsedTldts.domain; } else if (parsedTldts.isIp && parsedTldts.hostname) { request.domain = parsedTldts.hostname; } else { request.domain = 'UnknownDomain'; } request.subDomain = parsedTldts.subdomain || undefined; const contentLength = (() => { const contentLengthHeader = req.headers['content-length'] || ''; if (helpers_1.default.is.validString(contentLengthHeader)) { const contentLength = parseInt(contentLengthHeader, 10); if (!isNaN(contentLength)) { return contentLength; } } return 0; })(); const bodyMethods = ['POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'TRACE', 'CONNECT']; if (bodyMethods.includes(req.method) && contentLength > 0) { // Get the Content-Type header from the request const contentType = req.headers['content-type']; if (contentType) { // Check if the Content-Type header is present if (contentType.includes('text/plain') || contentType.includes('application/json') || contentType.includes('application/javascript') || contentType.includes('text/html') || contentType.includes('application/xml') || contentType.includes('application/graphql')) { req.setEncoding('utf8'); // Set encoding to interpret buffer as a string } else { req.setEncoding('binary'); // Other types of data } if (!contentType.includes('multipart/form-data')) { // Read and accumulate the request body let tempBody = ''; req.on('data', (chunk) => { tempBody += chunk; }); const requestEnd = new Promise((resolve, reject) => { try { // When the entire request body has been received req.on('end', () => { const { body, bodyType } = (0, handlerHelpers_1.bodyParser)(tempBody, contentType); request.bodyType = bodyType; if (body) { request.body = body; } resolve(undefined); }); } catch (error) { reject(error); } }); await requestEnd; } } } return Promise.resolve(new request_1.default(request, req)); } /** * A function to create a response from the ```HyperCloudRequest``` and the ```Http2ServerResponse```. * @param {HyperCloudServer} server * @param {HyperCloudRequest} req * @param {http2.Http2ServerResponse} res * @returns {HyperCloudResponse} */ createResponse(server, req, res) { return new response_1.default(server, req, res); } } exports.default = new Initializer();