//  ========================================================================
//  Copyright (c) 1995-2016 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-other]]
=== Other Features

[[http-client-cookie]]
==== Cookies Support

Jetty HTTP client supports cookies out of the box.
The `HttpClient` instance receives cookies from HTTP responses and stores them in a `java.net.CookieStore`, a class that is part of the JDK.
When new requests are made, the cookie store is consulted and if there are matching cookies (that is, cookies that are not expired and that match domain and path of the request) then they are added to the requests.

Applications can programmatically access the cookie store to find the cookies that have been set:

[source, java, subs="{sub-order}"]
----

CookieStore cookieStore = httpClient.getCookieStore();
List<HttpCookie> cookies = cookieStore.get(URI.create("http://domain.com/path"));

      
----

Applications can also programmatically set cookies as if they were returned from a HTTP response:

[source, java, subs="{sub-order}"]
----

CookieStore cookieStore = httpClient.getCookieStore();
HttpCookie cookie = new HttpCookie("foo", "bar");
cookie.setDomain("domain.com");
cookie.setPath("/");
cookie.setMaxAge(TimeUnit.DAYS.toSeconds(1));
cookieStore.add(URI.create("http://domain.com"), cookie);

      
----

You can remove cookies that you do not want to be sent in future HTTP requests:

[source, java, subs="{sub-order}"]
----

CookieStore cookieStore = httpClient.getCookieStore();
URI uri = URI.create("http://domain.com");
List<HttpCookie> cookies = cookieStore.get(uri);
for (HttpCookie cookie : cookies)
    cookieStore.remove(uri, cookie);

      
----

If you want to totally disable cookie handling, you can install a `HttpCookieStore.Empty` instance in this way:

[source, java, subs="{sub-order}"]
----

httpClient.setCookieStore(new HttpCookieStore.Empty());

      
----

You can enable cookie filtering by installing a cookie store that performs the filtering logic in this way:

[source, java, subs="{sub-order}"]
----

httpClient.setCookieStore(new GoogleOnlyCookieStore());

public class GoogleOnlyCookieStore extends HttpCookieStore
{
    @Override
    public void add(URI uri, HttpCookie cookie)
    {
        if (uri.getHost().endsWith("google.com"))
            super.add(uri, cookie);
    }
}

      
----

The example above will retain only cookies that come from the `google.com` domain or sub-domains.

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

Jetty HTTP client supports the "Basic" and "Digest" authentication mechanisms defined by http://www.ietf.org/rfc/rfc2617.txt[RFC 2617].

You can configure authentication credentials in the HTTP client instance as follows:

[source, java, subs="{sub-order}"]
----

URI uri = new URI("http://domain.com/secure");
String realm = "MyRealm";
String user = "username";
String pass = "password";

// Add authentication credentials
AuthenticationStore auth = httpClient.getAuthenticationStore();
auth.addAuthentication(new BasicAuthentication(uri, realm, user, pass));

ContentResponse response = httpClient
        .newRequest(uri)
        .send()
        .get(5, TimeUnit.SECONDS);

      
----

Jetty HTTP client tests authentication credentials against the challenge(s) the server issues, and if they match it automatically sends the right authentication headers to the server for authentication.
If the authentication is successful, it caches the result and reuses it for subsequent requests for the same domain and matching URIs.

Successful authentications are cached, but it is possible to clear them in order to force authentication again:

[source, java, subs="{sub-order}"]
----

httpClient.getAuthenticationStore().clearAuthenticationResults();

      
----

[[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`.

A typical configuration is the following:

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