Improvements to the Jetty client documentation, proxy section.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2020-04-02 13:22:54 +02:00
parent 9f38e433d4
commit eaf9d43a0b
2 changed files with 96 additions and 60 deletions

View File

@ -17,87 +17,76 @@
//
[[client-http-proxy]]
=== Proxy Support
=== HttpClient Proxy Support
Jetty's HTTP client can be configured to use proxies to connect to destinations.
Jetty's `HttpClient` can be configured to use proxies to connect to destinations.
Two types of proxies are available out of the box: a HTTP proxy (provided by class `org.eclipse.jetty.client.HttpProxy`) and a SOCKS 4 proxy (provided by class `org.eclipse.jetty.client.Socks4Proxy`).
Two types of proxies are available out of the box: a HTTP proxy (provided by
class `org.eclipse.jetty.client.HttpProxy`) and a SOCKS 4 proxy (provided by
class `org.eclipse.jetty.client.Socks4Proxy`).
Other implementations may be written by subclassing `ProxyConfiguration.Proxy`.
The following is a typical configuration:
[source, java, subs="{sub-order}"]
[source,java,indent=0]
----
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy("proxyHost", proxyPort);
// Do not proxy requests for localhost:8080
proxy.getExcludedAddresses().add("localhost:8080");
// add the new proxy to the list of proxies already registered
proxyConfig.getProxies().add(proxy);
ContentResponse response = httpClient.GET(uri);
include::../../{doc_code}/embedded/client/http/HTTPClientDocs.java[tag=proxy]
----
You specify the proxy host and port, and optionally also the addresses that you do not want to be proxied, and then add the proxy configuration on the `ProxyConfiguration` instance.
You specify the proxy host and proxy port, and optionally also the addresses
that you do not want to be proxied, and then add the proxy configuration on
the `ProxyConfiguration` instance.
Configured in this way, `HttpClient` makes requests to the HTTP proxy (for plain-text HTTP requests) or establishes a tunnel via `HTTP CONNECT` (for encrypted HTTPS requests).
Configured in this way, `HttpClient` makes requests to the HTTP proxy (for
plain-text HTTP requests) or establishes a tunnel via HTTP `CONNECT` (for
encrypted HTTPS requests).
Proxying is supported for both HTTP/1.1 and HTTP/2.
[[client-http-proxy-authentication]]
==== Proxy Authentication Support
Jetty's HTTP client support proxy authentication in the same way it supports link:#client-http-authentication[server authentication].
Jetty's `HttpClient` supports proxy authentication in the same way it supports
link:#client-http-authentication[server authentication].
In the example below, the proxy requires Basic authentication, but the server requires Digest authentication, and therefore:
In the example below, the proxy requires `BASIC` authentication, but the server
requires `DIGEST` authentication, and therefore:
[source, java, subs="{sub-order}"]
[source,java,indent=0]
----
URI proxyURI = new URI("http://proxy.net:8080");
URI serverURI = new URI("http://domain.com/secure");
AuthenticationStore auth = httpClient.getAuthenticationStore();
// Proxy credentials.
auth.addAuthentication(new BasicAuthentication(proxyURI, "ProxyRealm", "proxyUser", "proxyPass"));
// Server credentials.
auth.addAuthentication(new DigestAuthentication(serverURI, "ServerRealm", "serverUser", "serverPass"));
// Proxy configuration.
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy("proxy.net", 8080);
proxyConfig.getProxies().add(proxy);
ContentResponse response = httpClient.newRequest(serverURI)
.send()
.get(5, TimeUnit.SECONDS);
include::../../{doc_code}/embedded/client/http/HTTPClientDocs.java[tag=proxyAuthentication]
----
The HTTP conversation for successful authentications on both the proxy and the server is the following:
The HTTP conversation for successful authentications on both the proxy and the
server is the following:
[plantuml]
----
Application HttpClient Proxy Server
| | | |
|--- GET -->|------------- GET ------------->| |
| | | |
| |<----- 407 + Proxy-Authn -------| |
| | | |
| |------ GET + Proxy-Authz ------>| |
| | | |
| | |---------- GET --------->|
| | | |
| | |<--- 401 + WWW-Authn ----|
| | | |
| |<------ 401 + WWW-Authn --------| |
| | | |
| |-- GET + Proxy-Authz + Authz -->| |
| | | |
| | |------ GET + Authz ----->|
| | | |
|<-- 200 ---|<------------ 200 --------------|<--------- 200 ----------|
skinparam backgroundColor transparent
skinparam monochrome true
skinparam shadowing false
participant Application
participant HttpClient
participant Proxy
participant Server
Application -> Proxy: GET /path
Proxy -> HttpClient: 407 + Proxy-Authenticate
HttpClient -> Proxy: GET /path + Proxy-Authorization
Proxy -> Server: GET /path
Server -> Proxy: 401 + WWW-Authenticate
Proxy -> HttpClient: 401 + WWW-Authenticate
HttpClient -> Proxy: GET /path + Proxy-Authorization + Authorization
Proxy -> Server: GET /path + Authorization
Server -> Proxy: 200 OK
Proxy -> HttpClient: 200 OK
HttpClient -> Application: 200 OK
----
The application does not receive events related to the responses with code 407 and 401 since they are handled internally by `HttpClient`.
The application does not receive events related to the responses with code 407
and 401 since they are handled internally by `HttpClient`.
Similarly to the link:#client-http-authentication[authentication section], the proxy authentication result and the server authentication result can be preempted to avoid, respectively, the 407 and 401 roundtrips.
Similarly to the link:#client-http-authentication[authentication section], the
proxy authentication result and the server authentication result can be
preempted to avoid, respectively, the 407 and 401 roundtrips.

