add builder to HttpAddress

This commit is contained in:
Jörg Prante 2023-01-22 18:46:49 +01:00
parent b3cfb54837
commit ab4c22d4c2
4 changed files with 118 additions and 75 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib group = org.xbib
name = net-http name = net-http
version = 3.0.3 version = 3.0.4
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -93,7 +93,7 @@ public class HttpsAddress extends HttpAddress {
return sslContext; return sslContext;
} }
public static class Builder { public static class Builder extends HttpAddress.Builder {
private static TrustManagerFactory TRUST_MANAGER_FACTORY; private static TrustManagerFactory TRUST_MANAGER_FACTORY;
@ -120,14 +120,6 @@ public class HttpsAddress extends HttpAddress {
} }
} }
private String host;
private int port = -1;
private boolean isSecure = true;
private HttpVersion httpVersion = HttpVersion.HTTP_1_1;
private TrustManagerFactory trustManagerFactory; private TrustManagerFactory trustManagerFactory;
private KeyStore trustManagerKeyStore; private KeyStore trustManagerKeyStore;
@ -154,32 +146,34 @@ public class HttpsAddress extends HttpAddress {
private boolean enableOcsp; private boolean enableOcsp;
private Set<String> hostNames; protected Builder() {
private Builder() {
this.trustManagerFactory = TRUST_MANAGER_FACTORY; this.trustManagerFactory = TRUST_MANAGER_FACTORY;
this.sslProvider = OpenSsl.isAvailable() ? SslProvider.OPENSSL : SslProvider.JDK; this.sslProvider = OpenSsl.isAvailable() ? SslProvider.OPENSSL : SslProvider.JDK;
this.ciphers = OpenSsl.isAvailable() ? DEFAULT_OPENSSL_CIPHERS : DEFAULT_JDK_CIPHERS; this.ciphers = OpenSsl.isAvailable() ? DEFAULT_OPENSSL_CIPHERS : DEFAULT_JDK_CIPHERS;
this.cipherSuiteFilter = SupportedCipherSuiteFilter.INSTANCE; this.cipherSuiteFilter = SupportedCipherSuiteFilter.INSTANCE;
} }
@Override
public Builder setHost(String host) { public Builder setHost(String host) {
this.host = host; this.host = host;
return this; return this;
} }
@Override
public Builder setPort(int port) { public Builder setPort(int port) {
this.port = port; this.port = port;
return this; return this;
} }
@Override
public Builder setSecure(boolean secure) { public Builder setSecure(boolean secure) {
this.isSecure = secure; this.isSecure = secure;
return this; return this;
} }
public Builder setVersion(HttpVersion httpVersion) { @Override
this.httpVersion = httpVersion; public Builder setVersion(HttpVersion version) {
this.version = version;
return this; return this;
} }
@ -313,9 +307,10 @@ public class HttpsAddress extends HttpAddress {
return this; return this;
} }
@Override
public HttpsAddress build() throws KeyStoreException, SSLException { public HttpsAddress build() throws KeyStoreException, SSLException {
Objects.requireNonNull(host); Objects.requireNonNull(host);
Objects.requireNonNull(httpVersion); Objects.requireNonNull(version);
Objects.requireNonNull(privateKey); Objects.requireNonNull(privateKey);
Objects.requireNonNull(certChain); Objects.requireNonNull(certChain);
if (certChain.isEmpty()) { if (certChain.isEmpty()) {
@ -334,14 +329,14 @@ public class HttpsAddress extends HttpAddress {
sslContextBuilder.sslContextProvider(sslContextProvider); sslContextBuilder.sslContextProvider(sslContextProvider);
} }
if (applicationProtocolConfig == null) { if (applicationProtocolConfig == null) {
if (httpVersion.equals(HttpVersion.HTTP_2_0)) { if (version.equals(HttpVersion.HTTP_2_0)) {
// OpenSSL does not support FATAL_ALERT behaviour // OpenSSL does not support FATAL_ALERT behaviour
applicationProtocolConfig = new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, applicationProtocolConfig = new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1); ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1);
} }
if (httpVersion.equals(HttpVersion.HTTP_1_1)) { if (version.equals(HttpVersion.HTTP_1_1)) {
applicationProtocolConfig = new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, applicationProtocolConfig = new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
@ -360,7 +355,7 @@ public class HttpsAddress extends HttpAddress {
" session timeout = " + sslContext.sessionTimeout() + " session timeout = " + sslContext.sessionTimeout() +
" cipher suite = " + sslContext.cipherSuites() " cipher suite = " + sslContext.cipherSuites()
); );
return new HttpsAddress(host, port, httpVersion, isSecure, hostNames, sslContext); return new HttpsAddress(host, port, version, isSecure, hostNames, sslContext);
} }
} }

View file

