Class HttpProxy

java.lang.Object
com.codename1.backend.HttpProxy

public final class HttpProxy extends Object

Forwards a request to another HTTP server and streams its answer back: a reverse proxy, an API gateway route, a pass-through to an internal service.

HttpProxy images = new HttpProxy("http://images.internal:8080");
// in a handler:
return images.forward(request);              // same path and query upstream
return images.forward(request, "/v2/thumbs"); // or a path of your choosing

What it guarantees:

  • Bounded memory. A binary request body is streamed up from wherever it is -- a spooled upload included -- and the response body is streamed down as it arrives (Web.Exchange). A text or compressed request body is the server's in-memory one (under its 8 MB limit), forwarded decoded.
  • Headers survive, hop-by-hop ones do not. Every end-to-end header goes through in both directions, a repeated one (Set-Cookie) line by line. The hop-by-hop set of RFC 9110 7.6.1 -- Connection, Keep-Alive, Proxy-*, TE, Trailer, Transfer-Encoding, Upgrade -- and every header a Connection field names are removed each way. Host and Content-Length are the transport's. X-Forwarded-For, -Proto and -Host are added unless setForwardedHeaders(boolean) turns them off.
  • Destinations are fixed. Only the target's own host is reached, plus hosts named with allowHost(String); a redirect elsewhere is passed back to the client, never followed. Only http and https.
  • Redirects are passed through by default. setFollowRedirects(int) follows up to that many hops itself, for a request with no body only -- a streamed body cannot be sent twice -- and only to allowed hosts. A hop to another host drops the client's Authorization and Cookie.
  • Cancellation goes both ways. A client that disconnects mid-download makes the next write fail, which closes the upstream exchange at once. An upstream that fails before answering is a 502; one that fails after the status and headers went out cannot be turned into an error response any more, so the client's response is aborted -- the HTTP/1.1 connection is closed without its final chunk, the HTTP/2 stream is reset -- and the client sees a truncated response, never a complete-looking one.

The response is re-framed by this server: chunked on HTTP/1.1, DATA frames on HTTP/2, whatever length the upstream declared. One instance serves any number of concurrent requests once configured.

  • Constructor Details

    • HttpProxy

      public HttpProxy(String target) throws IOException
      • target: the upstream's origin and optional base path, such as https://api.internal:8443 or http://10.0.0.5/service
      Throws:
      IOException
  • Method Details

    • setClient

      public HttpProxy setClient(WebClient client)
      The client upstream requests go through, for its timeouts and client certificate; a default one when unset.
    • allowHost

      public HttpProxy allowHost(String host)
      Lets requests -- redirects and forward(HttpServer.Request, String) with an absolute URL -- reach host (a name, or name:port) as well as the target's own.
    • setFollowRedirects

      public HttpProxy setFollowRedirects(int hops)
      How many redirects to follow on the client's behalf; 0, the default, hands every 3xx back to the client as it came.
    • setForwardedHeaders

      public HttpProxy setForwardedHeaders(boolean forwardedHeaders)
      Whether to add X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host; on by default.
    • forward

      public HttpServer.Response forward(HttpServer.Request request)
      Forwards to the target with the request's own path and query appended.
    • forward

      public HttpServer.Response forward(HttpServer.Request request, String pathOrUrl)
      Forwards to pathOrUrl: a path (with any query) appended to the target, or an absolute URL, which must name an allowed host.