View File

@ -32,6 +32,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.LongConsumer;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.ProxyConfiguration;
import org.eclipse.jetty.client.api.Authentication;
import org.eclipse.jetty.client.api.AuthenticationStore;
import org.eclipse.jetty.client.api.ContentResponse;
@ -43,6 +45,7 @@ import org.eclipse.jetty.client.util.AsyncRequestContent;
import org.eclipse.jetty.client.util.BasicAuthentication;
import org.eclipse.jetty.client.util.BufferingResponseListener;
import org.eclipse.jetty.client.util.BytesRequestContent;
import org.eclipse.jetty.client.util.DigestAuthentication;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.client.util.InputStreamRequestContent;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
@ -619,4 +622,48 @@ public class HTTPClientDocs
request.send();
// end::requestPreemptedResult[]
}
public void proxy() throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.start();
// tag::proxy[]
HttpProxy proxy = new HttpProxy("proxyHost", 8888);
// Do not proxy requests for localhost:8080.
proxy.getExcludedAddresses().add("localhost:8080");
// Add the new proxy to the list of proxies already registered.
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
proxyConfig.getProxies().add(proxy);
ContentResponse response = httpClient.GET("http://domain.com/path");
// end::proxy[]
}
public void proxyAuthentication() throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.start();
// tag::proxyAuthentication[]
AuthenticationStore auth = httpClient.getAuthenticationStore();
// Proxy credentials.
URI proxyURI = new URI("http://proxy.net:8080");
auth.addAuthentication(new BasicAuthentication(proxyURI, "ProxyRealm", "proxyUser", "proxyPass"));
// Server credentials.
URI serverURI = new URI("http://domain.com/secure");
auth.addAuthentication(new DigestAuthentication(serverURI, "ServerRealm", "serverUser", "serverPass"));
// Proxy configuration.
ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
HttpProxy proxy = new HttpProxy("proxy.net", 8080);
proxyConfig.getProxies().add(proxy);
ContentResponse response = httpClient.newRequest(serverURI).send();
// end::proxyAuthentication[]
}
}