Proxy

Tags: applications

Added in version 0.5.

The harp_apps.proxy application provides the core proxy features for HARP and includes the configuration logic for endpoints (the mapping between local ports and remote urls, including how to handle them).

Setup

The proxy application is enabled by default when using the harp-proxy start … or harp-proxy server … commands. You can disable it with the –disable proxy option, although this will most probably result in an useless system.

Configuration

Minimal example

proxy:
  endpoints:
    - name: httpbin # a unique name for the endpoint, used to reference it in code, rules and dashboard
      description: An informative description of the endpoint (optional)
      port: 4000 # the local listening port for this endpoint
      url: "https://api1.example.com/"

Note

The url provided can be either a base url like https://api1.example.com/ or a full url like https://api1.example.com/foo/bar/.

Full example

proxy:
  endpoints:
    - # An identifier for this local endpoint, used to reference it in code, rules and
      # dashboard. Must be unique for a given harp instance.
      name: httpbins

      # a human-readable description of the endpoint (optional)
      description: A very informative description

      # the local listening port for this endpoint, if not set the proxy will not listen on
      # any port for this endpoint.
      port: 4000

      # the controller to use for this endpoint, "null" means default but you can specify
      # a custom controller. Most of the time you will want to use the default controller
      # and thus do not include this line.
      controller: null

      # the remote to proxy to, which can be anything from a single url to a complex
      # multipool configuration with # defaults and fallbacks, healthcheck probes, etc.
      remote:
        # the minimum number of endpoints to try to keep in the active pool. If the number
        # of active endpoints falls below this number, the proxy will attempt to bring them
        # back up to this number by including endpoints from the fallback pool.
        min_pool_size: 2

        # Endpoints
        endpoints:
          - url: "https://api1.example.com/"
          - url: "https://api2.example.com/"
          - url: "https://fallback.example.com/"
            pools: [fallback]
            liveness:
              type: ignore

        # Liveness settings for all endpoints, if not overriden by a specific endpoint's
        # liveness.
        liveness:
          type: naive
          failure_threshold: 2
          success_threshold: 2

        # A periodic probe to try to close the circuit breaker even if it's not actively
        # queried by the end user.
        probe:
          method: GET
          path: /healthz
          timeout: 10.0

Custom Controller

You can also provide a custom controller to handle the proxy logic. This is useful if you want to add custom logic to the proxy. A custom controller must be defined as a Service.

proxy:
  endpoints:
    - name: httpbin # a unique name for the endpoint, used to reference it in code, rules and dashboard
      description: An informative description of the endpoint (optional)
      port: 4000 # the local listening port for this endpoint
      url: "https://api1.example.com/"
      controller:
        type: harp_apps.proxy.controllers.HttpProxyController
        name: httpbin_controller
        logging: false

Command line

It is also possible to add endpoints using the command line. This is available for quick tests but should not be used as a permanent solution.

harp-proxy start --endpoint starwars=1234:https://swapi.dev/

Warning

The current CLI syntax is hackish and limited, the syntax will most probably change in the future.

You can use multiple --endpoint ... arguments and the option is available for all server-like commands (harp-proxy start ..., harp-proxy server ..., …).

Remote urls carrying a path

An endpoint url may carry a path of its own, which is how you expose one subtree of an upstream rather than the whole of it. The url acts as the base that an incoming request path is resolved against, in the ordinary URL sense, so end it with a slash if you mean it as a prefix:

Endpoint url

Request

Forwarded to

http://example.com

/a/b

http://example.com/a/b

http://example.com/api/v1/

/a/b

http://example.com/api/v1/a/b

http://example.com/api/v1

/a/b

http://example.com/api/a/b

The last row is why the trailing slash matters: without it, the final segment is treated as a resource rather than a directory and is replaced, exactly as a relative link on a web page would be.

A request may not leave the subtree the endpoint url points at. A path resolving above it, through .. segments, is refused with 400 Bad Request and nothing is sent upstream. Dot segments that resolve back inside it are forwarded normally, so /a/b/../c reaches /a/c as expected.