Class JavaHttpTransport

java.lang.Object
org.apache.juneau.rest.client.JavaHttpTransport
All Implemented Interfaces:
Closeable, AutoCloseable, HttpTransport

public final class JavaHttpTransport extends Object implements HttpTransport
HttpTransport implementation backed by the JDK's built-in HttpClient.

This is the default transport used by RestClient. It is built into the juneau-rest-client artifact, requires no external dependencies, and is always available on Java 11+.

It is auto-discovered via ServiceLoader and can also be instantiated explicitly:

transport = JavaHttpTransport.builder() .httpClient(HttpClient.newHttpClient()) .build(); client = RestClient.builder() .transport(transport) .build();

When a pooled keep-alive connection is torn down by the server before any response bytes are received (an immediate EOF surfaced by the JDK client as an IOException whose message is "HTTP/1.1 header parser received no bytes"), this transport replays the request exactly once on a fresh connection — but only when TransportRequest.isSafeToReplay() proves it is safe (an idempotent method with an absent or repeatable body). The JDK client already retries body-less GET requests itself, but not other idempotent methods (e.g. PUT/DELETE); this backstop closes that gap while never replaying a POST or any other non-idempotent request.

For SSRF-guard-active (@Remote) requests (see TransportRequest.isSsrfGuardActive()), this transport pin-on-connects: it resolves the request host, selects an address that passes RemoteUrlPolicy, and rewrites the request URI to that literal address (preserving the original host via an explicit Host header) so the socket connects only to the validated address — and re-runs the same check on every Location hop via PolicyEnforcedRedirects. The JDK HttpClient has no connect-time/DNS SPI, so an IP-literal rewrite cannot preserve TLS SNI/hostname verification for the original hostname; per the locked design, policy -covered HTTPS requests are therefore refused (fail closed) on this transport — use a transport that supports connect-time pinning (e.g. Apache HttpClient 4.5/5), or set allowPrivateUrls(true) if the target is an intentional local-dev/intranet endpoint. A policy-covered request is also refused if the underlying HttpClient was built with automatic redirect-following enabled (HttpClient.Redirect.NORMAL or HttpClient.Redirect.ALWAYS), since this transport cannot re-validate hops that client follows on its own; build it with the default HttpClient.Redirect.NEVER (the JDK default) to let this transport's own redirect loop apply.

See Also:
Since:
9.2.1
  • Method Details

    • builder

      Returns a new builder for this transport.
      Returns:
      A new builder. Never null.
    • create

      public static JavaHttpTransport create()
      Returns a new instance backed by a default HttpClient.
      Returns:
      A new instance. Never null.
    • execute

      Description copied from interface: HttpTransport
      Executes the given request and returns the response.

      The caller is responsible for closing the returned TransportResponse after consuming the body.

      Specified by:
      execute in interface HttpTransport
      Parameters:
      request - The fully-resolved request. Must not be null.
      Returns:
      The response. Never null.
      Throws:
      TransportException - If a network-level error occurs.
    • supportsUrlPolicy

      public boolean supportsUrlPolicy()
      Description copied from interface: HttpTransport
      Returns true if this transport can honor the SSRF guardrail's connect-time contract for a policy-covered request (TransportRequest.isSsrfGuardActive()): pin-on-connect to a resolved address that has passed the deny-private policy, and Juneau-controlled redirect revalidation (no fallback to the transport's own auto-follow).

      The default implementation returns false (fail closed): an unknown/caller-supplied transport that has not affirmatively opted in is presumed unable to honor the contract, so RestRequest#run() rejects policy-covered requests against it rather than silently connecting without the guardrail. First-party transports that construct and fully control their own underlying HTTP client override this to return true.

      Specified by:
      supportsUrlPolicy in interface HttpTransport
      Returns:
      true if this transport supports pin-on-connect + redirect revalidation for policy-covered requests.