| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 | 'use strict';const path = require('path');const mime = require('mime');const DevMiddlewareError = require('./DevMiddlewareError');const {  getFilenameFromUrl,  handleRangeHeaders,  handleRequest,  ready,} = require('./util');// Do not add a charset to the Content-Type header of these file types// otherwise the client will fail to render them correctly.const NonCharsetFileTypes = /\.(wasm|usdz)$/;module.exports = function wrapper(context) {  return function middleware(req, res, next) {    // fixes #282. credit @cexoso. in certain edge situations res.locals is    // undefined.    // eslint-disable-next-line no-param-reassign    res.locals = res.locals || {};    function goNext() {      if (!context.options.serverSideRender) {        return next();      }      return new Promise((resolve) => {        ready(          context,          () => {            // eslint-disable-next-line no-param-reassign            res.locals.webpackStats = context.webpackStats;            // eslint-disable-next-line no-param-reassign            res.locals.fs = context.fs;            resolve(next());          },          req        );      });    }    const acceptedMethods = context.options.methods || ['GET', 'HEAD'];    if (acceptedMethods.indexOf(req.method) === -1) {      return goNext();    }    let filename = getFilenameFromUrl(      context.options.publicPath,      context.compiler,      req.url    );    if (filename === false) {      return goNext();    }    return new Promise((resolve) => {      handleRequest(context, filename, processRequest, req);      // eslint-disable-next-line consistent-return      function processRequest() {        try {          let stat = context.fs.statSync(filename);          if (!stat.isFile()) {            if (stat.isDirectory()) {              let { index } = context.options;              // eslint-disable-next-line no-undefined              if (index === undefined || index === true) {                index = 'index.html';              } else if (!index) {                throw new DevMiddlewareError('next');              }              filename = path.posix.join(filename, index);              stat = context.fs.statSync(filename);              if (!stat.isFile()) {                throw new DevMiddlewareError('next');              }            } else {              throw new DevMiddlewareError('next');            }          }        } catch (e) {          return resolve(goNext());        }        // server content        let content = context.fs.readFileSync(filename);        content = handleRangeHeaders(content, req, res);        let contentType = mime.getType(filename) || '';        if (!NonCharsetFileTypes.test(filename)) {          contentType += '; charset=UTF-8';        }        if (!res.getHeader || !res.getHeader('Content-Type')) {          res.setHeader('Content-Type', contentType);        }        res.setHeader('Content-Length', content.length);        const { headers } = context.options;        if (headers) {          for (const name in headers) {            if ({}.hasOwnProperty.call(headers, name)) {              res.setHeader(name, context.options.headers[name]);            }          }        }        // Express automatically sets the statusCode to 200, but not all servers do (Koa).        // eslint-disable-next-line no-param-reassign        res.statusCode = res.statusCode || 200;        if (res.send) {          res.send(content);        } else {          res.end(content);        }        resolve();      }    });  };};
 |