Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/dubbo3.2 add rest client tls #12251

Open
wants to merge 34 commits into
base: 3.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b6d18cc
rest client add tls
suncairong163 May 4, 2023
0e14e48
rest client ssl
suncairong163 May 7, 2023
529499b
remove test log
suncairong163 May 7, 2023
757fb47
modify HTTPS_PROTOCOL
suncairong163 May 7, 2023
100977b
fix trust manage
suncairong163 May 7, 2023
9ce4def
PEM tls base64 decode
May 8, 2023
88ebde0
PEM tls base64 decode
May 8, 2023
7366c85
fix exception message
May 8, 2023
1489434
fix null point exception
suncairong163 May 8, 2023
e8b59db
fix SSL pem parse
suncairong163 May 8, 2023
6db95b6
add exception
suncairong163 May 13, 2023
f911d23
Merge branch '3.2' into feature/dubbo3.2_add_rest_client_tls
AlbumenJ May 18, 2023
9d4ea7a
http client ssl
suncairong163 May 20, 2023
acd1bf0
Merge remote-tracking branch 'origin/feature/dubbo3.2_add_rest_client…
suncairong163 May 20, 2023
b60a495
http client build
suncairong163 May 21, 2023
90cd33c
add ssl cert file parse ut
suncairong163 May 21, 2023
06b8266
modify ssl context build
suncairong163 May 21, 2023
d1e4a47
license
suncairong163 May 21, 2023
a8307cf
remove unsued import
suncairong163 May 21, 2023
08fa31c
Merge branch '3.3' into feature/dubbo3.2_add_rest_client_tls
AlbumenJ May 23, 2023
084572a
http client ssl
suncairong163 May 23, 2023
e854bed
Refactor file name & replace Base64Decode
suncairong163 May 23, 2023
a0fdfb9
Merge remote-tracking branch 'origin/feature/dubbo3.2_add_rest_client…
suncairong163 May 23, 2023
a7cf9b9
PEM charset US_ASCII
suncairong163 May 23, 2023
f8c0a35
remove empty X509TrustManager implement
suncairong163 May 23, 2023
f0a2301
add default host name verifier
suncairong163 May 23, 2023
0a27dfb
reconstruct rest client tls
suncairong163 May 24, 2023
280fe27
bug fix
suncairong163 May 27, 2023
069cb65
refactor file name
suncairong163 May 27, 2023
33551c8
refactor name
suncairong163 May 27, 2023
dca49f5
safeCloseStream out
suncairong163 May 28, 2023
78f6a9c
add ssl context cache
suncairong163 May 28, 2023
1e7a1c6
SslConfig exclude attribute
suncairong163 May 28, 2023
91d7f09
Merge branch '3.3' into feature/dubbo3.2_add_rest_client_tls
suncairong163 Jun 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,70 @@
package org.apache.dubbo.remoting.http;


import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.ssl.Cert;
import org.apache.dubbo.common.ssl.CertManager;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;

