Merge branch 'jetty-9.3.x' into jetty-9.4.x
This commit is contained in:
commit
0ecc8caff6
|
@ -20,7 +20,7 @@
|
||||||
JConsole and the Java Mission Control (JMX) are graphical tools; they allow you to remotely manage and monitor your server and web application status using JMX.
|
JConsole and the Java Mission Control (JMX) are graphical tools; they allow you to remotely manage and monitor your server and web application status using JMX.
|
||||||
When following the instructions given below, please also ensure that you make any necessary changes to any anti-virus software you may be using which may prevent JConsole or JMC from running.
|
When following the instructions given below, please also ensure that you make any necessary changes to any anti-virus software you may be using which may prevent JConsole or JMC from running.
|
||||||
|
|
||||||
===== Starting Jetty Standalone
|
==== Starting Jetty Standalone
|
||||||
|
|
||||||
The simplest way to enable support is to add the JMX-Remote support module to your `{$jetty.base}`.
|
The simplest way to enable support is to add the JMX-Remote support module to your `{$jetty.base}`.
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ context.setAttribute("org.eclipse.jetty.webapp.basetempdir", "/tmp/foo");
|
||||||
|
|
||||||
There are several ways to use a particular directory as the temporary directory:
|
There are several ways to use a particular directory as the temporary directory:
|
||||||
|
|
||||||
====== Call WebAppContext.setTempDirectory(String dir)
|
===== Call WebAppContext.setTempDirectory(String dir)
|
||||||
As before this can be accomplished with an xml file or directly in code. Here's an example of setting the temp directory in xml:
|
As before this can be accomplished with an xml file or directly in code. Here's an example of setting the temp directory in xml:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
|
@ -101,7 +101,7 @@ context.setWar("foo.war");
|
||||||
context.setTempDirectory(new File("/some/dir/foo"));
|
context.setTempDirectory(new File("/some/dir/foo"));
|
||||||
----
|
----
|
||||||
|
|
||||||
====== Set the javax.servlet.context.tempdir context attribute
|
===== Set the javax.servlet.context.tempdir context attribute
|
||||||
You should set this context attribute with the name of directory you want to use as the temp directory. Again, you can do this in xml:
|
You should set this context attribute with the name of directory you want to use as the temp directory. Again, you can do this in xml:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
|
|
|
@ -20,25 +20,19 @@
|
||||||
[[http-client-blocking]]
|
[[http-client-blocking]]
|
||||||
==== Blocking APIs
|
==== Blocking APIs
|
||||||
|
|
||||||
The simpler way to perform a HTTP request is the following:
|
The simple way to perform a HTTP request is the following:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
ContentResponse response = httpClient.GET("http://domain.com/path?query");
|
ContentResponse response = httpClient.GET("http://domain.com/path?query");
|
||||||
----
|
----
|
||||||
|
|
||||||
Method `HttpClient.GET(...)` performs a HTTP GET request to the given URI and
|
The method `HttpClient.GET(...)` performs a HTTP `GET` request to the given URI and returns a `ContentResponse` when the request/response conversation completes successfully.
|
||||||
returns a `ContentResponse` when the request/response conversation completes
|
|
||||||
successfully.
|
|
||||||
|
|
||||||
The `ContentResponse` object contains the HTTP response information: status
|
The `ContentResponse` object contains the HTTP response information: status code, headers and possibly content.
|
||||||
code, headers and possibly a content.
|
The content length is limited by default to 2 MiB; for larger content see xref:http-client-response-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
|
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:
|
||||||
instead of a GET, and simulating a browser user agent, you can do it in this
|
|
||||||
way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -58,13 +52,10 @@ request.agent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 F
|
||||||
ContentResponse response = request.send();
|
ContentResponse response = request.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
You first create a request object using `httpClient.newRequest(...)`, and then
|
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).
|
||||||
you customize it using the fluent API style (that is, chained invocation of
|
When the request object is customized, you call `request.send()` that produces the `ContentResponse` when the request/response conversation is complete.
|
||||||
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:
|
Simple `POST` requests also have a shortcut method:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -73,14 +64,10 @@ ContentResponse response = httpClient.POST("http://domain.com/entity/1")
|
||||||
.send();
|
.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
The POST parameter values added via the `param()` method are automatically
|
The `POST` parameter values added via the `param()` method are automatically URL-encoded.
|
||||||
URL-encoded.
|
|
||||||
|
|
||||||
Jetty's HTTP client automatically follows redirects, so automatically handles
|
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.
|
||||||
the typical web pattern http://en.wikipedia.org/wiki/Post/Redirect/Get[POST/Redirect/GET],
|
Following redirects is a feature that you can enable/disable on a per-request basis or globally.
|
||||||
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:
|
File uploads also require one line, and make use of JDK 7′s `java.nio.file` classes:
|
||||||
|
|
||||||
|
@ -92,8 +79,7 @@ ContentResponse response = httpClient.newRequest("http://domain.com/upload")
|
||||||
.send();
|
.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
It is possible to impose a total timeout for the request/response conversation
|
It is possible to impose a total timeout for the request/response conversation using the `Request.timeout(...)` method as follows:
|
||||||
using the `Request.timeout(...)` method, in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -102,69 +88,38 @@ ContentResponse response = httpClient.newRequest("http://domain.com/path?query")
|
||||||
.send();
|
.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
In the example above, when the 5 seconds expire, the request is aborted and a
|
In the example above, when the 5 seconds expire, the request is aborted and a `java.util.concurrent.TimeoutException` is thrown.
|
||||||
`java.util.concurrent.TimeoutException` is thrown.
|
|
||||||
|
|
||||||
[[http-client-async]]
|
[[http-client-async]]
|
||||||
==== Non-Blocking APIs
|
==== Non-Blocking APIs
|
||||||
|
|
||||||
So far we have shown how to use Jetty HTTP client in a blocking style, that is
|
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.
|
||||||
the thread that issues the request blocks until the request/response conversation
|
|
||||||
is complete.
|
|
||||||
|
|
||||||
In this section we will look at Jetty's HTTP client non-blocking, asynchronous,
|
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.
|
||||||
APIs that are perfectly suited for large content downloads, for parallel
|
|
||||||
processing of requests/responses and in all those 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
|
The asynchronous APIs rely heavily on listeners that are invoked at various stages of request and response processing.
|
||||||
of request and response processing.
|
|
||||||
These listeners are implemented by applications and may perform any kind of logic.
|
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
|
The implementation invokes these listeners in the same thread that is used to process the request or response.
|
||||||
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.
|
||||||
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,
|
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.
|
||||||
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
|
Request and response processing are executed by two different threads and therefore may happen concurrently.
|
||||||
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.
|
||||||
A typical example of this concurrent processing is an echo server, where a
|
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.
|
||||||
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)`
|
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).
|
||||||
performs the processing of the request until either the request is fully
|
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.
|
||||||
processed or until it would block on I/O, then it returns (and therefore never
|
When such an event is fired, a thread taken from the `HttpClient` thread pool will resume the processing of the request.
|
||||||
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
|
Response are processed from the I/O thread that fires the event that bytes are ready to be read.
|
||||||
ready to be read.
|
Response processing continues until either the response is fully processed or until it would block for I/O.
|
||||||
Response processing continues until either the response is fully processed or
|
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.
|
||||||
until it would block for I/O.
|
When such an event is fired, a thread taken from the `HttpClient` thread pool will resume the processing of the response.
|
||||||
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
|
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.
|
||||||
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 dequeue the next
|
|
||||||
request for the same destination and processes it.
|
|
||||||
|
|
||||||
A simple asynchronous GET request that discards the response content can be
|
A simple asynchronous `GET` request that discards the response content can be written in this way:
|
||||||
written in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -179,10 +134,7 @@ httpClient.newRequest("http://domain.com/path")
|
||||||
});
|
});
|
||||||
----
|
----
|
||||||
|
|
||||||
Method `Request.send(Response.CompleteListener)` returns `void` and does not
|
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.
|
||||||
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:
|
You can write the same code using JDK 8′s lambda expressions:
|
||||||
|
|
||||||
|
@ -192,8 +144,7 @@ httpClient.newRequest("http://domain.com/path")
|
||||||
.send(result -> { /* Your logic here */ });
|
.send(result -> { /* Your logic here */ });
|
||||||
----
|
----
|
||||||
|
|
||||||
You can impose a total timeout for the request/response conversation in the
|
You can impose a total timeout for the request/response conversation in the same way used by the synchronous API:
|
||||||
same way used by the synchronous API:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -202,12 +153,9 @@ Request request = httpClient.newRequest("http://domain.com/path")
|
||||||
.send(result -> { /* Your logic here */ });
|
.send(result -> { /* Your logic here */ });
|
||||||
----
|
----
|
||||||
|
|
||||||
The example above will impose a total timeout of 3 seconds on the request/response
|
The example above will impose a total timeout of 3 seconds on the request/response conversation.
|
||||||
conversation.
|
|
||||||
|
|
||||||
The HTTP client APIs use listeners extensively to provide hooks for all possible
|
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:
|
||||||
request and response events, and with JDK 8′s lambda expressions they’re even
|
|
||||||
more fun to use:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -226,14 +174,9 @@ httpClient.newRequest("http://domain.com/path")
|
||||||
.send(result -> { ... });
|
.send(result -> { ... });
|
||||||
----
|
----
|
||||||
|
|
||||||
This makes Jetty HTTP client suitable for HTTP load testing because, for example,
|
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).
|
||||||
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`]
|
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.
|
||||||
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]]
|
[[http-client-content]]
|
||||||
==== Content Handling
|
==== Content Handling
|
||||||
|
@ -241,12 +184,9 @@ class to know about response events.
|
||||||
[[http-client-request-content]]
|
[[http-client-request-content]]
|
||||||
===== Request Content Handling
|
===== Request Content Handling
|
||||||
|
|
||||||
Jetty's HTTP client provides a number of utility classes off the shelf to handle
|
Jetty's HTTP client provides a number of utility classes off the shelf to handle request content.
|
||||||
request content.
|
|
||||||
|
|
||||||
You can provide request content as `String`, `byte[]`, `ByteBuffer`,
|
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`.
|
||||||
`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`:
|
Here’s an example that provides the request content using `java.nio.file.Paths`:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
|
@ -277,12 +217,9 @@ ContentResponse response = httpClient.newRequest("http://domain.com/upload")
|
||||||
.send();
|
.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
Since `InputStream` is blocking, then also the send of the request will block
|
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 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[]`
|
If you have already read the content in memory, you can pass it as a `byte[]` using the `BytesContentProvider` utility class:
|
||||||
using the `BytesContentProvider` utility class:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -293,9 +230,7 @@ ContentResponse response = httpClient.newRequest("http://domain.com/upload")
|
||||||
.send();
|
.send();
|
||||||
----
|
----
|
||||||
|
|
||||||
If the request content is not immediately available, but your application will
|
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:
|
||||||
be notified of the content to send, you can use `DeferredContentProvider` in
|
|
||||||
this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -326,17 +261,12 @@ content.offer(ByteBuffer.wrap(bytes));
|
||||||
content.close();
|
content.close();
|
||||||
----
|
----
|
||||||
|
|
||||||
While the request content is awaited and consequently uploaded by the client
|
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.
|
||||||
application, the server may be able to respond (at least with the response
|
In this case, `Response.Listener` callbacks will be invoked before the request is fully sent.
|
||||||
headers) completely asynchronously. In this case, `Response.Listener` callbacks
|
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.
|
||||||
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`,
|
Another way to provide request content is by using an `OutputStreamContentProvider`,
|
||||||
which allows applications to write request content when it is available to the
|
which allows applications to write request content when it is available to the `OutputStream` provided by `OutputStreamContentProvider`:
|
||||||
`OutputStream` provided by `OutputStreamContentProvider`:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -370,13 +300,9 @@ try (OutputStream output = content.getOutputStream())
|
||||||
|
|
||||||
Jetty HTTP client allows applications to handle response content in different ways.
|
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
|
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.
|
||||||
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
|
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:
|
||||||
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}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -390,11 +316,9 @@ request.send(listener);
|
||||||
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
|
ContentResponse response = listener.get(5, TimeUnit.SECONDS);
|
||||||
----
|
----
|
||||||
|
|
||||||
If the response content length is exceeded, the response will be aborted, and
|
If the response content length is exceeded, the response will be aborted, and an exception will be thrown by method `get()`.
|
||||||
an exception will be thrown by method `get()`.
|
|
||||||
|
|
||||||
If you are using the asynchronous APIs (see xref:http-client-async[]), you can
|
If you are using the asynchronous APIs (see xref:http-client-async[]), you can use the `BufferingResponseListener` utility class:
|
||||||
use the `BufferingResponseListener` utility class:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -414,14 +338,9 @@ httpClient.newRequest("http://domain.com/path")
|
||||||
});
|
});
|
||||||
----
|
----
|
||||||
|
|
||||||
The second way is the most efficient (because it avoids content copies) and
|
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.
|
||||||
allows you to specify a `Response.ContentListener`, or a subclass, to handle
|
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()`.
|
||||||
the content as soon as it arrives.
|
Jetty's HTTP client will invoke the `onContent()` method zero or more times (until there is content), and finally invoke the `onComplete()` method.
|
||||||
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}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -437,8 +356,7 @@ ContentResponse response = httpClient
|
||||||
});
|
});
|
||||||
----
|
----
|
||||||
|
|
||||||
The third way allows you to wait for the response and then stream the content
|
The third way allows you to wait for the response and then stream the content using the `InputStreamResponseListener` utility class:
|
||||||
using the `InputStreamResponseListener` utility class:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
[[http-client-authentication]]
|
[[http-client-authentication]]
|
||||||
=== Authentication Support
|
=== Authentication Support
|
||||||
|
|
||||||
Jetty's HTTP client supports the "Basic" and "Digest" authentication mechanisms
|
Jetty's HTTP client supports the "Basic" and "Digest" authentication mechanisms defined by link:https://tools.ietf.org/html/rfc7235[RFC 7235].
|
||||||
defined by https://tools.ietf.org/html/rfc7235[RFC 7235].
|
|
||||||
|
|
||||||
You can configure authentication credentials in the HTTP client instance as follows:
|
You can configure authentication credentials in the HTTP client instance as follows:
|
||||||
|
|
||||||
|
@ -39,11 +38,8 @@ ContentResponse response = httpClient
|
||||||
.get(5, TimeUnit.SECONDS);
|
.get(5, TimeUnit.SECONDS);
|
||||||
----
|
----
|
||||||
|
|
||||||
Jetty's HTTP client tests authentication credentials against the challenge(s)
|
Jetty's 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.
|
||||||
the server issues, and if they match it automatically sends the right
|
If the authentication is successful, it caches the result and reuses it for subsequent requests for the same domain and matching URIs.
|
||||||
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.
|
|
||||||
|
|
||||||
The HTTP conversation for a successful match is the following:
|
The HTTP conversation for a successful match is the following:
|
||||||
|
|
||||||
|
@ -59,21 +55,16 @@ Application HttpClient Server
|
||||||
|<-- 200 ---|------------ 200 ------------|
|
|<-- 200 ---|------------ 200 ------------|
|
||||||
----
|
----
|
||||||
|
|
||||||
The application does not receive events related to the response with code 401,
|
The application does not receive events related to the response with code 401, they are handled internally by `HttpClient` which produces a request similar to the original but with the correct `Authorization` header, and then relays the response with code 200 to the application.
|
||||||
they are handled internally by `HttpClient` which produces a request similar
|
|
||||||
to the original but with the correct `Authorization` header, and then relays
|
|
||||||
the response with code 200 to the application.
|
|
||||||
|
|
||||||
Successful authentications are cached, but it is possible to clear them in
|
Successful authentications are cached, but it is possible to clear them in order to force authentication again:
|
||||||
order to force authentication again:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
httpClient.getAuthenticationStore().clearAuthenticationResults();
|
httpClient.getAuthenticationStore().clearAuthenticationResults();
|
||||||
----
|
----
|
||||||
|
|
||||||
Authentications may be preempted to avoid the additional roundtrip due to the
|
Authentications may be preempted to avoid the additional roundtrip due to the server challenge in this way:
|
||||||
server challenge in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -82,9 +73,6 @@ URI uri = URI.create("http://domain.com/secure");
|
||||||
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password"));
|
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password"));
|
||||||
----
|
----
|
||||||
|
|
||||||
In this way, the original request is enriched by `HttpClient` immediately with
|
In this way, the original request is enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge.
|
||||||
the `Authorization` header, and the server should respond with a 200 and the
|
|
||||||
resource content rather than with the 401 and the challenge.
|
|
||||||
|
|
||||||
See also the <<http-client-proxy-authentication,proxy authentication section>>
|
See also the link:#http-client-proxy-authentication[proxy authentication section] for further information about how authentication works with HTTP proxies.
|
||||||
for further information about how authentication works with HTTP proxies.
|
|
||||||
|
|
|
@ -18,14 +18,10 @@
|
||||||
=== Cookies Support
|
=== Cookies Support
|
||||||
|
|
||||||
Jetty HTTP client supports cookies out of the box.
|
Jetty HTTP client supports cookies out of the box.
|
||||||
The `HttpClient` instance receives cookies from HTTP responses and stores them
|
The `HttpClient` instance receives cookies from HTTP responses and stores them in a `java.net.CookieStore`, a class that is part of the JDK.
|
||||||
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.
|
||||||
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
|
Applications can programmatically access the cookie store to find the cookies that have been set:
|
||||||
that have been set:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -65,16 +61,14 @@ for (HttpCookie cookie : cookies)
|
||||||
cookieStore.remove(uri, cookie);
|
cookieStore.remove(uri, cookie);
|
||||||
----
|
----
|
||||||
|
|
||||||
If you want to totally disable cookie handling, you can install a
|
If you want to totally disable cookie handling, you can install a `HttpCookieStore.Empty` instance in this way:
|
||||||
`HttpCookieStore.Empty` instance in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
httpClient.setCookieStore(new HttpCookieStore.Empty());
|
httpClient.setCookieStore(new HttpCookieStore.Empty());
|
||||||
----
|
----
|
||||||
|
|
||||||
You can enable cookie filtering by installing a cookie store that performs the
|
You can enable cookie filtering by installing a cookie store that performs the filtering logic in this way:
|
||||||
filtering logic in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -91,5 +85,4 @@ public class GoogleOnlyCookieStore extends HttpCookieStore
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
The example above will retain only cookies that come from the `google.com`
|
The example above will retain only cookies that come from the `google.com` domain or sub-domains.
|
||||||
domain or sub-domains.
|
|
||||||
|
|
|
@ -17,42 +17,29 @@
|
||||||
[[http-client-intro]]
|
[[http-client-intro]]
|
||||||
=== Introduction
|
=== Introduction
|
||||||
|
|
||||||
The Jetty HTTP client module provides easy-to-use APIs and utility classes to
|
The Jetty HTTP client module provides easy-to-use APIs and utility classes to perform HTTP (or HTTPS) requests.
|
||||||
perform HTTP (or HTTPS) requests.
|
|
||||||
|
|
||||||
Jetty's HTTP client is non-blocking and asynchronous. It offers an asynchronous
|
Jetty's HTTP client is non-blocking and asynchronous.
|
||||||
API that never blocks for I/O, making it very efficient in thread utilization
|
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.
|
||||||
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,
|
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
|
||||||
Jetty's HTTP client offers also a synchronous API, that is a programming interface
|
where the thread that issued the request blocks until the request/response conversation is complete.
|
||||||
where the thread that issued the request blocks until the request/response
|
|
||||||
conversation is complete.
|
|
||||||
|
|
||||||
Jetty's HTTP client supports different <<http-client-transport,transports>>:
|
Jetty's HTTP client supports different link:#http-client-transport[transports]: HTTP/1.1, FastCGI and HTTP/2.
|
||||||
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.
|
||||||
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.
|
The most common and default format is HTTP/1.1.
|
||||||
However, Jetty's HTTP client can carry the same request using the FastCGI format
|
That said, Jetty's HTTP client can carry the same request using the FastCGI format or the new HTTP/2 format.
|
||||||
or the new HTTP/2 format.
|
|
||||||
|
|
||||||
The FastCGI transport is heavily used in Jetty's <<fastcgi,FastCGI support>>
|
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.
|
||||||
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
|
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].
|
||||||
to HTTP/2 enabled web sites, see also Jetty's <<http2,HTTP/2 support>>.
|
|
||||||
|
|
||||||
Out of the box features that you get with the Jetty HTTP client are:
|
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
|
* 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
|
* Cookies support - cookies sent by servers are stored and sent back to servers in matching requests.
|
||||||
in matching requests
|
* Authentication support - HTTP "Basic" and "Digest" authentications are supported, others are pluggable.
|
||||||
* Authentication support; HTTP "Basic" and "Digest" authentications are supported,
|
* Forward proxy support - HTTP proxying and SOCKS4 proxying.
|
||||||
others are pluggable
|
|
||||||
* Forward proxy support; HTTP proxying and SOCKS4 proxying.
|
|
||||||
|
|
||||||
[[http-client-init]]
|
[[http-client-init]]
|
||||||
==== Starting HttpClient
|
==== Starting HttpClient
|
||||||
|
@ -60,12 +47,10 @@ Out of the box features that you get with the Jetty HTTP client are:
|
||||||
The main class is named `org.eclipse.jetty.client.HttpClient`.
|
The main class is named `org.eclipse.jetty.client.HttpClient`.
|
||||||
|
|
||||||
You can think of a `HttpClient` instance as a browser instance.
|
You can think of a `HttpClient` instance as a browser instance.
|
||||||
Like a browser, it can make requests to different domains, it manages
|
Like a browser it can make requests to different domains, it manages redirects, cookies and authentication, you can configure it with a proxy, and
|
||||||
redirects, cookies and authentication, you can configure it with a proxy, and
|
|
||||||
it provides you with the responses to the requests you make.
|
it provides you with the responses to the requests you make.
|
||||||
|
|
||||||
In order to use `HttpClient`, you must instantiate it, configure it, and then
|
In order to use `HttpClient`, you must instantiate it, configure it, and then start it:
|
||||||
start it:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -79,24 +64,17 @@ httpClient.setFollowRedirects(false);
|
||||||
httpClient.start();
|
httpClient.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
You may create multiple instances of `HttpClient`, but typically one instance
|
You may create multiple instances of `HttpClient`, but typically one instance is enough for an application.
|
||||||
is enough for an application.
|
There are several reasons for having multiple `HttpClient` instances including, but not limited to:
|
||||||
The reason to create multiple instances of `HttpClient` is that you want to
|
|
||||||
specify different configuration parameters (for example, one instance is
|
|
||||||
configured with a forward proxy while another is not), or because you want the
|
|
||||||
two instances to behave like two different browsers and hence have different
|
|
||||||
cookies, different authentication credentials and so on, or because you want to
|
|
||||||
use different transports.
|
|
||||||
|
|
||||||
When you create a `HttpClient` instance using the parameterless constructor,
|
* You want to specify different configuration parameters (for example, one instance is configured with a forward proxy while another is not)
|
||||||
you will only be able to perform plain HTTP requests, and you will not be able
|
* You want the two instances to behave like two different browsers and hence have different cookies, different authentication credentials...etc.
|
||||||
to perform HTTPS requests.
|
* You want to use different transports
|
||||||
|
|
||||||
In order to perform HTTPS requests, you should create first a
|
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.
|
||||||
link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.html[`SslContextFactory`],
|
|
||||||
configure it, and pass it to `HttpClient`'s constructor.
|
In order to perform HTTPS requests, you should create first a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.html[`SslContextFactory`], configure it, and pass it to the `HttpClient` constructor.
|
||||||
When created with a `SslContextFactory`, the `HttpClient` will be able to perform
|
When created with a `SslContextFactory`, the `HttpClient` will be able to perform both HTTP and HTTPS requests to any domain.
|
||||||
both HTTP and HTTPS requests to any domain.
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -115,15 +93,11 @@ httpClient.start();
|
||||||
|
|
||||||
==== Stopping HttpClient
|
==== Stopping HttpClient
|
||||||
|
|
||||||
It is recommended that when your application stops, you also stop the `HttpClient`
|
It is recommended that when your application stops, you also stop the `HttpClient` instance (or instances) that you are using.
|
||||||
instance (or instances) that you are using.
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
httpClient.stop();
|
httpClient.stop();
|
||||||
----
|
----
|
||||||
|
|
||||||
Stopping `HttpClient` makes sure that the memory it holds (for example,
|
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.
|
||||||
authentication credentials, cookies, etc.) is released, and that the thread
|
|
||||||
pool and scheduler are properly stopped allowing all threads used by
|
|
||||||
`HttpClient` to exit.
|
|
||||||
|
|
|
@ -19,12 +19,10 @@
|
||||||
|
|
||||||
Jetty's HTTP client can be configured to use proxies to connect to destinations.
|
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
|
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`).
|
||||||
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`.
|
Other implementations may be written by subclassing `ProxyConfiguration.Proxy`.
|
||||||
|
|
||||||
A typical configuration is the following:
|
The following is a typical configuration:
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -40,22 +38,16 @@ proxyConfig.getProxies().add(proxy);
|
||||||
ContentResponse response = httpClient.GET(uri);
|
ContentResponse response = httpClient.GET(uri);
|
||||||
----
|
----
|
||||||
|
|
||||||
You specify the proxy host and port, and optionally also the addresses that
|
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 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
|
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).
|
||||||
(for plain-text HTTP requests) or establishes a tunnel via HTTP CONNECT
|
|
||||||
(for encrypted HTTPS requests).
|
|
||||||
|
|
||||||
[[http-client-proxy-authentication]]
|
[[http-client-proxy-authentication]]
|
||||||
==== Proxy Authentication Support
|
==== Proxy Authentication Support
|
||||||
|
|
||||||
Jetty's HTTP client support proxy authentication in the same way it supports
|
Jetty's HTTP client support proxy authentication in the same way it supports link:#http-client-authentication[server authentication].
|
||||||
<<http-client-authentication,server authentication>>.
|
|
||||||
|
|
||||||
In the example below, the proxy requires Basic authentication, but the server
|
In the example below, the proxy requires Basic authentication, but the server requires Digest authentication, and therefore:
|
||||||
requires Digest authentication, and therefore:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -80,8 +72,7 @@ ContentResponse response = httpClient.newRequest(serverURI)
|
||||||
.get(5, TimeUnit.SECONDS);
|
.get(5, TimeUnit.SECONDS);
|
||||||
----
|
----
|
||||||
|
|
||||||
The HTTP conversation for successful authentications on both the proxy and the
|
The HTTP conversation for successful authentications on both the proxy and the server is the following:
|
||||||
server is the following:
|
|
||||||
|
|
||||||
----
|
----
|
||||||
Application HttpClient Proxy Server
|
Application HttpClient Proxy Server
|
||||||
|
@ -105,9 +96,6 @@ Application HttpClient Proxy Server
|
||||||
|<-- 200 ---|<------------ 200 --------------|<--------- 200 ----------|
|
|<-- 200 ---|<------------ 200 --------------|<--------- 200 ----------|
|
||||||
----
|
----
|
||||||
|
|
||||||
The application does not receive events related to the responses with code 407
|
The application does not receive events related to the responses with code 407 and 401 since they are handled internally by `HttpClient`.
|
||||||
and 401 since they are handled internally by `HttpClient`.
|
|
||||||
|
|
||||||
Similarly to the <<http-client-authentication,authentication section>>, the
|
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.
|
||||||
proxy authentication result and the server authentication result can be
|
|
||||||
preempted to avoid, respectively, the 407 and 401 roundtrips.
|
|
||||||
|
|
|
@ -17,25 +17,18 @@
|
||||||
[[http-client-transport]]
|
[[http-client-transport]]
|
||||||
=== Pluggable Transports
|
=== Pluggable Transports
|
||||||
|
|
||||||
Jetty's HTTP client can be configured to use different transports to carry
|
Jetty's HTTP client can be configured to use different transports to carry the semantic of HTTP requests and responses.
|
||||||
the semantic of HTTP requests and responses.
|
|
||||||
|
|
||||||
This means that the intention of a client to request resource `/index.html`
|
This means that the intention of a client to request resource `/index.html` using the `GET` method can be carried over the network in different formats.
|
||||||
using the `GET` method can be carried over the network in different formats.
|
|
||||||
|
|
||||||
A HTTP client transport is the component that is in charge of converting
|
A HTTP client transport is the component that is in charge of converting a high-level, semantic, HTTP requests such as "GET resource /index.html" into the specific format understood by the server (for example, HTTP/2), and to convert the server response from the specific format (HTTP/2) into high-level, semantic objects that can be used by applications.
|
||||||
a high-level, semantic, HTTP requests such as "GET resource /index.html"
|
|
||||||
into the specific format understood by the server (for example, HTTP/2),
|
|
||||||
and to convert the server response from the specific format (HTTP/2) into
|
|
||||||
high-level, semantic objects that can be used by applications.
|
|
||||||
|
|
||||||
In this way, applications are not aware of the actual protocol being used.
|
In this way, applications are not aware of the actual protocol being used.
|
||||||
They can write their logic against a high-level API that hides the details
|
This allows them to write their logic against a high-level API that hides the details of the specific protocol being used over the network.
|
||||||
of the specific protocol being used over the network.
|
|
||||||
|
|
||||||
The most common protocol format is HTTP/1.1, a text-based protocol with
|
The most common protocol format is HTTP/1.1, a text-based protocol with lines separated by `\r\n`:
|
||||||
lines separated by `\r\n`:
|
|
||||||
|
|
||||||
|
[source, screen, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
GET /index.html HTTP/1.1\r\n
|
GET /index.html HTTP/1.1\r\n
|
||||||
Host: domain.com\r\n
|
Host: domain.com\r\n
|
||||||
|
@ -45,6 +38,7 @@ Host: domain.com\r\n
|
||||||
|
|
||||||
However, the same request can be made using FastCGI, a binary protocol:
|
However, the same request can be made using FastCGI, a binary protocol:
|
||||||
|
|
||||||
|
[source, screen, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
x01 x01 x00 x01 x00 x08 x00 x00
|
x01 x01 x00 x01 x00 x08 x00 x00
|
||||||
x00 x01 x01 x00 x00 x00 x00 x00
|
x00 x01 x01 x00 x00 x00 x00 x00
|
||||||
|
@ -56,8 +50,7 @@ x0C x0B D O C U M E
|
||||||
...
|
...
|
||||||
----
|
----
|
||||||
|
|
||||||
Similarly, HTTP/2 is a binary protocol that transports the same information
|
Similarly, HTTP/2 is a binary protocol that transports the same information in a yet different format.
|
||||||
in a yet different format.
|
|
||||||
|
|
||||||
==== HTTP/1.1 Transport
|
==== HTTP/1.1 Transport
|
||||||
|
|
||||||
|
@ -70,8 +63,7 @@ HttpClient client = new HttpClient();
|
||||||
client.start();
|
client.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
If you want to customize the HTTP/1.1 transport, you can explicitly configure
|
If you want to customize the HTTP/1.1 transport, you can explicitly configure `HttpClient` in this way:
|
||||||
`HttpClient` in this way:
|
|
||||||
|
|
||||||
[source, java, subs="{sub-order}"]
|
[source, java, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -82,8 +74,7 @@ HttpClient client = new HttpClient(transport, null);
|
||||||
client.start();
|
client.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
The example above allows you to customize the number of NIO selectors that
|
The example above allows you to customize the number of NIO selectors that `HttpClient` will be using.
|
||||||
`HttpClient` will be using.
|
|
||||||
|
|
||||||
==== HTTP/2 Transport
|
==== HTTP/2 Transport
|
||||||
|
|
||||||
|
@ -99,11 +90,9 @@ HttpClient client = new HttpClient(transport, null);
|
||||||
client.start();
|
client.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
`HTTP2Client` is the lower-level client that provides an API based on HTTP/2
|
`HTTP2Client` is the lower-level client that provides an API based on HTTP/2 concepts such as _sessions_, _streams_ and _frames_ that are specific to HTTP/2.
|
||||||
concepts such as _sessions_, _streams_ and _frames_ that are specific to HTTP/2.
|
|
||||||
|
|
||||||
`HttpClientTransportOverHTTP2` uses `HTTP2Client` to format high-level semantic
|
`HttpClientTransportOverHTTP2` uses `HTTP2Client` to format high-level semantic HTTP requests ("GET resource /index.html") into the HTTP/2 specific format.
|
||||||
HTTP requests ("GET resource /index.html") into the HTTP/2 specific format.
|
|
||||||
|
|
||||||
==== FastCGI Transport
|
==== FastCGI Transport
|
||||||
|
|
||||||
|
@ -119,9 +108,6 @@ HttpClient client = new HttpClient(transport, null);
|
||||||
client.start();
|
client.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
In order to make requests using the FastCGI transport, you need to have a
|
In order to make requests using the FastCGI transport, you need to have a FastCGI server such as https://en.wikipedia.org/wiki/PHP#PHPFPM[PHP-FPM] (see also http://php.net/manual/en/install.fpm.php).
|
||||||
FastCGI server such as https://en.wikipedia.org/wiki/PHP#PHPFPM[PHP-FPM]
|
|
||||||
(see also http://php.net/manual/en/install.fpm.php).
|
|
||||||
|
|
||||||
The FastCGI transport is primarily used by Jetty's <<fastcgi,FastCGI support>>
|
The FastCGI transport is primarily used by Jetty's link:#fastcgi[FastCGI support] to serve PHP pages (WordPress for example).
|
||||||
to serve PHP pages (for example WordPress).
|
|
||||||
|
|
Loading…
Reference in New Issue