//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

[[http-client-intro]]
=== Introduction

The Jetty HTTP client module provides easy-to-use APIs and utility classes to perform HTTP (or HTTPS) requests.

Jetty's HTTP client is non-blocking and asynchronous.
It offers an asynchronous API that never blocks for I/O, making it very efficient in thread utilization and well suited for high performance scenarios such as load testing or parallel computation.

However, when all you need to do is to perform a `GET` request to a resource, Jetty's HTTP client offers also a synchronous API; a programming interface
where the thread that issued the request blocks until the request/response conversation is complete.

Jetty's HTTP client supports different link:#http-client-transport[transports]: HTTP/1.1, FastCGI and HTTP/2.
This means that the semantic of a HTTP request (that is, " `GET` me the resource `/index.html` ") can be carried over the network in different formats.
The most common and default format is HTTP/1.1.
That said, Jetty's HTTP client can carry the same request using the FastCGI format or the new HTTP/2 format.

The FastCGI transport is heavily used in Jetty's link:#fastcgi[FastCGI support] that allows Jetty to work as a reverse proxy to PHP (exactly like Apache or Nginx do) and therefore be able to serve - for example - WordPress websites.

The HTTP/2 transport allows Jetty's HTTP client to perform requests using HTTP/2 to HTTP/2 enabled web sites, see also Jetty's link:#http2[HTTP/2 support].

Out of the box features that you get with the Jetty HTTP client include:

* Redirect support - redirect codes such as 302 or 303 are automatically followed.
* Cookies support - cookies sent by servers are stored and sent back to servers in matching requests.
* Authentication support - HTTP "Basic" and "Digest" authentications are supported, others are pluggable.
* Forward proxy support - HTTP proxying and SOCKS4 proxying.

[[http-client-init]]
==== Starting HttpClient

The main class is named `org.eclipse.jetty.client.HttpClient`.

You can think of a `HttpClient` instance as a browser instance.
Like a browser it can make requests to different domains, it manages redirects, cookies and authentication, you can configure it with a proxy, and
it provides you with the responses to the requests you make.

In order to use `HttpClient`, you must instantiate it, configure it, and then start it:

[source, java, subs="{sub-order}"]
----
// Instantiate HttpClient
HttpClient httpClient = new HttpClient();

// Configure HttpClient, for example:
httpClient.setFollowRedirects(false);

// Start HttpClient
httpClient.start();
----

You may create multiple instances of `HttpClient`, but typically one instance is enough for an application.
There are several reasons for having multiple `HttpClient` instances including, but not limited to:

* You want to specify different configuration parameters (for example, one instance is configured with a forward proxy while another is not)
* You want the two instances to behave like two different browsers and hence have different cookies, different authentication credentials...etc.
* You want to use different transports

When you create a `HttpClient` instance using the parameterless constructor, you will only be able to perform plain HTTP requests and you will not be able to perform HTTPS requests.

In order to perform HTTPS requests, you should create first a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.Client.html[`SslContextFactory.Client`], configure it, and pass it to the `HttpClient` constructor.
When created with a `SslContextFactory`, the `HttpClient` will be able to perform both HTTP and HTTPS requests to any domain.

[source, java, subs="{sub-order}"]
----
// Instantiate and configure the SslContextFactory
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();

// Instantiate HttpClient with the SslContextFactory
HttpClient httpClient = new HttpClient(sslContextFactory);

// Configure HttpClient, for example:
httpClient.setFollowRedirects(false);

// Start HttpClient
httpClient.start();
----

==== Stopping HttpClient

It is recommended that when your application stops, you also stop the `HttpClient` instance (or instances) that you are using.

[source, java, subs="{sub-order}"]
----
httpClient.stop();
----

Stopping `HttpClient` makes sure that the memory it holds (for example, authentication credentials, cookies, etc.) is released, and that the thread pool and scheduler are properly stopped allowing all threads used by `HttpClient` to exit.