@ -29,13 +29,9 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HttpsAddress extends HttpAddress { public class HttpsAddress extends HttpAddress {
private static final Logger logger = Logger.getLogger(HttpsAddress.class.getName());
private final SSLContext sslContext; private final SSLContext sslContext;
public HttpsAddress(String host, Integer port, HttpVersion version, public HttpsAddress(String host, Integer port, HttpVersion version,
@ -84,7 +80,7 @@ public class HttpsAddress extends HttpAddress {
return sslContext; return sslContext;
} }
public static class Builder { public static class Builder extends HttpAddress.Builder {
private static TrustManagerFactory TRUST_MANAGER_FACTORY; private static TrustManagerFactory TRUST_MANAGER_FACTORY;
@ -99,14 +95,6 @@ public class HttpsAddress extends HttpAddress {
} }
} }
private String host;
private int port = -1;
private boolean isSecure = true;
private HttpVersion httpVersion = HttpVersion.HTTP_1_1;
private TrustManagerFactory trustManagerFactory; private TrustManagerFactory trustManagerFactory;
private KeyStore trustManagerKeyStore; private KeyStore trustManagerKeyStore;
@ -126,23 +114,27 @@ public class HttpsAddress extends HttpAddress {
this.ciphers = DEFAULT_JDK_CIPHERS; this.ciphers = DEFAULT_JDK_CIPHERS;
} }
@Override
public Builder setHost(String host) { public Builder setHost(String host) {
this.host = host; this.host = host;
return this; return this;
} }
@Override
public Builder setPort(int port) { public Builder setPort(int port) {
this.port = port; this.port = port;
return this; return this;
} }
@Override
public Builder setSecure(boolean secure) { public Builder setSecure(boolean secure) {
this.isSecure = secure; this.isSecure = secure;
return this; return this;
} }
public Builder setVersion(HttpVersion httpVersion) { @Override
this.httpVersion = httpVersion; public Builder setVersion(HttpVersion version) {
this.version = version;
return this; return this;
} }
@ -220,7 +212,7 @@ public class HttpsAddress extends HttpAddress {
public HttpsAddress build() throws KeyStoreException { public HttpsAddress build() throws KeyStoreException {
Objects.requireNonNull(host); Objects.requireNonNull(host);
Objects.requireNonNull(httpVersion); Objects.requireNonNull(version);
Objects.requireNonNull(privateKey); Objects.requireNonNull(privateKey);
Objects.requireNonNull(certChain); Objects.requireNonNull(certChain);
if (certChain.isEmpty()) { if (certChain.isEmpty()) {
@ -236,7 +228,7 @@ public class HttpsAddress extends HttpAddress {
certChain) certChain)
.withTrustMaterial(trustManagerFactory) .withTrustMaterial(trustManagerFactory)
.build(); .build();
return new HttpsAddress(host, port, httpVersion, isSecure, hostNames, sslFactory.getSslContext()); return new HttpsAddress(host, port, version, isSecure, hostNames, sslFactory.getSslContext());
} }
} }

View file

@ -1,5 +1,8 @@
package org.xbib.net.http; package org.xbib.net.http;
import java.security.KeyStoreException;
import java.util.Objects;
import javax.net.ssl.SSLException;
import org.xbib.net.Address; import org.xbib.net.Address;
import org.xbib.net.NetworkUtils; import org.xbib.net.NetworkUtils;
import org.xbib.net.SocketConfig; import org.xbib.net.SocketConfig;
@ -15,21 +18,15 @@ import java.util.Set;
*/ */
public class HttpAddress implements Address { public class HttpAddress implements Address {
private final String host; private final Builder builder;
private final Integer port;
private final HttpVersion version;
private final Boolean secure;
private final Set<String> hostNames;
private InetAddress inetAddress; private InetAddress inetAddress;
private InetSocketAddress inetSocketAddress; private InetSocketAddress inetSocketAddress;
private SocketConfig socketConfig; public static Builder builder() {
return new Builder();
}
public static HttpAddress http1(String host) { public static HttpAddress http1(String host) {
return new HttpAddress(host, 80, HttpVersion.HTTP_1_1, false); return new HttpAddress(host, 80, HttpVersion.HTTP_1_1, false);
@ -74,30 +71,36 @@ public class HttpAddress implements Address {
public HttpAddress(String host, Integer port, HttpVersion version, boolean secure) { public HttpAddress(String host, Integer port, HttpVersion version, boolean secure) {
this(host, port, version, secure, Set.of()); this(host, port, version, secure, Set.of());
} }
public HttpAddress(String host, Integer port, HttpVersion version, public HttpAddress(String host, Integer port, HttpVersion version,
boolean secure, Set<String> hostNames) { boolean secure, Set<String> hostNames) {
this.host = host; this(builder()
this.port = (port == null || port == -1) ? secure ? 443 : 80 : port; .setHost(host)
this.version = version; .setPort((port == null || port == -1) ? secure ? 443 : 80 : port)
this.secure = secure; .setVersion(version)
this.hostNames = hostNames; .setSecure(secure)
this.socketConfig = new SocketConfig(); .setHostNames(hostNames)
.setSocketConfig(new SocketConfig()));
}
public HttpAddress(Builder builder) {
this.builder = builder;
} }
@Override @Override
public String getHost() { public String getHost() {
return host; return builder.host;
} }
@Override @Override
public Integer getPort() { public Integer getPort() {
return port; return builder.port;
} }
@Override @Override
public InetAddress getInetAddress() throws IOException { public InetAddress getInetAddress() throws IOException {
if (inetAddress == null) { if (inetAddress == null) {
this.inetAddress = NetworkUtils.resolveInetAddress(host, null); this.inetAddress = NetworkUtils.resolveInetAddress(builder.host, null);
} }
return inetAddress; return inetAddress;
} }
@ -106,7 +109,7 @@ public class HttpAddress implements Address {
public InetSocketAddress getInetSocketAddress() throws IOException { public InetSocketAddress getInetSocketAddress() throws IOException {
if (inetSocketAddress == null) { if (inetSocketAddress == null) {
InetAddress inetAddress = getInetAddress(); InetAddress inetAddress = getInetAddress();
this.inetSocketAddress = new InetSocketAddress(inetAddress.getHostAddress(), port); this.inetSocketAddress = new InetSocketAddress(inetAddress.getHostAddress(), builder.port);
} }
return inetSocketAddress; return inetSocketAddress;
} }
@ -114,60 +117,113 @@ public class HttpAddress implements Address {
@Override @Override
public URL base() { public URL base() {
return isSecure() ? return isSecure() ?
URL.https().host(host).port(port).build() : URL.https().host(builder.host).port(builder.port).build() :
URL.http().host(host).port(port).build(); URL.http().host(builder.host).port(builder.port).build();
} }
@Override @Override
public boolean isSecure() { public boolean isSecure() {
return secure; return builder.isSecure;
}
public void setSocketConfig(SocketConfig socketConfig) {
this.socketConfig = socketConfig;
} }
@Override @Override
public SocketConfig getSocketConfig() { public SocketConfig getSocketConfig() {
return socketConfig; return builder.socketConfig;
} }
public Set<String> getHostNames() { public Set<String> getHostNames() {
return hostNames; return builder.hostNames;
} }
public HttpVersion getVersion() { public HttpVersion getVersion() {
return version; return builder.version;
} }
public String hostAndPort() { public String hostAndPort() {
return host + ":" + port; return builder.host + ":" + builder.port;
} }
public String hostAddressAndPort() throws IOException { public String hostAddressAndPort() throws IOException {
return getInetAddress().getHostAddress() + ":" + port; return getInetAddress().getHostAddress() + ":" + builder.port;
} }
public String canonicalHostAndPort() throws IOException { public String canonicalHostAndPort() throws IOException {
return getInetAddress().getCanonicalHostName() + ":" + port; return getInetAddress().getCanonicalHostName() + ":" + builder.port;
} }
@Override @Override
public String toString() { public String toString() {
return "[" + version + "]" + (secure ? "[SECURE]" : "") + host + ":" + port; return "[" + builder.version + "]" + (builder.isSecure ? "[SECURE]" : "") + builder.host + ":" + builder.port;
} }
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
return object instanceof HttpAddress && return object instanceof HttpAddress &&
host.equals(((HttpAddress) object).host) && builder.host.equals(((HttpAddress) object).builder.host) &&
(port != null && port.equals(((HttpAddress) object).port)) && (builder.port != null && builder.port.equals(((HttpAddress) object).builder.port)) &&
version.equals(((HttpAddress) object).version) && builder.version.equals(((HttpAddress) object).builder.version) &&
secure.equals(((HttpAddress) object).secure); builder.isSecure.equals(((HttpAddress) object).builder.isSecure);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return host.hashCode() ^ port ^ version.hashCode() ^ secure.hashCode(); return builder.host.hashCode() ^ builder.port ^ builder.version.hashCode() ^ builder.isSecure.hashCode();
}
public static class Builder {
protected String host;
protected Integer port;
protected Boolean isSecure;
protected HttpVersion version;
protected Set<String> hostNames;
protected SocketConfig socketConfig;
protected Builder() {
this.port = -1;
this.isSecure = false;
this.version = HttpVersion.HTTP_1_1;
}
public Builder setHost(String host) {
this.host = host;
return this;
}
public Builder setPort(int port) {
this.port = port;
return this;
}
public Builder setSecure(boolean secure) {
this.isSecure = secure;
return this;
}
public Builder setVersion(HttpVersion httpVersion) {
this.version = httpVersion;
return this;
}
public Builder setHostNames(Set<String> hostNames) {
this.hostNames = hostNames;
return this;
}
public Builder setSocketConfig(SocketConfig socketConfig) {
this.socketConfig = socketConfig;
return this;
}
public HttpAddress build() throws KeyStoreException, SSLException {
Objects.requireNonNull(host);
Objects.requireNonNull(version);
return new HttpAddress(this);
}
} }
} }