Skip to content

Commit

Permalink
Merge pull request #202 from aliyun/feature/proxy
Browse files Browse the repository at this point in the history
Support http proxy
  • Loading branch information
sjj3086786 committed Mar 21, 2019
2 parents 23ae415 + 7b2956b commit 5543979
Show file tree
Hide file tree
Showing 15 changed files with 527 additions and 76 deletions.
6 changes: 6 additions & 0 deletions .appveyor.yml
Expand Up @@ -8,7 +8,13 @@ skip_commits:

build: off

install:
# Install Proxy
- npm install o_o -g

test_script:
# Start Proxy
- ps: Start-Process -FilePath o_o -NoNewWindow
- mvn test -B -f .\aliyun-java-sdk-core\pom.xml
- if defined daily_accessKeyId ( if defined daily_accessSecret ( call appveyor-test.bat ) ) else echo BUILD FAILURE MissingAccessKeyId

11 changes: 11 additions & 0 deletions .travis.yml
Expand Up @@ -11,7 +11,18 @@ branches: # build only on these branches
only:
- master

install:
# Install Proxy
- sudo rm -rf ~/.nvm - curl -sL "https://deb.nodesource.com/setup_7.x" | sudo -E bash -
- sudo apt-get install -y nodejs
- sudo ln -s /usr/bin/nodejs /usr/bin/node
- sudo apt-get install -y npm
- sudo npm install o_o -g --registry=https://registry.npm.taobao.org

script:
# Start Proxy
- sudo o_o &
# Test
- mvn test -B -f ./aliyun-java-sdk-core/pom.xml
- test -z $daily_accessKeyId -a -z $daily_accessSecret || make travis-test

Expand Down
23 changes: 23 additions & 0 deletions README.md
Expand Up @@ -283,4 +283,27 @@ request.setX509TrustManagers(requestTrustManagers);
request.setKeyManagers(requestKeyManagers);

client.getAcsResponse(request)
```

## Proxy Configurations
Priority: Client > Environment variable

Support below environment variable:
1. HTTP_PROXY or http_proxy
2. HTTPS_PROXY
3. NO_PROXY

```java
// Client proxy configurations
HttpClientConfig clientConfig = HttpClientConfig.getDefault();
// Configure HTTP proxy
clientConfig.setHttpProxy("http://127.0.0.1:9898");
// Configure HTTPS proxy
clientConfig.setHttpsProxy("http://user:password@127.0.0.1:8989");
// Configure host addresses bypass the proxy
clientConfig.setNoProxy("127.0.0.1,localhost");

IClientProfile profile = DefaultProfile.getProfile(regionId, accesskeyId, accesskeySecret);
profile.setHttpClientConfig(clientConfig);
DefaultAcsClient client = new DefaultAcsClient(profile);
```
23 changes: 23 additions & 0 deletions README_zh.md
Expand Up @@ -265,4 +265,27 @@ request.setX509TrustManagers(requestTrustManagers);
request.setKeyManagers(requestKeyManagers);

client.getAcsResponse(request)
```

## 代理配置
优先级: Client > 环境变量

支持以下环境变量:
1. HTTP_PROXY或者http_proxy
2. HTTPS_PROXY
3. NO_PROXY

```java
// Client 代理配置
HttpClientConfig clientConfig = HttpClientConfig.getDefault();
// 设置HTTP代理
clientConfig.setHttpProxy("http://127.0.0.1:9898");
// 设置HTTPS代理
clientConfig.setHttpsProxy("http://user:password@127.0.0.1:8989");
// 设置忽略代理地址列表
clientConfig.setNoProxy("127.0.0.1,localhost");

IClientProfile profile = DefaultProfile.getProfile(regionId, accesskeyId, accesskeySecret);
profile.setHttpClientConfig(clientConfig);
DefaultAcsClient client = new DefaultAcsClient(profile);
```
@@ -1,14 +1,13 @@
package com.aliyuncs.http;

import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;

