//  ========================================================================
//  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-api]]
=== API Usage

[[http-client-blocking]]
==== Blocking APIs

The simple way to perform a HTTP request is the following:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.GET("http://domain.com/path?query");
----

The method `HttpClient.GET(...)` performs a HTTP `GET` request to the given URI and returns a `ContentResponse` when the request/response conversation completes successfully.

The `ContentResponse` object contains the HTTP response information: status code, headers and possibly content.
The content length is limited by default to 2 MiB; for larger content see xref:http-client-response-content[].

If you want to customize the request, for example by issuing a `HEAD` request instead of a `GET`, and simulating a browser user agent, you can do it in this way:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/path?query")
        .method(HttpMethod.HEAD)
        .agent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0")
        .send();
----

This is a shorthand for:

[source, java, subs="{sub-order}"]
----
Request request = httpClient.newRequest("http://domain.com/path?query");
request.method(HttpMethod.HEAD);
request.agent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0");
ContentResponse response = request.send();
----

You first create a request object using `httpClient.newRequest(...)`, and then you customize it using the fluent API style (that is, a chained invocation of methods on the request object).
When the request object is customized, you call `request.send()` that produces the `ContentResponse` when the request/response conversation is complete.

Simple `POST` requests also have a shortcut method:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.POST("http://domain.com/entity/1")
        .param("p", "value")
        .send();
----

The `POST` parameter values added via the `param()` method are automatically URL-encoded.

Jetty's HTTP client automatically follows redirects, so it handles the typical web pattern http://en.wikipedia.org/wiki/Post/Redirect/Get[POST/Redirect/GET], and the response object contains the content of the response of the `GET` request.
Following redirects is a feature that you can enable/disable on a per-request basis or globally.

File uploads also require one line, and make use of JDK 7′s `java.nio.file` classes:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .file(Paths.get("file_to_upload.txt"), "text/plain")
        .send();
----

It is possible to impose a total timeout for the request/response conversation using the `Request.timeout(...)` method as follows:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/path?query")
        .timeout(5, TimeUnit.SECONDS)
        .send();
----

In the example above, when the 5 seconds expire, the request is aborted and a `java.util.concurrent.TimeoutException` is thrown.

[[http-client-async]]
==== Non-Blocking APIs

So far we have shown how to use Jetty HTTP client in a blocking style - that is, the thread that issues the request blocks until the request/response conversation is complete.

This section will look at Jetty's HTTP client non-blocking, asynchronous APIs that are perfectly suited for large content downloads, for parallel processing of requests/responses and in cases where performance and efficient thread and resource utilization is a key factor.

The asynchronous APIs rely heavily on listeners that are invoked at various stages of request and response processing.
These listeners are implemented by applications and may perform any kind of logic.
The implementation invokes these listeners in the same thread that is used to process the request or response.
Therefore, if the application code in these listeners takes a long time to execute, the request or response processing is delayed until the listener returns.

If you need to execute application code that takes long time inside a listener, you must spawn your own thread and remember to deep copy any data provided by the listener that you will need in your code, because when the listener returns the data it provides may be recycled/cleared/destroyed.

Request and response processing are executed by two different threads and therefore may happen concurrently.
A typical example of this concurrent processing is an echo server, where a large upload may be concurrent with the large download echoed back.
As a side note, remember that responses may be processed and completed _before_ requests; a typical example is a large upload that triggers a quick response - for example an error - by the server: the response may arrive and be completed while the request content is still being uploaded.

The application thread that calls `Request.send(Response.CompleteListener)` performs the processing of the request until either the request is fully processed or until it would block on I/O, then it returns (and therefore never blocks).
If it would block on I/O, the thread asks the I/O system to emit an event when the I/O will be ready to continue, then returns.
When such an event is fired, a thread taken from the `HttpClient` thread pool will resume the processing of the request.

Response are processed from the I/O thread that fires the event that bytes are ready to be read.
Response processing continues until either the response is fully processed or until it would block for I/O.
If it would block for I/O, the thread asks the I/O system to emit an event when the I/O will be ready to continue, then returns.
When such an event is fired, a thread taken from the `HttpClient` thread pool will resume the processing of the response.

