import type BrowserWindow from '../../window/BrowserWindow.js'; import WindowBrowserContext from '../../window/WindowBrowserContext.js'; import Path from 'path'; import type Response from '../Response.js'; import type ISyncResponse from '../types/ISyncResponse.js'; import * as PropertySymbol from '../../PropertySymbol.js'; const NOT_FOUND_HTML = 'Happy DOM Virtual Server - 404 Not Found

Happy DOM Virtual Server - 404 Not Found

'; /** * Virtual server utility. */ export default class VirtualServerUtility { /** * Returns the filesystem path for a request URL if it matches a virtual server. * * @param window Window. * @param requestURL Request URL. */ public static getFilepath(window: BrowserWindow, requestURL: string): string | null { const browserSettings = new WindowBrowserContext(window).getSettings(); if ( !browserSettings || (!browserSettings.fetch.virtualServers && !browserSettings.module.resolveNodeModules) ) { return null; } if (browserSettings.fetch.virtualServers) { for (const virtualServer of browserSettings.fetch.virtualServers) { let baseURL: URL | null = null; if (typeof virtualServer.url === 'string') { const url = new URL( virtualServer.url[virtualServer.url.length - 1] === '/' ? virtualServer.url.slice(0, -1) : virtualServer.url, window.location.origin ); if (requestURL.startsWith(url.href)) { baseURL = url; } } else if (virtualServer.url instanceof RegExp) { const match = requestURL.match(virtualServer.url); if (match) { baseURL = new URL( match[0][match[0].length - 1] === '/' ? match[0].slice(0, -1) : match[0], window.location.origin ); } } if (baseURL) { const path = requestURL.slice(baseURL.href.length).split('?')[0].split('#')[0]; return Path.join(Path.resolve(virtualServer.directory), path.replaceAll('/', Path.sep)); } } } if (browserSettings.module.resolveNodeModules) { const moduleUrl = browserSettings.module.resolveNodeModules.url; const url = new URL( moduleUrl[moduleUrl.length - 1] === '/' ? moduleUrl.slice(0, -1) : moduleUrl, window.location.origin ); if (requestURL.startsWith(url.href)) { const path = requestURL.slice(url.href.length).split('?')[0].split('#')[0]; return Path.join( Path.resolve(browserSettings.module.resolveNodeModules.directory), path.replaceAll('/', Path.sep) ); } } return null; } /** * Returns a 404 response. * * @param window Window. * @returns 404 response. */ public static getNotFoundResponse(window: BrowserWindow): Response { return new window.Response(NOT_FOUND_HTML, { status: 404, statusText: 'Not Found', headers: { 'Content-Type': 'text/html' } }); } /** * Returns a 404 response. * * @param window Window. * @param requestURL Request URL. * @returns 404 response. */ public static getNotFoundSyncResponse(window: BrowserWindow, requestURL: string): ISyncResponse { return { status: 404, statusText: 'Not Found', ok: false, url: requestURL, redirected: false, headers: new window.Headers({ 'Content-Type': 'text/html' }), body: Buffer.from(NOT_FOUND_HTML), [PropertySymbol.virtualServerFile]: null }; } }