<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc>
<#import "/templates/links.adoc" as links>

<@tmpl.guide
title="Configuring outgoing HTTP requests"
summary="Configure the client used for outgoing HTTP requests."
includedOptions="truststore-*">

{project_name} often needs to make requests to the applications and services that it secures. {project_name} manages these outgoing connections using an HTTP client. This {section} shows how to configure the client, connection pool, proxy environment settings, timeouts, and more.

== Configuring trusted certificates for TLS connections

See <@links.server id="keycloak-truststore"/> for how
to configure a {project_name} Truststore so that {project_name} is able to perform outgoing requests using TLS.

== Client Configuration Command
The HTTP client that {project_name} uses for outgoing communication is highly configurable. To configure the {project_name} outgoing HTTP client, enter this command:

<@kc.start parameters="--spi-connections-http-client--default--<configurationoption>=<value>"/>

The following are the command options:

*establish-connection-timeout-millis*::
Maximum time in milliseconds until establishing a connection times out. Default: Not set.

*connection-request-timeout-millis*::
Maximum time in milliseconds to obtain a connection for a request. Default: 5000ms

*socket-timeout-millis*::
Maximum time of inactivity between two data packets until a socket connection times out, in milliseconds. Default: 5000ms

*connection-pool-size*::
Size of the connection pool for outgoing connections. Default: 128.

*max-pooled-per-route*::
How many connections can be pooled per host. Default: 64.

*connection-ttl-millis*::
Maximum connection time to live in milliseconds. Default: Not set.

*max-connection-idle-time-millis*::
Maximum time an idle connection stays in the connection pool, in milliseconds. Idle connections will be removed from the pool by a background cleaner thread. Set this option to -1 to disable this check. Default: 900000.

*disable-cookies*::
Enable or disable caching of cookies. Default: true.

*client-keystore*::
File path to a Java keystore file. This keystore contains client certificates for mTLS.

*client-keystore-password*::
Password for the client keystore. REQUIRED, when `client-keystore` is set.

*client-key-password*::
Password for the private key of the client. REQUIRED, when client-keystore is set.

*proxy-mappings*::
Specify proxy configurations for outgoing HTTP requests. For more details, see <<Proxy mappings for outgoing HTTP requests>>.

*disable-trust-manager*::
If an outgoing request requires HTTPS and this configuration option is set to true, you do not have to specify a truststore. This setting should be used only during development and *never in production* because it will disable verification of SSL certificates. Default: false.

== Configuring retry behavior for outgoing HTTP requests
IMPORTANT: Do not let outgoing retry duration exceed the caller’s timeout. Otherwise, the caller may time out and see an error while {project_name} continues retrying in the background.

{project_name} can automatically retry failed outgoing HTTP requests. This is useful for handling transient network errors or temporary service unavailability. Retry behavior is disabled by default and must be explicitly enabled.

The following are the retry configuration options:

*max-retries*::
Maximum number of retry attempts for failed HTTP requests. Set to 0 to disable retries. Default: 0.

NOTE: Retries for requests that have already been sent (for common methods such as GET and POST) are always enabled. Use `max-retries` to control whether retries are performed.

*initial-backoff-millis*::
Initial backoff time in milliseconds before the first retry attempt. Default: 1000.

*backoff-multiplier*::
Multiplier for exponential backoff between retry attempts. For example, with an initial backoff of 1000ms and a multiplier of 2.0, the retry delays would be: 1000ms, 2000ms, 4000ms, etc. Default: 2.0.

*use-jitter*::
Whether to apply jitter to backoff times to prevent synchronized retry storms when multiple clients are retrying at the same time. Default: true.

*jitter-factor*::
Jitter factor to apply to backoff times. A value of 0.5 means the actual backoff time will be between 50% and 150% of the calculated exponential backoff time. Default: 0.5.

.Example of enabling retry behavior
[source,bash]
----
bin/kc.[sh|bat] start --spi-connections-http-client-default-max-retries=3 \
  --spi-connections-http-client-default-initial-backoff-millis=1000 \
  --spi-connections-http-client-default-backoff-multiplier=2.0
----

In this example, {project_name} will retry failed HTTP requests up to 3 times with exponential backoff starting at 1000ms and doubling with each retry attempt.

NOTE: Retry behavior applies to all outgoing HTTP requests made by {project_name}, including OCSP validation, identity provider communication, and other external service calls.

== Proxy mappings for outgoing HTTP requests
To configure outgoing requests to use a proxy, you can use the following standard proxy environment variables to configure the proxy mappings: `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`.

* The `HTTP_PROXY` and `HTTPS_PROXY` variables represent the proxy server that is used for outgoing HTTP requests. {project_name} does not differentiate between the two variables. If you define both variables, `HTTPS_PROXY` takes precedence regardless of the actual scheme that the proxy server uses.

* The `NO_PROXY` variable defines a comma separated list of hostnames that should not use the proxy. For each hostname that you specify, all its subdomains are also excluded from using proxy.

The environment variables can be lowercase or uppercase. Lowercase takes precedence. For example, if you define both `HTTP_PROXY` and `http_proxy`, `http_proxy` is used.

.Example of proxy mappings and environment variables
[source]
----
HTTPS_PROXY=https://www-proxy.acme.com:8080
NO_PROXY=google.com,login.facebook.com
----
In this example, the following results occur:

* All outgoing requests use the proxy `https://www-proxy.acme.com:8080` except for requests to google.com or any subdomain of google.com, such as auth.google.com.
* login.facebook.com and all its subdomains do not use the defined proxy, but groups.facebook.com uses the proxy because it is not a subdomain of login.facebook.com.

== Proxy mappings using regular expressions

An alternative to using environment variables for proxy mappings is to configure a comma-delimited list of proxy-mappings for outgoing requests sent by {project_name}. A proxy-mapping consists of a regex-based hostname pattern and a proxy-uri, using the format `hostname-pattern;proxy-uri`.

For example, consider the following regex:

[source]
----
.*\.(google|googleapis)\.com
----

You apply a regex-based hostname pattern by entering this command:

<@kc.start parameters="--spi-connections-http-client--default--proxy-mappings=\'.*\\\\.(google|googleapis)\\\\.com;http://www-proxy.acme.com:8080\'"/>

The backslash character `\` is escaped again because micro-profile config is used to parse the array of mappings.

To determine the proxy for the outgoing HTTP request, the following occurs:

* The target hostname is matched against all configured hostname patterns.
* The proxy-uri of the first matching pattern is used.
* If no configured pattern matches the hostname, no proxy is used.

When your proxy server requires authentication, include the credentials of the proxy user in the format `username:password@`. For example:

[source]
----
.*\.(google|googleapis)\.com;http://proxyuser:password@www-proxy.acme.com:8080
----

.Example of regular expressions for proxy-mapping:
[source]
----
# All requests to Google APIs use http://www-proxy.acme.com:8080 as proxy
.*\.(google|googleapis)\.com;http://www-proxy.acme.com:8080

# All requests to internal systems use no proxy
.*\.acme\.com;NO_PROXY

# All other requests use http://fallback:8080 as proxy
.*;http://fallback:8080
----

In this example, the following occurs:

* The special value NO_PROXY for the proxy-uri is used, which means that no proxy is used for hosts matching the associated hostname pattern.
* A catch-all pattern ends the proxy-mappings, providing a default proxy for all outgoing requests.

</@tmpl.guide>
