Merged branch 'jetty-10.0.x' into 'jetty-11.0.x'.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2021-04-20 18:01:35 +02:00
commit e18e6c5dd3
5 changed files with 69 additions and 19 deletions

View File

@ -22,24 +22,26 @@ The following command creates a KeyStore file containing a private key and a sel
----
keytool
-genkeypair <1>
-validity 90 <2>
-keyalg RSA <3>
-keysize 2048 <4>
-keystore /path/to/keystore.p12 <5>
-storetype pkcs12 <6>
-dname "CN=domain.com, OU=Unit, O=Company, L=City, S=State, C=Country" <7>
-ext san=dns:www.domain.com,dns:domain.org <8>
-v <9>
-alias mykey <2>
-validity 90 <3>
-keyalg RSA <4>
-keysize 2048 <5>
-keystore /path/to/keystore.p12 <6>
-storetype pkcs12 <7>
-dname "CN=domain.com, OU=Unit, O=Company, L=City, S=State, C=Country" <8>
-ext san=dns:www.domain.com,dns:domain.org <9>
-v <10>
----
<1> the command to generate a key and certificate pair
<2> specifies the number of days after which the certificate expires
<3> the algorithm _must_ be RSA (the DSA algorithm does not work for web sites)
<4> indicates the strength of the key
<5> the keyStore file
<6> the keyStore type, stick with the standard PKCS12
<7> the distinguished name (more below) -- customize it with your values for CN, OU, O, L, S and C
<8> the extension with the subject alternative names (more below)
<9> verbose output
<2> the alias name of the key and certificate pair
<3> specifies the number of days after which the certificate expires
<4> the algorithm _must_ be RSA (the DSA algorithm does not work for web sites)
<5> indicates the strength of the key
<6> the KeyStore file
<7> the KeyStore type, stick with the standard PKCS12
<8> the distinguished name (more below) -- customize it with your values for CN, OU, O, L, S and C
<9> the extension with the subject alternative names (more below)
<10> verbose output
The command prompts for the KeyStore password that you must choose to protect the access to the KeyStore.
@ -56,3 +58,13 @@ In the example above, `san=dns:www.domain.com,dns:domain.org` specifies `www.dom
In rare cases, you may want to specify IP addresses, rather than domains, in the SAN extension.
The syntax in such case is `san=ip:127.0.0.1,ip:[::1]`, which specifies as subject alternative names IPv4 `127.0.0.1` and IPv6 `[::1]`.
====
[[og-keystore-create-many]]
===== KeyStores with Multiple Entries
A single KeyStore may contain multiple key/certificate pairs.
This is useful when you need to support multiple domains on the same Jetty server (typically accomplished using xref:og-deploy-virtual-hosts[virtual hosts]).
You can create multiple key/certificate pairs as detailed in the xref:og-keystore-create[previous section], provided that you assign each one to a different alias.
Compliant TLS clients will send the xref:og-protocols-ssl-sni[TLS SNI extension] when creating new connections, and Jetty will automatically choose the right certificate by matching the SNI name sent by the client with the CN or SAN of certificates present in the KeyStore.

View File

@ -84,6 +84,17 @@ include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/http/HTTPCli
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.
[NOTE]
====
You cannot call `HttpClient.stop()` from one of its own threads, as it would cause a deadlock.
It is recommended that you stop `HttpClient` from an unrelated thread, or from a newly allocated thread, for example:
[source,java,indent=0]
----
include::../../{doc_code}/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java[tags=stopFromOtherThread]
----
====
[[pg-client-http-arch]]
==== HttpClient Architecture

View File

@ -66,6 +66,7 @@ import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import static java.lang.System.Logger.Level.INFO;
@ -97,6 +98,17 @@ public class HTTPClientDocs
// end::stop[]
}
public void stopFromOtherThread() throws Exception
{
HttpClient httpClient = new HttpClient();
httpClient.start();
// tag::stopFromOtherThread[]
// Stop HttpClient from a new thread.
// Use LifeCycle.stop(...) to rethrow checked exceptions as unchecked.
new Thread(() -> LifeCycle.stop(httpClient)).start();
// end::stopFromOtherThread[]
}
public void tlsExplicit() throws Exception
{
// tag::tlsExplicit[]

View File

@ -16,6 +16,7 @@ package org.eclipse.jetty.client;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.io.ClientConnector;
@ -30,7 +31,7 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC
protected AbstractConnectorHttpClientTransport(ClientConnector connector)
{
this.connector = connector;
this.connector = Objects.requireNonNull(connector);
addBean(connector);
}

View File

@ -19,6 +19,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -86,7 +87,12 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
*/
public HttpClientTransportDynamic()
{
this(new ClientConnector(), HttpClientConnectionFactory.HTTP11);
this(HttpClientConnectionFactory.HTTP11);
}
public HttpClientTransportDynamic(ClientConnectionFactory.Info... factoryInfos)
{
this(findClientConnector(factoryInfos), factoryInfos);
}
/**
@ -98,7 +104,6 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
public HttpClientTransportDynamic(ClientConnector connector, ClientConnectionFactory.Info... factoryInfos)
{
super(connector);
addBean(connector);
if (factoryInfos.length == 0)
factoryInfos = new Info[]{HttpClientConnectionFactory.HTTP11};
this.factoryInfos = Arrays.asList(factoryInfos);
@ -112,6 +117,15 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1));
}
private static ClientConnector findClientConnector(ClientConnectionFactory.Info[] infos)
{
return Arrays.stream(infos)
.map(info -> info.getBean(ClientConnector.class))
.filter(Objects::nonNull)
.findFirst()
.orElse(new ClientConnector());
}
@Override
public Origin newOrigin(HttpRequest request)
{