When the request and the response are both fully processed, the thread that finished the last processing (usually the thread that processes the response, but may also be the thread that processes the request - if the request takes more time than the response to be processed) is used to de-queue the next request for the same destination and processes it.

A simple asynchronous `GET` request that discards the response content can be written in this way:

[source, java, subs="{sub-order}"]
----
httpClient.newRequest("http://domain.com/path")
        .send(new Response.CompleteListener()
        {
            @Override
            public void onComplete(Result result)
            {
                // Your logic here
            }
        });
----

Method `Request.send(Response.CompleteListener)` returns `void` and does not block; the `Response.CompleteListener` provided as a parameter is notified when the request/response conversation is complete, and the `Result` parameter allows you to access the response object.

You can write the same code using JDK 8′s lambda expressions:

[source, java, subs="{sub-order}"]
----
httpClient.newRequest("http://domain.com/path")
        .send(result -> { /* Your logic here */ });
----

You can impose a total timeout for the request/response conversation in the same way used by the synchronous API:

[source, java, subs="{sub-order}"]
----
Request request = httpClient.newRequest("http://domain.com/path")
        .timeout(3, TimeUnit.SECONDS)
        .send(result -> { /* Your logic here */ });
----

The example above will impose a total timeout of 3 seconds on the request/response conversation.

The HTTP client APIs use listeners extensively to provide hooks for all possible request and response events, and with JDK 8′s lambda expressions they are even more fun to use:

[source, java, subs="{sub-order}"]
----
httpClient.newRequest("http://domain.com/path")
        // Add request hooks
        .onRequestQueued(request -> { ... })
        .onRequestBegin(request -> { ... })
        ... // More request hooks available

        // Add response hooks
        .onResponseBegin(response -> { ... })
        .onResponseHeaders(response -> { ... })
        .onResponseContent((response, buffer) -> { ... })
        ... // More response hooks available

        .send(result -> { ... });
----

This makes Jetty HTTP client suitable for HTTP load testing because, for example, you can accurately time every step of the request/response conversation (thus knowing where the request/response time is really spent).

Have a look at the link:{JDURL}/org/eclipse/jetty/client/api/Request.Listener.html[`Request.Listener`] class to know about request events, and to the link:{JDURL}/org/eclipse/jetty/client/api/Response.Listener.html[`Response.Listener`] class to know about response events.

[[http-client-content]]
==== Content Handling

[[http-client-request-content]]
===== Request Content Handling

Jetty's HTTP client provides a number of utility classes off the shelf to handle request content.

You can provide request content as `String`, `byte[]`, `ByteBuffer`, `java.nio.file.Path`, `InputStream`, and provide your own implementation of `org.eclipse.jetty.client.api.ContentProvider`.
Here’s an example that provides the request content using `java.nio.file.Paths`:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .file(Paths.get("file_to_upload.txt"), "text/plain")
        .send();
----

This is equivalent to using the `PathContentProvider` utility class:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .content(new PathContentProvider(Paths.get("file_to_upload.txt")), "text/plain")
        .send();
----

Alternatively, you can use `FileInputStream` via the `InputStreamContentProvider` utility class:

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .content(new InputStreamContentProvider(new FileInputStream("file_to_upload.txt")), "text/plain")
        .send();
----

Since `InputStream` is blocking, then also the send of the request will block if the input stream blocks, even in case of usage of the asynchronous `HttpClient` APIs.

If you have already read the content in memory, you can pass it as a `byte[]` using the `BytesContentProvider` utility class:

[source, java, subs="{sub-order}"]
----
byte[] bytes = ...;
ContentResponse response = httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .content(new BytesContentProvider(bytes), "text/plain")
        .send();
----

If the request content is not immediately available, but your application will be notified of the content to send, you can use `DeferredContentProvider` in this way:

[source, java, subs="{sub-order}"]
----
DeferredContentProvider content = new DeferredContentProvider();
httpClient.newRequest("http://domain.com/upload")
        .method(HttpMethod.POST)
        .content(content)
        .send(new Response.CompleteListener()
        {
            @Override
            public void onComplete(Result result)
            {
                // Your logic here
            }
        });