public class HttpClientConfig {

Expand Down Expand Up @@ -61,6 +60,15 @@ public class HttpClientConfig {
private Runnable idleCallback = null;
private ExecutorService executorService = null;


/**
* proxy configurations
*/

private String httpProxy = null;
private String httpsProxy = null;
private String noProxy = null;

/**
* extra params
*/
Expand Down Expand Up @@ -272,4 +280,28 @@ public ProtocolType getProtocolType() {
public void setProtocolType(ProtocolType protocolType) {
this.protocolType = protocolType;
}

public String getHttpProxy() {
return httpProxy;
}

public void setHttpProxy(String httpProxy) {
this.httpProxy = httpProxy;
}

public String getHttpsProxy() {
return httpsProxy;
}

public void setHttpsProxy(String httpsProxy) {
this.httpsProxy = httpsProxy;
}

public String getNoProxy() {
return noProxy;
}

public void setNoProxy(String noProxy) {
this.noProxy = noProxy;
}
}
78 changes: 74 additions & 4 deletions aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/HttpUtil.java
@@ -1,12 +1,19 @@
package com.aliyuncs.http;

import java.util.Map;
import java.util.Map.Entry;

import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.utils.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHost;

import com.aliyuncs.exceptions.ClientException;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;

public class HttpUtil {

Expand Down Expand Up @@ -73,4 +80,67 @@ public static String debugHttpResponse(HttpResponse response) throws ClientExcep
return null;
}
}

public static Proxy getJDKProxy(String clientProxy, String envProxy, HttpRequest request) throws ClientException {
Proxy proxy = Proxy.NO_PROXY;
try {
String proxyStr = (!StringUtils.isEmpty(clientProxy) ? clientProxy : envProxy);
if (StringUtils.isEmpty(proxyStr)) {
return proxy;
}
URL proxyUrl = new URL(proxyStr);

String userInfo = proxyUrl.getUserInfo();
if (userInfo != null) {
byte[] bytes = userInfo.getBytes("UTF-8");
String auth = DatatypeConverter.printBase64Binary(bytes);
request.putHeaderParameter("Proxy-Authorization", "Basic " + auth);
}
String hostname = proxyUrl.getHost();
int port = proxyUrl.getPort();
if (port == -1) {
port = proxyUrl.getDefaultPort();
}
SocketAddress addr = new InetSocketAddress(hostname, port);
proxy = new Proxy(Proxy.Type.HTTP, addr);

} catch (IOException e) {
throw new ClientException("SDK.InvalidProxy", "proxy url is invalid");
}
return proxy;
}

public static HttpHost getApacheProxy(String clientProxy, String envProxy, HttpRequest request) throws ClientException {
try {
String proxyStr = (!StringUtils.isEmpty(clientProxy) ? clientProxy : envProxy);
if (StringUtils.isEmpty(proxyStr)) {
return null;
}
URL proxyUrl = new URL(proxyStr);
String userInfo = proxyUrl.getUserInfo();
if (userInfo != null) {
byte[] bytes = userInfo.getBytes("UTF-8");
String auth = DatatypeConverter.printBase64Binary(bytes);
request.putHeaderParameter("Proxy-Authorization", "Basic " + auth);
}
return new HttpHost(proxyUrl.getHost(), proxyUrl.getPort(), proxyUrl.getProtocol());

} catch (IOException e) {
throw new ClientException("SDK.InvalidProxy", "proxy url is invalid");
}
}

public static boolean needProxy(String targetHost, String clientNoProxyList, String envNoProxyList) {
String noProxyList = (!StringUtils.isEmpty(clientNoProxyList) ? clientNoProxyList : envNoProxyList);
if (StringUtils.isEmpty(noProxyList)) {
return true;
}
String[] noProxyArr = noProxyList.split(",");
for (String host : noProxyArr) {
if (host.equals(targetHost)) {
return false;
}
}
return true;
}
}
Expand Up @@ -2,10 +2,11 @@

import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.*;
import com.aliyuncs.utils.EnvironmentUtils;
import com.aliyuncs.utils.IOUtils;
import com.aliyuncs.utils.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
Expand All @@ -28,6 +29,8 @@

import javax.net.ssl.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -153,7 +156,7 @@ protected void init(final HttpClientConfig config) throws ClientException {
if (config.getKeepAliveDurationMillis() > 0) {
builder.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
public long getKeepAliveDuration(org.apache.http.HttpResponse response, HttpContext context) {
long duration = DefaultConnectionKeepAliveStrategy.INSTANCE.getKeepAliveDuration(response, context);

if (duration > 0 && duration < config.getKeepAliveDurationMillis()) {
Expand All @@ -168,7 +171,7 @@ public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
httpClient = builder.build();
}

private HttpUriRequest parseToHttpRequest(HttpRequest apiReq) throws IOException {
private HttpUriRequest parseToHttpRequest(HttpRequest apiReq) throws IOException, ClientException {
RequestBuilder builder = RequestBuilder.create(apiReq.getSysMethod().name());

builder.setUri(apiReq.getSysUrl());
Expand Down Expand Up @@ -205,13 +208,29 @@ private HttpUriRequest parseToHttpRequest(HttpRequest apiReq) throws IOException
} else {
readTimeout = (int) clientConfig.getReadTimeoutMillis();
}
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(
HttpHost proxy = calcProxy(apiReq);
RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).setConnectTimeout(connectTimeout).setSocketTimeout(
readTimeout).setConnectionRequestTimeout((int) clientConfig.getWriteTimeoutMillis()).build();
builder.setConfig(requestConfig);
return builder.build();
}

private com.aliyuncs.http.HttpResponse parseToHttpResponse(HttpResponse httpResponse) throws IOException {
private HttpHost calcProxy(HttpRequest apiReq) throws MalformedURLException, ClientException {
boolean needProxy = HttpUtil.needProxy(new URL(apiReq.getSysUrl()).getHost(), clientConfig.getNoProxy(), EnvironmentUtils.getNoProxy());
if (!needProxy) {
return null;
}
URL url = new URL(apiReq.getSysUrl());
HttpHost proxy = null;
if ("https".equalsIgnoreCase(url.getProtocol())) {
proxy = HttpUtil.getApacheProxy(clientConfig.getHttpsProxy(), EnvironmentUtils.getHttpsProxy(), apiReq);
} else {
proxy = HttpUtil.getApacheProxy(clientConfig.getHttpProxy(), EnvironmentUtils.getHttpProxy(), apiReq);
}
return proxy;
}

private HttpResponse parseToHttpResponse(org.apache.http.HttpResponse httpResponse) throws IOException {
com.aliyuncs.http.HttpResponse result = new com.aliyuncs.http.HttpResponse();

// status code
Expand Down Expand Up @@ -242,7 +261,7 @@ private com.aliyuncs.http.HttpResponse parseToHttpResponse(HttpResponse httpResp
}

@Override
public final com.aliyuncs.http.HttpResponse syncInvoke(HttpRequest apiRequest) throws IOException {
public final HttpResponse syncInvoke(HttpRequest apiRequest) throws IOException, ClientException {
HttpUriRequest httpRequest = parseToHttpRequest(apiRequest);
CloseableHttpResponse httpResponse = null;
try {
Expand Down

0 comments on commit 5543979

Please sign in to comment.