diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc index 2d1c53642bf..3e76e8c9045 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc @@ -12,7 +12,7 @@ // [[pg-client-io-arch]] -=== Client Libraries I/O Architecture +=== I/O Architecture The Jetty client libraries provide the basic components and APIs to implement a network client. @@ -24,7 +24,7 @@ There are conceptually two layers that compose the Jetty client libraries: . xref:pg-client-io-arch-protocol[The protocol layer], that handles the parsing of bytes read from the network and the generation of bytes to write to the network. [[pg-client-io-arch-network]] -==== Client Libraries Network Layer +==== Network Layer The Jetty client libraries use the common I/O design described in xref:pg-arch-io[this section]. The main client-side component is the link:{javadoc-url}/org/eclipse/jetty/io/ClientConnector.html[`ClientConnector`]. @@ -78,8 +78,25 @@ This time includes the DNS lookup time _and_ the TCP connect time. Please refer to the `ClientConnector` link:{javadoc-url}/org/eclipse/jetty/io/ClientConnector.html[javadocs] for the complete list of configurable parameters. +[[pg-client-io-arch-unix-domain]] +===== Unix-Domain Support + +link:https://openjdk.java.net/jeps/380[JEP 380] introduced Unix-Domain sockets support in Java 16, on all operative systems. + +`ClientConnector` can be configured to support Unix-Domain sockets in the following way: + +[source,java,indent=0] +---- +include::../{doc_code}/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java[tags=unixDomain] +---- + +[IMPORTANT] +==== +You can use Unix-Domain sockets support only when you run your client application with Java 16 or later. +==== + [[pg-client-io-arch-protocol]] -==== Client Libraries Protocol Layer +==== Protocol Layer The protocol layer builds on top of the network layer to generate the bytes to be written to the network and to parse the bytes read from the network. diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-intro.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-intro.adoc index 5c4dda2d76f..338b4fdbd78 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-intro.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-intro.adoc @@ -21,10 +21,13 @@ It offers an asynchronous API that never blocks for I/O, making it very efficien 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 xref:pg-client-http-transport[different transports]: HTTP/1.1, FastCGI and HTTP/2. This means that the semantic of an HTTP request: " ``GET`` 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 HTTP/2 format. +Jetty's HTTP client supports different xref:pg-client-http-transport[transports protocols]: HTTP/1.1, HTTP/2 and FastCGI. This means that the semantic of an HTTP request such as: " ``GET`` 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 HTTP/2 format or the FastCGI format. -The xref:pg-client-http-transport-fcgi[FastCGI transport] is heavily used in Jetty's xref:pg-server-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. +Furthermore, every transport protocol can be sent either over the network or via Unix-Domain sockets. +Supports for Unix-Domain sockets requires Java 16 or later, since Unix-Domain sockets support has been introduced in OpenJDK with link:https://openjdk.java.net/jeps/380[JEP 380]. + +The xref:pg-client-http-transport-fcgi[FastCGI transport] is heavily used in Jetty's xref:pg-server-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, often in conjunction with Unix-Domain sockets (although it's possible to use FastCGI via network too). 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 xref:pg-client-http2[HTTP/2 support]. diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc index 22375eb6d5c..dd48cb9bb5a 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/http/client-http-transport.adoc @@ -14,11 +14,11 @@ [[pg-client-http-transport]] ==== HttpClient Pluggable Transports -Jetty's `HttpClient` can be configured to use different transports to carry the semantic of HTTP requests and responses. +Jetty's `HttpClient` can be configured to use different transport protocols to carry the semantic of HTTP requests and responses. 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. -A `HttpClient` 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. +An `HttpClient` 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. The most common protocol format is HTTP/1.1, a textual protocol with lines separated by `\r\n`: @@ -53,6 +53,9 @@ A request for a resource may be sent using one protocol (for example, HTTP/1.1), `HttpClient` also supports one xref:pg-client-http-transport-dynamic[dynamic transport], that can speak different protocols and can select the right protocol by negotiating it with the server or by explicit indication from applications. +Furthermore, every transport protocol can be sent either over the network or via Unix-Domain sockets. +Supports for Unix-Domain sockets requires Java 16 or later, since Unix-Domain sockets support has been introduced in OpenJDK with link:https://openjdk.java.net/jeps/380[JEP 380]. + Applications are typically not aware of the actual protocol being used. 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. @@ -154,3 +157,26 @@ If the server does not support the HTTP version chosen by the client, then the c If the client application does not explicitly specify the HTTP version, then ALPN will be used on the client. If the server also supports ALPN, then the protocol will be negotiated via ALPN and the server will choose the protocol to use. If the server does not support ALPN, the client will try to use the first protocol configured in `HttpClientTransportDynamic`, and the communication may succeed or fail depending on whether the server supports the protocol chosen by the client. + +[[pg-client-http-transport-unix-domain]] +===== Unix-Domain Configuration + +All the transports can be configured with a `ClientConnector`, the component that is responsible for the transmission of the bytes generated by the transport to the server. + +By default, `ClientConnector` uses TCP networking to send bytes to the server and receive bytes from the server. + +When you are using Java 16 or later, `ClientConnector` also support xref:pg-client-io-arch-unix-domain[Unix-Domain sockets], and every transport can be configured to use Unix-Domain sockets instead of TCP networking. + +To configure Unix-Domain sockets, you can create a `ClientConnector` instance in the following way: + +[source,java,indent=0] +---- +include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tag=unixDomain] +---- + +[IMPORTANT] +==== +You can use Unix-Domain sockets support only when you run your client application with Java 16 or later. +==== + +You can configure a Jetty server to use Unix-Domain sockets, as explained in xref:pg-server-http-connector[this section]. diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-connector.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-connector.adoc index 767c94a82d3..ed8c020f7af 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-connector.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-connector.adoc @@ -19,7 +19,7 @@ A `Connector` is the component that handles incoming requests from clients, and The available implementations are: * `org.eclipse.jetty.server.ServerConnector`, for TCP/IP sockets. -* `org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector` for Unix-Domain sockets. +* `org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector` for Unix-Domain sockets (requires Java 16 or later). Both use a `java.nio.channels.ServerSocketChannel` to listen to a socket address and to accept socket connections. @@ -37,6 +37,11 @@ Likewise, `UnixDomainServerConnector` also wraps a `ServerSocketChannel` and can include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=configureConnectorUnix] ---- +[IMPORTANT] +==== +You can use Unix-Domain sockets support only when you run your server with Java 16 or later. +==== + The _acceptors_ are threads (typically only one) that compete to accept socket connections. When a connection is accepted, `ServerConnector` wraps the accepted `SocketChannel` and passes it to the xref:pg-arch-io-selector-manager[`SelectorManager`]. Therefore, there is a little moment where the acceptor thread is not accepting new connections because it is busy wrapping the just accepted connection to pass it to the `SelectorManager`. diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java index c7b17b478f0..40608fd4d5f 100644 --- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java +++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java @@ -18,6 +18,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -41,6 +42,7 @@ import org.eclipse.jetty.util.thread.Scheduler; import static java.lang.System.Logger.Level.INFO; +@SuppressWarnings("unused") public class ClientConnectorDocs { public void simplest() throws Exception @@ -417,6 +419,19 @@ public class ClientConnectorDocs // end::tlsTelnet[] } + public void unixDomain() throws Exception + { + // tag::unixDomain[] + // This is the path where the server "listens" on. + Path unixDomainPath = Path.of("/path/to/server.sock"); + + // Creates a ClientConnector that uses Unix-Domain + // sockets, not the network, to connect to the server. + ClientConnector clientConnector = ClientConnector.forUnixDomain(unixDomainPath); + clientConnector.start(); + // end::unixDomain[] + } + public static void main(String[] args) throws Exception { new ClientConnectorDocs().tlsTelnet(); diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java index 67b35f05b0a..885679748c7 100644 --- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java +++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java @@ -21,6 +21,7 @@ import java.net.CookieStore; import java.net.HttpCookie; import java.net.URI; import java.nio.ByteBuffer; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.concurrent.TimeUnit; @@ -855,4 +856,32 @@ public class HTTPClientDocs maxRequestsPerConnection)); // end::setConnectionPool[] } + + public void unixDomain() throws Exception + { + // tag::unixDomain[] + // This is the path where the server "listens" on. + Path unixDomainPath = Path.of("/path/to/server.sock"); + + // Creates a ClientConnector that uses Unix-Domain + // sockets, not the network, to connect to the server. + ClientConnector unixDomainClientConnector = ClientConnector.forUnixDomain(unixDomainPath); + + // Use Unix-Domain for HTTP/1.1. + HttpClientTransportOverHTTP http1Transport = new HttpClientTransportOverHTTP(unixDomainClientConnector); + + // You can use Unix-Domain also for HTTP/2. + HTTP2Client http2Client = new HTTP2Client(unixDomainClientConnector); + HttpClientTransportOverHTTP2 http2Transport = new HttpClientTransportOverHTTP2(http2Client); + + // You can also use UnixDomain for the dynamic transport. + ClientConnectionFactory.Info http1 = HttpClientConnectionFactory.HTTP11; + ClientConnectionFactoryOverHTTP2.HTTP2 http2 = new ClientConnectionFactoryOverHTTP2.HTTP2(http2Client); + HttpClientTransportDynamic dynamicTransport = new HttpClientTransportDynamic(unixDomainClientConnector, http1, http2); + + // Choose the transport you prefer for HttpClient, for example the dynamic transport. + HttpClient httpClient = new HttpClient(dynamicTransport); + httpClient.start(); + // end::unixDomain[] + } }