Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions examples/cvm/v20170312/Nginx.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.cvm.v20170312.CvmClient;
import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesRequest;
import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesResponse;

import java.util.HashMap;

public class Nginx {
public static void main(String[] args) {
/*
本示例演示如何通过 **nginx 反向代理** 请求腾讯云 API。
场景:某些网络环境不能直接访问腾讯云域名(*.tencentcloudapi.com),只能通过代理服务器。
========================
1. nginx 配置示例:
========================
server {
listen 80;
# 指定 DNS 服务器(可以根据自己网络环境进行替换)
resolver 114.114.114.114;
# 可以自定义请求路径
location /tc_api {
# http_host 后必须以 / 结尾
proxy_pass https://$http_host/$is_args$args;
}
}
*/
try {
Credential cred = new Credential(
System.getenv("TENCENTCLOUD_SECRET_ID"),
System.getenv("TENCENTCLOUD_SECRET_KEY")
);

ClientProfile cpf = new ClientProfile();
// 2. 将 Scheme 设置为 http
cpf.getHttpProfile().setProtocol(HttpProfile.REQ_HTTP);

// 3. 替换 1.2.3.4 为真实的 nginx 地址, /tc_api 可以自定义
String nginx = "1.2.3.4/tc_api";
cpf.getHttpProfile().setEndpoint(nginx);

CvmClient client = new CvmClient(cred, "ap-guangzhou", cpf);

DescribeInstancesRequest req = new DescribeInstancesRequest();
// 4. 设置 header 为 {服务名}.tencentcloudapi.com
req.SetHeader(new HashMap<String, String>() {{
put("Host", "cvm.tencentcloudapi.com");
}});
req.setLimit(10L);

DescribeInstancesResponse resp = client.DescribeInstances(req);
System.out.println(DescribeInstancesResponse.toJsonString(resp));

} catch (TencentCloudSDKException e) {
e.printStackTrace();
}
}
}
67 changes: 49 additions & 18 deletions src/main/java/com/tencentcloudapi/common/AbstractClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ public AbstractClient(
this.endpoint = endpoint;
this.service = endpoint.split("\\.")[0];
this.region = region;
this.path = "/";
int pathIdx = endpoint.indexOf('/');
if (pathIdx >= 0) {
this.path = endpoint.substring(pathIdx);
} else {
this.path = "/";
}
this.sdkVersion = AbstractClient.SDK_VERSION;
this.apiVersion = version;
this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Expand Down Expand Up @@ -212,7 +217,7 @@ public String call(String action, String jsonPayload) throws TencentCloudSDKExce
byte[] requestPayload = jsonPayload.getBytes(StandardCharsets.UTF_8);
String authorization = this.getAuthorization(headers, requestPayload);
headers.put("Authorization", authorization);
String url = this.profile.getHttpProfile().getProtocol() + this.getEndpoint() + this.path;
String url = this.profile.getHttpProfile().getProtocol() + this.getEndpoint();
return this.getResponseBody(url, headers, requestPayload);
}

Expand All @@ -233,7 +238,7 @@ public String callOctetStream(String action, HashMap<String, String> headers, by
headers.put("Content-Type", "application/octet-stream; charset=utf-8");
String authorization = this.getAuthorization(headers, body);
headers.put("Authorization", authorization);
String url = this.profile.getHttpProfile().getProtocol() + this.getEndpoint() + this.path;
String url = this.profile.getHttpProfile().getProtocol() + this.getEndpoint();
return this.getResponseBody(url, headers, body);
}

