first commit
This commit is contained in:
195
app_vue/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js
generated
vendored
Normal file
195
app_vue/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js
generated
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const {
|
||||
parse
|
||||
} = require("url");
|
||||
|
||||
const querystring = require("querystring");
|
||||
|
||||
const getPaths = require("./getPaths");
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
|
||||
const cacheStore = new WeakMap();
|
||||
/**
|
||||
* @template T
|
||||
* @param {Function} fn
|
||||
* @param {{ cache?: Map<string, { data: T }> } | undefined} cache
|
||||
* @param {(value: T) => T} callback
|
||||
* @returns {any}
|
||||
*/
|
||||
// @ts-ignore
|
||||
|
||||
const mem = (fn, {
|
||||
cache = new Map()
|
||||
} = {}, callback) => {
|
||||
/**
|
||||
* @param {any} arguments_
|
||||
* @return {any}
|
||||
*/
|
||||
const memoized = (...arguments_) => {
|
||||
const [key] = arguments_;
|
||||
const cacheItem = cache.get(key);
|
||||
|
||||
if (cacheItem) {
|
||||
return cacheItem.data;
|
||||
}
|
||||
|
||||
let result = fn.apply(void 0, arguments_);
|
||||
result = callback(result);
|
||||
cache.set(key, {
|
||||
data: result
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
cacheStore.set(memoized, cache);
|
||||
return memoized;
|
||||
}; // eslint-disable-next-line no-undefined
|
||||
|
||||
|
||||
const memoizedParse = mem(parse, undefined, value => {
|
||||
if (value.pathname) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
value.pathname = decode(value.pathname);
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
||||
/**
|
||||
* @typedef {Object} Extra
|
||||
* @property {import("fs").Stats=} stats
|
||||
* @property {number=} errorCode
|
||||
*/
|
||||
|
||||
/**
|
||||
* decodeURIComponent.
|
||||
*
|
||||
* Allows V8 to only deoptimize this fn instead of all of send().
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
function decode(input) {
|
||||
return querystring.unescape(input);
|
||||
}
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
* @param {string} url
|
||||
* @param {Extra=} extra
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
|
||||
|
||||
function getFilenameFromUrl(context, url, extra = {}) {
|
||||
const {
|
||||
options
|
||||
} = context;
|
||||
const paths = getPaths(context);
|
||||
/** @type {string | undefined} */
|
||||
|
||||
let foundFilename;
|
||||
/** @type {URL} */
|
||||
|
||||
let urlObject;
|
||||
|
||||
try {
|
||||
// The `url` property of the `request` is contains only `pathname`, `search` and `hash`
|
||||
urlObject = memoizedParse(url, false, true);
|
||||
} catch (_ignoreError) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const {
|
||||
publicPath,
|
||||
outputPath
|
||||
} of paths) {
|
||||
/** @type {string | undefined} */
|
||||
let filename;
|
||||
/** @type {URL} */
|
||||
|
||||
let publicPathObject;
|
||||
|
||||
try {
|
||||
publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
const {
|
||||
pathname
|
||||
} = urlObject;
|
||||
const {
|
||||
pathname: publicPathPathname
|
||||
} = publicPathObject;
|
||||
|
||||
if (pathname && pathname.startsWith(publicPathPathname)) {
|
||||
// Null byte(s)
|
||||
if (pathname.includes("\0")) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
extra.errorCode = 400;
|
||||
return;
|
||||
} // ".." is malicious
|
||||
|
||||
|
||||
if (UP_PATH_REGEXP.test(path.normalize(`./${pathname}`))) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
extra.errorCode = 403;
|
||||
return;
|
||||
} // Strip the `pathname` property from the `publicPath` option from the start of requested url
|
||||
// `/complex/foo.js` => `foo.js`
|
||||
// and add outputPath
|
||||
// `foo.js` => `/home/user/my-project/dist/foo.js`
|
||||
|
||||
|
||||
filename = path.join(outputPath, pathname.slice(publicPathPathname.length));
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
extra.stats =
|
||||
/** @type {import("fs").statSync} */
|
||||
context.outputFileSystem.statSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (extra.stats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
} else if (extra.stats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
|
||||
const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
|
||||
filename = path.join(filename, indexValue);
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
extra.stats =
|
||||
/** @type {import("fs").statSync} */
|
||||
context.outputFileSystem.statSync(filename);
|
||||
} catch (__ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (extra.stats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // eslint-disable-next-line consistent-return
|
||||
|
||||
|
||||
return foundFilename;
|
||||
}
|
||||
|
||||
module.exports = getFilenameFromUrl;
|
Reference in New Issue
Block a user