getOnlyProxy function

Route getOnlyProxy(
  1. String path,
  2. String proxyBaseUrl, {
  3. Map<String, String>? pathRegEx,
  4. ResponseProcessor? responseProcessor,
  5. bool stripPrefix = true,
  6. String proxyName = 'jaguar_proxy',
  7. HttpClient? client,
})

Creates a route that proxies the requests matching the path to another server at proxyBaseUrl.

Example usage: final server = Jaguar(); server.addRoute(getOnlyProxy('/client/*', 'http://localhost:8000/'));

path is used to match the incoming URL/route. The matching is based on prefix. For example:

When path is /html/*, it will match:

  • /html
  • /html/
  • /html/index.html
  • /html/static/index.html

The proxyBaseUrl is just prefixed to the remaining part after path is matched. For example:

For getOnlyProxy('/html/*', 'http://localhost:8000/client'),

  • /html is mapped into http://localhost:8000/client/
  • /html/ is mapped into http://localhost:8000/client/
  • /html/index.html is mapped into http://localhost:8000/client/index.html
  • /html/static/index.html is mapped into http://localhost:8000/client/static/index.html

Implementation

//TODO add timeout
Route getOnlyProxy(String path, String proxyBaseUrl,
    {Map<String, String>? pathRegEx,
    ResponseProcessor? responseProcessor,
    bool stripPrefix: true,
    String proxyName: 'jaguar_proxy',
    HttpClient? client}) {
  client ??= HttpClient();

  Route route;
  int skipCount = 0;
  route = Route.get(path, (ctx) async {
    Iterable<String> segs = ctx.pathSegments;
    if (stripPrefix) segs = segs.skip(skipCount);
    Uri requestUri = Uri.parse(proxyBaseUrl + '/' + segs.join('/'));
    HttpClientRequest clientReq;
    try {
      clientReq = await client!.openUrl(ctx.req.method, requestUri);
    } catch (e) {
      return Response(statusCode: 404);
    }
    clientReq.followRedirects = false;

    ctx.req.headers.forEach((String key, dynamic val) {
      clientReq.headers.add(key, val);
    });
    // TODO add forward headers
    clientReq.headers.set('Host', requestUri.authority);

    // Add a Via header. See
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45
    clientReq.headers.add('via', '${ctx.req.protocolVersion} $proxyName');

    clientReq.add(await ctx.req.body);
    final HttpClientResponse clientResp = await clientReq.close();

    if (clientResp.statusCode == HttpStatus.notFound)
      return Response(statusCode: 404);

    _returnResponse(ctx, clientResp, requestUri, proxyName, proxyBaseUrl);
  }, responseProcessor: responseProcessor, pathRegEx: pathRegEx);

  if (stripPrefix) {
    if (route.pathSegments.isNotEmpty)
      skipCount = route.pathSegments.length - 1;
  }
  return route;
}