//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ========================================================================
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================

[[http-client-proxy]]
=== Proxy Support

Jetty's HTTP client 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`).
Other implementations may be written by subclassing `ProxyConfiguration.Proxy`.

The following is a typical configuration:

[source, java, subs="{sub-order}"]
----
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);
----

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.

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).

[[http-client-proxy-authentication]]
==== Proxy Authentication Support

Jetty's HTTP client support proxy authentication in the same way it supports link:#http-client-authentication[server authentication].

In the example below, the proxy requires Basic authentication, but the server requires Digest authentication, and therefore:

[source, java, subs="{sub-order}"]
----
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);
----

The HTTP conversation for successful authentications on both the proxy and the server is the following:

----
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 ----------|
----

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:#http-client-authentication[authentication section], the proxy authentication result and the server authentication result can be preempted to avoid, respectively, the 407 and 401 roundtrips.