Expand All @@ -249,7 +254,7 @@ private HashMap<String, String> getHeaders() {
headers.put("X-TC-Version", this.apiVersion);
headers.put("X-TC-Region", this.getRegion());
headers.put("X-TC-RequestClient", SDK_VERSION);
headers.put("Host", this.getEndpoint());
headers.put("Host", this.getHost());
String token = this.credential.getToken();
if (token != null && !token.isEmpty()) {
headers.put("X-TC-Token", token);
Expand All @@ -273,15 +278,15 @@ private HashMap<String, String> getHeaders() {
*/
private String getAuthorization(HashMap<String, String> headers, byte[] body)
throws TencentCloudSDKException {
String endpoint = this.getEndpoint();
String host = this.getHost();
// always use post tc3-hmac-sha256 signature process
// okhttp always set charset even we don't specify it,
// to ensure signature be correct, we have to set it here as well.
String contentType = headers.get("Content-Type");
byte[] requestPayload = body;
String canonicalUri = "/";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:" + contentType + "\nhost:" + endpoint + "\n";
String canonicalHeaders = "content-type:" + contentType + "\nhost:" + host + "\n";
String signedHeaders = "content-type;host";

String hashedRequestPayload = "";
Expand All @@ -307,7 +312,7 @@ private String getAuthorization(HashMap<String, String> headers, byte[] body)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
String service = endpoint.split("\\.")[0];
String service = host.split("\\.")[0];
String credentialScope = date + "/" + service + "/" + "tc3_request";
String hashedCanonicalRequest =
Sign.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));
Expand Down Expand Up @@ -713,18 +718,27 @@ private Response doRequest(String endpoint, AbstractModel request, String action
throws TencentCloudSDKException, IOException {
HashMap<String, String> param = new HashMap<String, String>();
request.toMap(param, "");
String strParam = this.formatRequestData(action, param);
String strParam = this.formatRequestData(action, request, param);
String reqMethod = this.profile.getHttpProfile().getReqMethod();
String protocol = this.profile.getHttpProfile().getProtocol();
String url = protocol + endpoint + this.path;
String url = protocol + endpoint;
String apigwEndpoint = this.profile.getHttpProfile().getApigwEndpoint();
if (null != apigwEndpoint) {
url = protocol + apigwEndpoint;
}

Builder headers = new Headers.Builder();
if (null != request.GetHeader()) {
for (Map.Entry<String, String> entry : request.GetHeader().entrySet()) {
headers.add(entry.getKey(), entry.getValue());
}
}
if (reqMethod.equals(HttpProfile.REQ_GET)) {
return this.httpConnection.getRequest(url + "?" + strParam);
return this.httpConnection.getRequest(url + "?" + strParam, headers.build());
} else if (reqMethod.equals(HttpProfile.REQ_POST)) {
return this.httpConnection.postRequest(url, strParam);
headers.add("X-TC-RequestClient", SDK_VERSION);
headers.add("Content-Type", "application/x-www-form-urlencoded");
return this.httpConnection.postRequest(url, strParam, headers.build());
} else {
throw new TencentCloudSDKException("Method only support (GET, POST)");
}
Expand Down Expand Up @@ -770,9 +784,14 @@ private Response doRequestWithTC3(String endpoint, AbstractModel request, String
contentType = "application/json; charset=utf-8";
}
// Construct the canonical request for signature calculation.
String host = this.getHost();
if (request.GetHeader().containsKey("Host")) {
host = request.GetHeader().get("Host");
request.GetHeader().remove("Host");
}
String canonicalUri = "/";
String canonicalQueryString = this.getCanonicalQueryString(params, httpRequestMethod);
String canonicalHeaders = "content-type:" + contentType + "\nhost:" + endpoint + "\n";
String canonicalHeaders = "content-type:" + contentType + "\nhost:" + host + "\n";
String signedHeaders = "content-type;host";

String hashedRequestPayload = "";
Expand All @@ -798,7 +817,7 @@ private Response doRequestWithTC3(String endpoint, AbstractModel request, String
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
String service = endpoint.split("\\.")[0];
String service = host.split("\\.")[0];
String credentialScope = date + "/" + service + "/" + "tc3_request";
String hashedCanonicalRequest =
Sign.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8));
Expand Down Expand Up @@ -831,7 +850,7 @@ private Response doRequestWithTC3(String endpoint, AbstractModel request, String
}
Builder hb = new Headers.Builder();
hb.add("Content-Type", contentType)
.add("Host", endpoint)
.add("Host", host)
.add("Authorization", authorization)
.add("X-TC-Action", action)
.add("X-TC-Timestamp", timestamp)
Expand All @@ -857,7 +876,7 @@ private Response doRequestWithTC3(String endpoint, AbstractModel request, String
}

String protocol = this.profile.getHttpProfile().getProtocol();
String url = protocol + endpoint + this.path;
String url = protocol + endpoint;
String apigwEndpoint = this.profile.getHttpProfile().getApigwEndpoint();
if (null != apigwEndpoint) {
url = protocol + apigwEndpoint;
Expand Down Expand Up @@ -954,7 +973,7 @@ private String getCanonicalQueryString(HashMap<String, String> params, String me
* @return The formatted string for signing.
* @throws TencentCloudSDKException If UTF-8 encoding is not supported.
*/
private String formatRequestData(String action, Map<String, String> param)
private String formatRequestData(String action, AbstractModel request, Map<String, String> param)
throws TencentCloudSDKException {
param.put("Action", action);
param.put("RequestClient", this.sdkVersion);
Expand Down Expand Up @@ -983,14 +1002,17 @@ private String formatRequestData(String action, Map<String, String> param)
param.put("Language", this.profile.getLanguage().getValue());
}

String endpoint = this.getEndpoint();
String host = this.getHost();
if (request.GetHeader().containsKey("Host")) {
host = request.GetHeader().get("Host");
}

// Generate the string to be signed.
String sigInParam =
Sign.makeSignPlainText(
new TreeMap<String, String>(param),
this.profile.getHttpProfile().getReqMethod(),
endpoint,
host,
this.path);
// Generate the signature.
String sigOutParam =
Expand Down Expand Up @@ -1048,6 +1070,15 @@ private String getEndpoint() {
}
}

private String getHost() {
String endpoint = getEndpoint();
int pathIdx = endpoint.indexOf('/');
if (pathIdx < 0) {
pathIdx = endpoint.length();
}
return endpoint.substring(0, pathIdx);
}

/**
* 请注意购买类接口谨慎调用,可能导致多次购买
* 仅幂等接口推荐使用
Expand Down
23 changes: 0 additions & 23 deletions src/main/java/com/tencentcloudapi/common/http/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,6 @@ public Response doRequest(Request request) throws IOException {
return this.client.newCall(request).execute();
}

public Response getRequest(String url) throws TencentCloudSDKException, IOException {
Request request = null;
try {
request = new Request.Builder().url(url).get().build();
} catch (IllegalArgumentException e) {
throw new TencentCloudSDKException(e.getClass().getName() + "-" + e.getMessage());
}

return this.doRequest(request);
}

public Response getRequest(String url, Headers headers) throws TencentCloudSDKException, IOException {
Request request = null;
try {
Expand All @@ -95,18 +84,6 @@ public Response getRequest(String url, Headers headers) throws TencentCloudSDKEx
return this.doRequest(request);
}

public Response postRequest(String url, String body) throws TencentCloudSDKException, IOException {
MediaType contentType = MediaType.parse("application/x-www-form-urlencoded");
Request request = null;
try {
request = new Request.Builder().url(url).post(RequestBody.create(contentType, body)).build();
} catch (IllegalArgumentException e) {
throw new TencentCloudSDKException(e.getClass().getName() + "-" + e.getMessage());
}

return this.doRequest(request);
}

public Response postRequest(String url, String body, Headers headers)
throws TencentCloudSDKException, IOException {
MediaType contentType = MediaType.parse(headers.get("Content-Type"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.tencentcloudapi.integration.requests;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.cvm.v20170312.CvmClient;
import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesRequest;
import org.junit.Test;

import java.util.HashMap;

public class HeaderTest {
@Test
public void TestSetHeader() throws TencentCloudSDKException {
Credential cred = new Credential(
System.getenv("TENCENTCLOUD_SECRET_ID"),
System.getenv("TENCENTCLOUD_SECRET_KEY")
);

String[] signMethods = new String[]{
ClientProfile.SIGN_SHA1,
ClientProfile.SIGN_SHA256,
ClientProfile.SIGN_TC3_256
};
String[] reqMethods = new String[]{
HttpProfile.REQ_POST,
HttpProfile.REQ_GET,
};

for (String signMethod : signMethods) {
for (String reqMethod : reqMethods) {
ClientProfile cpf = new ClientProfile();
cpf.setSignMethod(signMethod);
HttpProfile hpf = new HttpProfile();
hpf.setReqMethod(reqMethod);
hpf.setProtocol("http://");
hpf.setEndpoint("9.134.89.153:81/tc_api");
cpf.setHttpProfile(hpf);

CvmClient client = new CvmClient(cred, "ap-guangzhou", cpf);
DescribeInstancesRequest req = new DescribeInstancesRequest();
req.SetHeader(new HashMap<String, String>() {{
put("Host", "cvm.tencentcloudapi.com");
}});
client.DescribeInstances(req);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void TestCommonClient() throws TencentCloudSDKException {
hpf.setReqMethod(reqMethod);
cpf.setHttpProfile(hpf);

CommonClient client = new CommonClient("cvm", "2017-03-12", cred, "ap-guangzhou");
CommonClient client = new CommonClient("cvm", "2017-03-12", cred, "ap-guangzhou", cpf);
DescribeInstancesRequest req = new DescribeInstancesRequest();
client.commonRequest(req, "DescribeInstances");
}
Expand Down Expand Up @@ -99,7 +99,7 @@ public void TestCommonClientCall() throws TencentCloudSDKException {
hpf.setReqMethod(reqMethod);
cpf.setHttpProfile(hpf);

CommonClient client = new CommonClient("cvm", "2017-03-12", cred, "ap-guangzhou");
CommonClient client = new CommonClient("cvm", "2017-03-12", cred, "ap-guangzhou", cpf);
client.call("DescribeInstances",
"{\"Filters\":"
+ "[{\"Name\":\"zone\","
Expand Down