export function getStorageContent()

in src/msha/middlewares/response.middleware.ts [85:243]


export function getStorageContent(
  req: http.IncomingMessage,
  res: http.ServerResponse,
  pathToServe: string | undefined,
  matchedRoute: SWAConfigFileRoute | undefined,
  responseOverridesRule: SWAConfigFileResponseOverrides | undefined,
  navigationFallbackRule: SWAConfigFileNavigationFallback | undefined,
  mimeTypeRule: SWAConfigFileMimeTypes | undefined,
  routeHeaders: SWAConfigFileRouteHeaders | undefined,
  globalHeaders: SWAConfigFileGlobalHeaders | undefined
): {
  isFunctionFallbackRequest: boolean;
  isSuccessfulSiteHit: boolean;
} {
  logger.silly(`checking storage content`);

  // don't serve staticwebapp.config.json / routes.json
  if (isSWAConfigFileUrl(req)) {
    logger.silly(` - request to config file detected. Exit`);

    handleErrorPage(req, res, 404, responseOverridesRule);
    return {
      isFunctionFallbackRequest: false,
      isSuccessfulSiteHit: false,
    };
  }

  let requestPath = req.url as string;
  let filePathFromRequest: string | null = null;
  let decodedRequestPath = req.url;
  const { urlPathnameWithoutQueryParams } = parseQueryParams(req, matchedRoute);

  // we only process if the user is NOT connecting to a remote dev server.
  // if the user is connecting to a remote dev server, we skip the following logic.
  if (IS_APP_DEV_SERVER()) {
    logger.silly(`remote dev server detected.`);
    return {
      isFunctionFallbackRequest: false,
      isSuccessfulSiteHit: true,
    };
  } else {
    requestPath = urlPathnameWithoutQueryParams;
    decodedRequestPath = urlPathnameWithoutQueryParams;

    if (pathToServe) {
      requestPath = pathToServe;
      decodedRequestPath = decodeURI(pathToServe);
    }

    filePathFromRequest = tryFindFileForRequest(requestPath!);
  }

  if (!filePathFromRequest) {
    let shouldDisplayNotFoundPage = true;
    if (navigationFallbackRule?.rewrite) {
      const isFunctionFallback = isFunctionRequest(req, navigationFallbackRule.rewrite);
      logger.silly(` - isFunctionFallback: ${chalk.yellow(isFunctionFallback)}`);

      if (isFunctionFallback) {
        return {
          isFunctionFallbackRequest: true,
          isSuccessfulSiteHit: false,
        };
      } else {
        const navigationFallbackRewrite = navigationFallbackRule.rewrite;
        logger.silly(`validating navigation fallback rewrite rule`);
        logger.silly(` - rewrite: ${chalk.yellow(navigationFallbackRewrite)}`);

        const isNavigationFallbackWritePathExists = tryFindFileForRequest(navigationFallbackRewrite);
        if (
          isNavigationFallbackWritePathExists &&
          !isRequestPathExcludedFromNavigationFallback(decodedRequestPath, navigationFallbackRule, matchedRoute)
        ) {
          shouldDisplayNotFoundPage = false;
        }

        if (navigationFallbackRewrite) {
          filePathFromRequest = navigationFallbackRewrite;

          if (!shouldDisplayNotFoundPage) {
            logger.silly(`rewrite request to ${chalk.yellow(filePathFromRequest)}`);
            req.url = filePathFromRequest;
          }
        }
      }
    }

    logger.silly(` - shouldDisplayNotFoundPage: ${chalk.yellow(shouldDisplayNotFoundPage)}`);

    if (shouldDisplayNotFoundPage) {
      handleErrorPage(req, res, 404, responseOverridesRule);
      return {
        isFunctionFallbackRequest: false,
        isSuccessfulSiteHit: false,
      };
    }
  }

  if (!filePathFromRequest) {
    return {
      isFunctionFallbackRequest: false,
      isSuccessfulSiteHit: false,
    };
  }

  // if the file path is a remote HTTP request, this means we are connecting to a dev server.
  // exist here and let the remote server handle the request.
  if (isHttpUrl(filePathFromRequest)) {
    return {
      isFunctionFallbackRequest: false,
      isSuccessfulSiteHit: true,
    };
  }

  // mime type
  const mimeType = getMimeTypeForExtension(filePathFromRequest, mimeTypeRule);
  res.setHeader("Content-Type", mimeType);

  // compute both global and route headers
  const matchingRouteHeaders = getHeadersForRoute(routeHeaders, globalHeaders);

  if (responseOverridesRule) {
    // Handle HEAD request
    if (req.method === "HEAD") {
      updateResponseHeaders(res, matchingRouteHeaders);

      res.statusCode = 200;

      return {
        isFunctionFallbackRequest: false,
        isSuccessfulSiteHit: true,
      };
    }

    // Handle OPTIONS request
    if (req.method === "OPTIONS") {
      updateResponseHeaders(res, matchingRouteHeaders);

      const allowStr = "GET, HEAD, OPTIONS";
      res.setHeader("Allow", allowStr);

      res.statusCode = 204; // No Content
      return {
        isFunctionFallbackRequest: false,
        isSuccessfulSiteHit: true,
      };
    }
  }

  // Handle GET request
  updateResponseHeaders(res, matchingRouteHeaders);

  req.url = filePathFromRequest;

  return {
    isSuccessfulSiteHit: true,
    isFunctionFallbackRequest: false,
  };
}