first commit
This commit is contained in:
249
app_vue/node_modules/webpack-dev-middleware/dist/middleware.js
generated
vendored
Normal file
249
app_vue/node_modules/webpack-dev-middleware/dist/middleware.js
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const mime = require("mime-types");
|
||||
|
||||
const parseRange = require("range-parser");
|
||||
|
||||
const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
|
||||
|
||||
const {
|
||||
getHeaderNames,
|
||||
getHeaderFromRequest,
|
||||
getHeaderFromResponse,
|
||||
setHeaderForResponse,
|
||||
setStatusCode,
|
||||
send,
|
||||
sendError
|
||||
} = require("./utils/compatibleAPI");
|
||||
|
||||
const ready = require("./utils/ready");
|
||||
/** @typedef {import("./index.js").NextFunction} NextFunction */
|
||||
|
||||
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
|
||||
|
||||
/** @typedef {import("./index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @param {number} size
|
||||
* @param {import("range-parser").Range} [range]
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
|
||||
function getValueContentRangeHeader(type, size, range) {
|
||||
return `${type} ${range ? `${range.start}-${range.end}` : "*"}/${size}`;
|
||||
}
|
||||
/**
|
||||
* @param {string | number} title
|
||||
* @param {string} body
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
|
||||
function createHtmlDocument(title, body) {
|
||||
return `${"<!DOCTYPE html>\n" + '<html lang="en">\n' + "<head>\n" + '<meta charset="utf-8">\n' + "<title>"}${title}</title>\n` + `</head>\n` + `<body>\n` + `<pre>${body}</pre>\n` + `</body>\n` + `</html>\n`;
|
||||
}
|
||||
|
||||
const BYTES_RANGE_REGEXP = /^ *bytes/i;
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("./index.js").Context<Request, Response>} context
|
||||
* @return {import("./index.js").Middleware<Request, Response>}
|
||||
*/
|
||||
|
||||
function wrapper(context) {
|
||||
return async function middleware(req, res, next) {
|
||||
const acceptedMethods = context.options.methods || ["GET", "HEAD"]; // fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
res.locals = res.locals || {};
|
||||
|
||||
if (req.method && !acceptedMethods.includes(req.method)) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
ready(context, processRequest, req);
|
||||
|
||||
async function goNext() {
|
||||
if (!context.options.serverSideRender) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
ready(context, () => {
|
||||
/** @type {any} */
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.locals.webpack = {
|
||||
devMiddleware: context
|
||||
};
|
||||
resolve(next());
|
||||
}, req);
|
||||
});
|
||||
}
|
||||
|
||||
async function processRequest() {
|
||||
/** @type {import("./utils/getFilenameFromUrl").Extra} */
|
||||
const extra = {};
|
||||
const filename = getFilenameFromUrl(context,
|
||||
/** @type {string} */
|
||||
req.url, extra);
|
||||
|
||||
if (!filename) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
if (extra.errorCode) {
|
||||
if (extra.errorCode === 403) {
|
||||
context.logger.error(`Malicious path "${filename}".`);
|
||||
}
|
||||
|
||||
sendError(req, res, extra.errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
let {
|
||||
headers
|
||||
} = context.options;
|
||||
|
||||
if (typeof headers === "function") {
|
||||
// @ts-ignore
|
||||
headers = headers(req, res, context);
|
||||
}
|
||||
/**
|
||||
* @type {{key: string, value: string | number}[]}
|
||||
*/
|
||||
|
||||
|
||||
const allHeaders = [];
|
||||
|
||||
if (typeof headers !== "undefined") {
|
||||
if (!Array.isArray(headers)) {
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const name in headers) {
|
||||
// @ts-ignore
|
||||
allHeaders.push({
|
||||
key: name,
|
||||
value: headers[name]
|
||||
});
|
||||
}
|
||||
|
||||
headers = allHeaders;
|
||||
}
|
||||
|
||||
headers.forEach(
|
||||
/**
|
||||
* @param {{key: string, value: any}} header
|
||||
*/
|
||||
header => {
|
||||
setHeaderForResponse(res, header.key, header.value);
|
||||
});
|
||||
}
|
||||
|
||||
if (!getHeaderFromResponse(res, "Content-Type")) {
|
||||
// content-type name(like application/javascript; charset=utf-8) or false
|
||||
const contentType = mime.contentType(path.extname(filename)); // Only set content-type header if media type is known
|
||||
// https://tools.ietf.org/html/rfc7231#section-3.1.1.5
|
||||
|
||||
if (contentType) {
|
||||
setHeaderForResponse(res, "Content-Type", contentType);
|
||||
}
|
||||
}
|
||||
|
||||
if (!getHeaderFromResponse(res, "Accept-Ranges")) {
|
||||
setHeaderForResponse(res, "Accept-Ranges", "bytes");
|
||||
}
|
||||
|
||||
const rangeHeader = getHeaderFromRequest(req, "range");
|
||||
let start;
|
||||
let end;
|
||||
|
||||
if (rangeHeader && BYTES_RANGE_REGEXP.test(rangeHeader)) {
|
||||
const size = await new Promise(resolve => {
|
||||
/** @type {import("fs").lstat} */
|
||||
context.outputFileSystem.lstat(filename, (error, stats) => {
|
||||
if (error) {
|
||||
context.logger.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(stats.size);
|
||||
});
|
||||
});
|
||||
const parsedRanges = parseRange(size, rangeHeader, {
|
||||
combine: true
|
||||
});
|
||||
|
||||
if (parsedRanges === -1) {
|
||||
const message = "Unsatisfiable range for 'Range' header.";
|
||||
context.logger.error(message);
|
||||
const existingHeaders = getHeaderNames(res);
|
||||
|
||||
for (let i = 0; i < existingHeaders.length; i++) {
|
||||
res.removeHeader(existingHeaders[i]);
|
||||
}
|
||||
|
||||
setStatusCode(res, 416);
|
||||
setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size));
|
||||
setHeaderForResponse(res, "Content-Type", "text/html; charset=utf-8");
|
||||
const document = createHtmlDocument(416, `Error: ${message}`);
|
||||
const byteLength = Buffer.byteLength(document);
|
||||
setHeaderForResponse(res, "Content-Length", Buffer.byteLength(document));
|
||||
send(req, res, document, byteLength);
|
||||
return;
|
||||
} else if (parsedRanges === -2) {
|
||||
context.logger.error("A malformed 'Range' header was provided. A regular response will be sent for this request.");
|
||||
} else if (parsedRanges.length > 1) {
|
||||
context.logger.error("A 'Range' header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
|
||||
}
|
||||
|
||||
if (parsedRanges !== -2 && parsedRanges.length === 1) {
|
||||
// Content-Range
|
||||
setStatusCode(res, 206);
|
||||
setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size,
|
||||
/** @type {import("range-parser").Ranges} */
|
||||
parsedRanges[0]));
|
||||
[{
|
||||
start,
|
||||
end
|
||||
}] = parsedRanges;
|
||||
}
|
||||
}
|
||||
|
||||
const isFsSupportsStream = typeof context.outputFileSystem.createReadStream === "function";
|
||||
let bufferOtStream;
|
||||
let byteLength;
|
||||
|
||||
try {
|
||||
if (typeof start !== "undefined" && typeof end !== "undefined" && isFsSupportsStream) {
|
||||
bufferOtStream =
|
||||
/** @type {import("fs").createReadStream} */
|
||||
context.outputFileSystem.createReadStream(filename, {
|
||||
start,
|
||||
end
|
||||
});
|
||||
byteLength = end - start + 1;
|
||||
} else {
|
||||
bufferOtStream =
|
||||
/** @type {import("fs").readFileSync} */
|
||||
context.outputFileSystem.readFileSync(filename);
|
||||
({
|
||||
byteLength
|
||||
} = bufferOtStream);
|
||||
}
|
||||
} catch (_ignoreError) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
send(req, res, bufferOtStream, byteLength);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = wrapper;
|
Reference in New Issue
Block a user