// Content not available yet here

...

// An event happens, now content is available
byte[] bytes = ...;
content.offer(ByteBuffer.wrap(bytes));

...

// All content has arrived
content.close();
----

While the request content is awaited and consequently uploaded by the client application, the server may be able to respond (at least with the response headers) completely asynchronously.
In this case, `Response.Listener` callbacks will be invoked before the request is fully sent.
This allows fine-grained control of the request/response conversation: for example the server may reject contents that are too big, send a response to the client, which in turn may stop the content upload.

Another way to provide request content is by using an `OutputStreamContentProvider`,
which allows applications to write request content when it is available to the `OutputStream` provided by `OutputStreamContentProvider`:

[source, java, subs="{sub-order}"]
----
OutputStreamContentProvider content = new OutputStreamContentProvider();

// Use try-with-resources to close the OutputStream when all content is written
try (OutputStream output = content.getOutputStream())
{
    client.newRequest("localhost", 8080)
            .method(HttpMethod.POST)
            .content(content)
            .send(new Response.CompleteListener()
            {
                @Override
                public void onComplete(Result result)
                {
                    // Your logic here
                }
            });

    ...

    // Write content
    writeContent(output);
}
// End of try-with-resource, output.close() called automatically to signal end of content
----

[[http-client-response-content]]
===== Response Content Handling

Jetty HTTP client allows applications to handle response content in different ways.

The first way is to buffer the response content in memory; this is done when using the blocking APIs (see xref:http-client-blocking[]) and the content is buffered within a `ContentResponse` up to 2 MiB.

If you want to control the length of the response content (for example limiting to values smaller than the default of 2 MiB), then you can use a `org.eclipse.jetty.client.util.FutureResponseListener` in this way:

[source, java, subs="{sub-order}"]
----
Request request = httpClient.newRequest("http://domain.com/path");

// Limit response content buffer to 512 KiB
FutureResponseListener listener = new FutureResponseListener(request, 512 * 1024);

request.send(listener);

ContentResponse response = listener.get(5, TimeUnit.SECONDS);
----

If the response content length is exceeded, the response will be aborted, and an exception will be thrown by method `get()`.

If you are using the asynchronous APIs (see xref:http-client-async[]), you can use the `BufferingResponseListener` utility class:

[source, java, subs="{sub-order}"]
----
httpClient.newRequest("http://domain.com/path")
        // Buffer response content up to 8 MiB
        .send(new BufferingResponseListener(8 * 1024 * 1024)
        {
            @Override
            public void onComplete(Result result)
            {
                if (!result.isFailed())
                {
                    byte[] responseContent = getContent();
                    // Your logic here
                }
            }
        });
----

The second way is the most efficient (because it avoids content copies) and allows you to specify a `Response.ContentListener`, or a subclass, to handle the content as soon as it arrives.
In the example below, `Response.Listener.Adapter` is a class that implements both `Response.ContentListener` and `Response.CompleteListener` and can be passed to `Request.send()`.
Jetty's HTTP client will invoke the `onContent()` method zero or more times (until there is content), and finally invoke the `onComplete()` method.

[source, java, subs="{sub-order}"]
----
ContentResponse response = httpClient
        .newRequest("http://domain.com/path")
        .send(new Response.Listener.Adapter()
        {
            @Override
            public void onContent(Response response, ByteBuffer buffer)
            {
                // Your logic here
            }
        });
----

The third way allows you to wait for the response and then stream the content using the `InputStreamResponseListener` utility class:

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

InputStreamResponseListener listener = new InputStreamResponseListener();
httpClient.newRequest("http://domain.com/path")
        .send(listener);

// Wait for the response headers to arrive
Response response = listener.get(5, TimeUnit.SECONDS);

// Look at the response
if (response.getStatus() == HttpStatus.OK_200)
{
    // Use try-with-resources to close input stream.
    try (InputStream responseContent = listener.getInputStream())
    {
        // Your logic here
    }
}
----