public abstract class BaseRestClient<CLIENT> implements RestClient {
import java.util.concurrent.CompletableFuture;

protected CLIENT client;
public abstract class BaseRestClient implements RestClient {
protected final HttpClientConfig httpClientConfig;
protected final URL url;

protected HttpClientConfig clientConfig;

public BaseRestClient(HttpClientConfig clientConfig) {
this.clientConfig = clientConfig;
client = createHttpClient(clientConfig);
public BaseRestClient(HttpClientConfig httpClientConfig, URL url) {
this.httpClientConfig = httpClientConfig;
this.url = url;
}

protected abstract CLIENT createHttpClient(HttpClientConfig clientConfig);

public URL getUrl() {
return url;
}

public HttpClientConfig getHttpClientConfig() {
return httpClientConfig;
}

/**
* ssl config check
* @return
*/
public boolean isEnableSSL() {
Cert consumerConnectionConfig = null;
try {
CertManager certManager = url.getOrDefaultFrameworkModel().getBeanFactory().getBean(CertManager.class);
consumerConnectionConfig = certManager.getConsumerConnectionConfig(url);
} catch (Exception e) {
return false;
}

public HttpClientConfig getClientConfig() {
return clientConfig;
if (consumerConnectionConfig == null) {
return false;
}
return true;

}

/**
* set protocol by sslConfig
*
* @param requestTemplate
*/
private void preSend(RequestTemplate requestTemplate) {
if (isEnableSSL()) {
requestTemplate.setHttpsProtocol();
} else {
requestTemplate.setHttpProtocol();
}
}

public CLIENT getClient() {
return client;
@Override
public CompletableFuture<RestResult> send(RequestTemplate message) {
preSend(message);
return doSend(message);
}

protected abstract CompletableFuture<RestResult> doSend(RequestTemplate message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class RequestTemplate implements Serializable {
private Object body;
private byte[] byteBody = new byte[0];
private String protocol = "http://";
private static final String HTTP_PROTOCOL = "http://";
private static final String HTTPS_PROTOCOL = "https://";
private final Invocation invocation;
private String contextPath = "";
private Class<?> bodyType;
Expand Down Expand Up @@ -132,7 +134,7 @@ public boolean isBodyEmpty() {
return getUnSerializedBody() == null;
}

public RequestTemplate body(Object body,Class bodyType) {
public RequestTemplate body(Object body, Class bodyType) {
this.body = body;
setBodyType(bodyType);
return this;
Expand Down Expand Up @@ -281,6 +283,13 @@ public void setProtocol(String protocol) {
this.protocol = protocol;
}

public void setHttpProtocol() {
this.protocol = HTTP_PROTOCOL;
}

public void setHttpsProtocol() {
this.protocol = HTTPS_PROTOCOL;
}

public Invocation getInvocation() {
return invocation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ public class ApacheHttpClientFactory extends AbstractHttpClientFactory {
protected RestClient doCreateRestClient(URL url) throws RpcException {


return new HttpClientRestClient(httpClientConfig);
return new HttpClientRestClient(httpClientConfig,url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ public class OkHttpClientFactory extends AbstractHttpClientFactory {
@Override
protected RestClient doCreateRestClient(URL url) throws RpcException {

return new OKHttpRestClient(httpClientConfig);
return new OKHttpRestClient(httpClientConfig, url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ public class URLConnectionClientFactory extends AbstractHttpClientFactory {
@Override
protected RestClient doCreateRestClient(URL url) throws RpcException {

return new URLConnectionRestClient(httpClientConfig);
return new URLConnectionRestClient(httpClientConfig,url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
*/
package org.apache.dubbo.remoting.http.restclient;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.http.BaseRestClient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;

import org.apache.commons.io.IOUtils;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLContexts;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLSetter;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.config.RequestConfig;
Expand All @@ -38,9 +41,12 @@
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -51,17 +57,21 @@
import java.util.stream.Collectors;


public class HttpClientRestClient implements RestClient {
public class HttpClientRestClient extends BaseRestClient {
private final CloseableHttpClient closeableHttpClient;
private final HttpClientConfig httpClientConfig;

public HttpClientRestClient(HttpClientConfig clientConfig) {
public HttpClientRestClient(HttpClientConfig clientConfig, URL url) {
super(clientConfig, url);
closeableHttpClient = createHttpClient();
httpClientConfig = clientConfig;
}

public HttpClientRestClient(HttpClientConfig clientConfig) {

this(clientConfig, null);
}

@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
public CompletableFuture<RestResult> doSend(RequestTemplate requestTemplate) {

HttpRequestBase httpRequest = null;
String httpMethod = requestTemplate.getHttpMethod();
Expand Down Expand Up @@ -158,8 +168,23 @@ public boolean isClosed() {
}

public CloseableHttpClient createHttpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
return HttpClients.custom().setConnectionManager(connectionManager).build();

HttpClientBuilder custom = HttpClients.custom();
HttpClientBuilder finalCustom = custom;
custom = RestClientSSLContexts.buildClientSslContext(getUrl(), new RestClientSSLSetter() {
@Override
public void initSSLContext(SSLContext sslContext, TrustManager[] trustAllCerts) {
finalCustom.setSSLContext(sslContext);
}

@Override
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {

finalCustom.setSSLHostnameVerifier(hostnameVerifier);
}
}, finalCustom);

return custom.build();
}

protected HttpRequestBase createHttpUriRequest(String httpMethod, RequestTemplate requestTemplate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
*/
package org.apache.dubbo.remoting.http.restclient;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.http.BaseRestClient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;

Expand All @@ -29,7 +30,13 @@
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpMethod;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLContexts;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLSetter;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
Expand All @@ -38,17 +45,21 @@
import java.util.concurrent.TimeUnit;

// TODO add version 4.0 implements ,and default version is < 4.0,for dependency conflict
public class OKHttpRestClient implements RestClient {
public class OKHttpRestClient extends BaseRestClient {
private final OkHttpClient okHttpClient;
private final HttpClientConfig httpClientConfig;

public OKHttpRestClient(HttpClientConfig clientConfig) {
public OKHttpRestClient(HttpClientConfig clientConfig, URL url) {
super(clientConfig, url);
this.okHttpClient = createHttpClient(clientConfig);
this.httpClientConfig = clientConfig;
}

public OKHttpRestClient(HttpClientConfig clientConfig) {

this(clientConfig, null);
}

@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
public CompletableFuture<RestResult> doSend(RequestTemplate requestTemplate) {

Request.Builder builder = new Request.Builder();
// url
Expand Down Expand Up @@ -142,11 +153,29 @@ public boolean isClosed() {
}

public OkHttpClient createHttpClient(HttpClientConfig httpClientConfig) {
OkHttpClient client = new OkHttpClient.Builder().
readTimeout(httpClientConfig.getReadTimeout(), TimeUnit.SECONDS).
writeTimeout(httpClientConfig.getWriteTimeout(), TimeUnit.SECONDS).
connectTimeout(httpClientConfig.getConnectTimeout(), TimeUnit.SECONDS).
build();
OkHttpClient.Builder builder = new OkHttpClient.Builder();

OkHttpClient.Builder finalBuilder = builder;
builder = RestClientSSLContexts.buildClientSslContext(getUrl(), new RestClientSSLSetter() {
@Override
public void initSSLContext(SSLContext sslContext, TrustManager[] trustAllCerts) {
finalBuilder.sslSocketFactory(sslContext.getSocketFactory(),(X509TrustManager)trustAllCerts[0]);
}

@Override
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {

finalBuilder.hostnameVerifier(hostnameVerifier);
}
}, builder);

OkHttpClient client =
builder.readTimeout(httpClientConfig.getReadTimeout(), TimeUnit.SECONDS).
writeTimeout(httpClientConfig.getWriteTimeout(), TimeUnit.SECONDS).
connectTimeout(httpClientConfig.getConnectTimeout(), TimeUnit.SECONDS).
build();
return client;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@
*/
package org.apache.dubbo.remoting.http.restclient;

import org.apache.dubbo.remoting.http.BaseRestClient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;

import org.apache.commons.io.IOUtils;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLContexts;
import org.apache.dubbo.remoting.http.ssl.RestClientSSLSetter;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
Expand All @@ -34,20 +40,44 @@
import java.util.zip.GZIPOutputStream;


public class URLConnectionRestClient implements RestClient {
public class URLConnectionRestClient extends BaseRestClient {
private final HttpClientConfig clientConfig;

public URLConnectionRestClient(HttpClientConfig clientConfig) {

this(clientConfig, null);
}

public URLConnectionRestClient(HttpClientConfig clientConfig, org.apache.dubbo.common.URL url) {
super(clientConfig, url);
this.clientConfig = clientConfig;
}

@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
public CompletableFuture<RestResult> doSend(RequestTemplate requestTemplate) {

CompletableFuture<RestResult> future = new CompletableFuture<>();

try {
HttpURLConnection connection = (HttpURLConnection) new URL(requestTemplate.getURL()).openConnection();
HttpURLConnection connection = null;
if (isEnableSSL()) {
HttpsURLConnection tmp = (HttpsURLConnection) new URL(requestTemplate.getURL()).openConnection();

connection = RestClientSSLContexts.buildClientSslContext(getUrl(), new RestClientSSLSetter() {
@Override
public void initSSLContext(SSLContext sslContext, TrustManager[] trustAllCerts) {
tmp.setSSLSocketFactory(sslContext.getSocketFactory());
}

@Override
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {

tmp.setHostnameVerifier(hostnameVerifier);
}
}, tmp);
} else {
connection = (HttpURLConnection) new URL(requestTemplate.getURL()).openConnection();
}
connection.setConnectTimeout(clientConfig.getConnectTimeout());
connection.setReadTimeout(clientConfig.getReadTimeout());
connection.setRequestMethod(requestTemplate.getHttpMethod());
Expand Down