http-proxy-middleware#RequestHandler TypeScript Examples

The following examples show how to use http-proxy-middleware#RequestHandler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: proxy.ts    From the-fake-backend with ISC License 6 votes vote down vote up
/**
   * Resolve the current proxy handler for a given route.
   *
   * @param route The route
   * @return Resolved proxy handler
   */
  private resolveRouteProxyHandler(route: Route): RequestHandler | undefined {
    return route.proxy?.handler;
  }
Example #2
Source File: proxy.ts    From the-fake-backend with ISC License 6 votes vote down vote up
/**
   * Resolve the current global proxy handler.
   *
   * @param route The route
   * @return Resolved proxy handler
   */
  private resolveGlobalProxyHandler(): RequestHandler | undefined {
    const current = this.getCurrent();

    return current?.handler;
  }
Example #3
Source File: router.ts    From backstage with Apache License 2.0 4 votes vote down vote up
// Creates a proxy middleware, possibly with defaults added on top of the
// given config.
export function buildMiddleware(
  pathPrefix: string,
  logger: Logger,
  route: string,
  config: string | ProxyConfig,
): RequestHandler {
  const fullConfig =
    typeof config === 'string' ? { target: config } : { ...config };

  // Validate that target is a valid URL.
  if (typeof fullConfig.target !== 'string') {
    throw new Error(`Proxy target must be a string`);
  }
  try {
    // eslint-disable-next-line no-new
    new URL(fullConfig.target! as string);
  } catch {
    throw new Error(
      `Proxy target is not a valid URL: ${fullConfig.target ?? ''}`,
    );
  }

  // Default is to do a path rewrite that strips out the proxy's path prefix
  // and the rest of the route.
  if (fullConfig.pathRewrite === undefined) {
    let routeWithSlash = route.endsWith('/') ? route : `${route}/`;

    if (!pathPrefix.endsWith('/') && !routeWithSlash.startsWith('/')) {
      // Need to insert a / between pathPrefix and routeWithSlash
      routeWithSlash = `/${routeWithSlash}`;
    } else if (pathPrefix.endsWith('/') && routeWithSlash.startsWith('/')) {
      // Never expect this to happen at this point in time as
      // pathPrefix is set using `getExternalBaseUrl` which "Returns the
      // external HTTP base backend URL for a given plugin,
      // **without a trailing slash.**". But in case this changes in future, we
      // need to drop a / on either pathPrefix or routeWithSlash
      routeWithSlash = routeWithSlash.substring(1);
    }

    // The ? makes the slash optional for the rewrite, so that a base path without an ending slash
    // will also be matched (e.g. '/sample' and then requesting just '/api/proxy/sample' without an
    // ending slash). Otherwise the target gets called with the full '/api/proxy/sample' path
    // appended.
    fullConfig.pathRewrite = {
      [`^${pathPrefix}${routeWithSlash}?`]: '/',
    };
  }

  // Default is to update the Host header to the target
  if (fullConfig.changeOrigin === undefined) {
    fullConfig.changeOrigin = true;
  }

  // Attach the logger to the proxy config
  fullConfig.logProvider = () => logger;

  // Only return the allowed HTTP headers to not forward unwanted secret headers
  const requestHeaderAllowList = new Set<string>(
    [
      // allow all safe headers
      ...safeForwardHeaders,

      // allow all headers that are set by the proxy
      ...((fullConfig.headers && Object.keys(fullConfig.headers)) || []),

      // allow all configured headers
      ...(fullConfig.allowedHeaders || []),
    ].map(h => h.toLocaleLowerCase()),
  );

  // Use the custom middleware filter to do two things:
  //  1. Remove any headers not in the allow list to stop them being forwarded
  //  2. Only permit the allowed HTTP methods if configured
  //
  // We are filtering the proxy request headers here rather than in
  // `onProxyReq` because when global-agent is enabled then `onProxyReq`
  // fires _after_ the agent has already sent the headers to the proxy
  // target, causing a ERR_HTTP_HEADERS_SENT crash
  const filter = (_pathname: string, req: http.IncomingMessage): boolean => {
    const headerNames = Object.keys(req.headers);
    headerNames.forEach(h => {
      if (!requestHeaderAllowList.has(h.toLocaleLowerCase())) {
        delete req.headers[h];
      }
    });

    return fullConfig?.allowedMethods?.includes(req.method!) ?? true;
  };
  // Makes http-proxy-middleware logs look nicer and include the mount path
  filter.toString = () => route;

  // Only forward the allowed HTTP headers to not forward unwanted secret headers
  const responseHeaderAllowList = new Set<string>(
    [
      // allow all safe headers
      ...safeForwardHeaders,

      // allow all configured headers
      ...(fullConfig.allowedHeaders || []),
    ].map(h => h.toLocaleLowerCase()),
  );

  // only forward the allowed headers in backend->client
  fullConfig.onProxyRes = (proxyRes: http.IncomingMessage) => {
    const headerNames = Object.keys(proxyRes.headers);

    headerNames.forEach(h => {
      if (!responseHeaderAllowList.has(h.toLocaleLowerCase())) {
        delete proxyRes.headers[h];
      }
    });
  };

  return createProxyMiddleware(filter, fullConfig);
}