Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dd6f508

Browse files
ssy352959096JacksonTian
authored andcommitted
Add HTTP message details for HTTP requests and responses
1 parent f426a93 commit dd6f508

File tree

6 files changed

+213
-12
lines changed

6 files changed

+213
-12
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,6 @@ The following code example shows the three main steps to use Alibaba Cloud Java
9595
}
9696
}
9797
```
98+
99+
## Debugging
100+
If there is an environment variable DEBUG=sdk , all http request/response will work in debug mode.

README_zh.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,6 @@
8383
}
8484
}
8585
```
86-
86+
## 调试
87+
如果存在环境变量 `DEBUG=sdk` ,所有的http请求和响应都将启用调试输出。
8788

aliyun-java-sdk-core/src/main/java/com/aliyuncs/DefaultAcsClient.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@
2222
import com.aliyuncs.exceptions.ErrorCodeConstant;
2323
import com.aliyuncs.exceptions.ErrorMessageConstant;
2424
import com.aliyuncs.exceptions.ServerException;
25-
import com.aliyuncs.http.*;
25+
import com.aliyuncs.http.FormatType;
26+
import com.aliyuncs.http.HttpClientFactory;
27+
import com.aliyuncs.http.HttpUtil;
28+
import com.aliyuncs.http.HttpRequest;
29+
import com.aliyuncs.http.HttpResponse;
30+
import com.aliyuncs.http.IHttpClient;
31+
import com.aliyuncs.http.UserAgentConfig;
2632
import com.aliyuncs.profile.DefaultProfile;
2733
import com.aliyuncs.profile.IClientProfile;
2834
import com.aliyuncs.reader.Reader;
@@ -240,12 +246,14 @@ private <T extends AcsResponse> HttpResponse doAction(AcsRequest<T> request, boo
240246
if (request.getSysProtocol() == null) {
241247
request.setSysProtocol(this.clientProfile.getHttpClientConfig().getProtocolType());
242248
}
243-
request.putHeaderParameter("User-Agent",
244-
UserAgentConfig.resolve(request.getSysUserAgentConfig(), this.userAgentConfig));
249+
request.putHeaderParameter("User-Agent", UserAgentConfig.resolve(request.getSysUserAgentConfig(),
250+
this.userAgentConfig));
245251
try {
246252
HttpRequest httpRequest = request.signRequest(signer, credentials, format, domain);
253+
HttpUtil.debugHttpRequest(request);
247254
HttpResponse response;
248255
response = this.httpClient.syncInvoke(httpRequest);
256+
HttpUtil.debugHttpResponse(response);
249257
return response;
250258
} catch (SocketTimeoutException exp) {
251259
throw new ClientException("SDK.ServerUnreachable",
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.aliyuncs.http;
2+
3+
import java.util.Map;
4+
import java.util.Map.Entry;
5+
6+
import org.apache.commons.logging.Log;
7+
import org.apache.commons.logging.LogFactory;
8+
9+
import com.aliyuncs.exceptions.ClientException;
10+
11+
public class HttpUtil {
12+
13+
private final static Log log = LogFactory.getLog(HttpUtil.class);
14+
15+
private static Boolean isHttpDebug;
16+
17+
private static Boolean isHttpContentDebug;
18+
19+
static {
20+
Boolean flag = "sdk".equalsIgnoreCase(System.getenv("DEBUG"));
21+
isHttpDebug = flag;
22+
isHttpContentDebug = flag;
23+
}
24+
25+
public static Boolean getIsHttpDebug() {
26+
return isHttpDebug;
27+
}
28+
29+
public static void setIsHttpDebug(Boolean isHttpDebug) {
30+
HttpUtil.isHttpDebug = isHttpDebug;
31+
}
32+
33+
public static Boolean getIsHttpContentDebug() {
34+
return isHttpContentDebug;
35+
}
36+
37+
public static void setIsHttpContentDebug(Boolean isHttpContentDebug) {
38+
HttpUtil.isHttpContentDebug = isHttpContentDebug;
39+
}
40+
41+
public static String debugHttpRequest(HttpRequest request) throws ClientException {
42+
if (isHttpDebug) {
43+
String protocol = request.getSysUrl().split("://")[0].toUpperCase() + "/1.1";
44+
StringBuilder debugString = new StringBuilder("> " + request.getSysMethod() + " " + protocol + "\n> ");
45+
Map<String, String> requestHeaders = request.getSysHeaders();
46+
for (Entry<String, String> entry : requestHeaders.entrySet()) {
47+
debugString.append(entry.getKey() + " : " + entry.getValue() + "\n> ");
48+
}
49+
if (isHttpContentDebug) {
50+
debugString.append("\n" + request.getHttpContentString());
51+
}
52+
log.info("\n" + debugString);
53+
return debugString.toString();
54+
} else {
55+
return null;
56+
}
57+
}
58+
59+
public static String debugHttpResponse(HttpResponse response) throws ClientException {
60+
if (isHttpDebug) {
61+
String protocol = response.getSysUrl().split("://")[0].toUpperCase() + "/1.1";
62+
StringBuilder debugString = new StringBuilder("< " + protocol + " " + response.getStatus() + "\n< ");
63+
Map<String, String> responseHeaders = response.getSysHeaders();
64+
for (Entry<String, String> entry : responseHeaders.entrySet()) {
65+
debugString.append(entry.getKey() + " : " + entry.getValue() + "\n< ");
66+
}
67+
if (isHttpContentDebug) {
68+
debugString.append("\n" + response.getHttpContentString());
69+
}
70+
log.info("\n" + debugString);
71+
return debugString.toString();
72+
} else {
73+
return null;
74+
}
75+
}
76+
}

aliyun-java-sdk-core/src/test/java/com/aliyuncs/DefaultAcsClientTest.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package com.aliyuncs;
22

3+
import static org.mockito.Matchers.any;
4+
35
import java.io.IOException;
46
import java.lang.reflect.Field;
57
import java.net.SocketTimeoutException;
68
import java.security.InvalidKeyException;
79
import java.security.NoSuchAlgorithmException;
810

9-
import com.aliyuncs.http.*;
1011
import org.junit.Assert;
1112
import org.junit.Rule;
1213
import org.junit.Test;
1314
import org.junit.rules.ExpectedException;
1415
import org.junit.runner.RunWith;
16+
import org.mockito.BDDMockito;
1517
import org.mockito.Mockito;
16-
import org.mockito.runners.MockitoJUnitRunner;
18+
import org.powermock.api.mockito.PowerMockito;
1719
import org.powermock.core.classloader.annotations.PrepareForTest;
20+
import org.powermock.modules.junit4.PowerMockRunner;
1821

1922
import com.aliyuncs.auth.Credential;
2023
import com.aliyuncs.auth.LegacyCredentials;
@@ -26,12 +29,20 @@
2629
import com.aliyuncs.exceptions.ErrorCodeConstant;
2730
import com.aliyuncs.exceptions.ErrorMessageConstant;
2831
import com.aliyuncs.exceptions.ServerException;
32+
import com.aliyuncs.http.FormatType;
33+
import com.aliyuncs.http.HttpClientConfig;
34+
import com.aliyuncs.http.HttpRequest;
35+
import com.aliyuncs.http.HttpResponse;
36+
import com.aliyuncs.http.HttpUtil;
37+
import com.aliyuncs.http.IHttpClient;
38+
import com.aliyuncs.http.ProtocolType;
39+
import com.aliyuncs.http.UserAgentConfig;
2940
import com.aliyuncs.http.clients.CompatibleUrlConnClient;
3041
import com.aliyuncs.profile.DefaultProfile;
3142
import com.aliyuncs.regions.ProductDomain;
3243

33-
@RunWith(MockitoJUnitRunner.class)
34-
@PrepareForTest(HttpClientFactory.class)
44+
@RunWith(PowerMockRunner.class)
45+
@PrepareForTest(HttpUtil.class)
3546
public class DefaultAcsClientTest {
3647
@Rule
3748
public ExpectedException thrown = ExpectedException.none();
@@ -104,7 +115,7 @@ public void testShutdown() {
104115

105116
@SuppressWarnings("deprecation")
106117
private DefaultAcsClient initDefaultAcsClient() throws NoSuchFieldException, SecurityException,
107-
IllegalArgumentException, IllegalAccessException {
118+
IllegalArgumentException, IllegalAccessException, ClientException {
108119
Credential credential = Mockito.mock(Credential.class);
109120
Mockito.when(credential.getSecurityToken()).thenReturn(null);
110121
DefaultProfile profile = Mockito.mock(DefaultProfile.class);
@@ -117,7 +128,9 @@ private DefaultAcsClient initDefaultAcsClient() throws NoSuchFieldException, Sec
117128
HttpClientConfig httpClientConfig = Mockito.mock(HttpClientConfig.class);
118129
Mockito.when(httpClientConfig.getProtocolType()).thenReturn(ProtocolType.HTTP);
119130
Mockito.when(profile.getHttpClientConfig()).thenReturn(httpClientConfig);
120-
131+
PowerMockito.mockStatic(HttpUtil.class);
132+
BDDMockito.given(HttpUtil.debugHttpRequest(any(HttpRequest.class))).willReturn(null);
133+
BDDMockito.given(HttpUtil.debugHttpResponse(any(HttpResponse.class))).willReturn(null);
121134
return client;
122135
}
123136

@@ -153,7 +166,7 @@ private HttpResponse initHttpResponse() throws ClientException {
153166

154167
@Test
155168
public void testRestoreSSLCertificate() throws NoSuchFieldException, SecurityException, IllegalArgumentException,
156-
IllegalAccessException {
169+
IllegalAccessException, ClientException {
157170
DefaultAcsClient client = initDefaultAcsClient();
158171
client.restoreSSLCertificate();
159172
client.ignoreSSLCertificate();
@@ -171,6 +184,7 @@ public void testGetAcsResponse() throws NoSuchFieldException, SecurityException,
171184
Mockito.doReturn("endpoint").when(endpointResolver).resolve(Mockito.any(ResolveEndpointRequest.class));
172185
HttpResponse response = initHttpResponse();
173186
Mockito.doReturn(response).when(getHttpClient(client)).syncInvoke(Mockito.any(HttpRequest.class));
187+
Mockito.doReturn("http://test.domain").when(response).getSysUrl();
174188
AcsRequest request = initRequest(DescribeEndpointsResponse.class);
175189

176190
Assert.assertTrue(client.getAcsResponse(request) instanceof DescribeEndpointsResponse);
@@ -194,6 +208,7 @@ public void testDoActionBranch() throws ClientException, IOException, IllegalArg
194208
DefaultAcsClient client = initDefaultAcsClient();
195209
HttpResponse response = Mockito.mock(HttpResponse.class);
196210
Mockito.doReturn(response).when(getHttpClient(client)).syncInvoke(Mockito.any(HttpRequest.class));
211+
Mockito.doReturn("http://test.domain").when(response).getSysUrl();
197212
DefaultEndpointResolver endpointResolver = Mockito.mock(DefaultEndpointResolver.class);
198213
client.setEndpointResolver(endpointResolver);
199214
Mockito.doReturn("endpoint").when(endpointResolver).resolve(Mockito.any(ResolveEndpointRequest.class));
@@ -306,6 +321,7 @@ public void testGetAcsResponseInvalidServerResponseException() throws NoSuchFiel
306321
Mockito.when(response.isSuccess()).thenReturn(true);
307322
Mockito.when(response.getHttpContentType()).thenReturn(FormatType.XML);
308323
Mockito.when(response.getHttpContentString()).thenReturn(null);
324+
Mockito.doReturn("http://test.domain").when(response).getSysUrl();
309325
Mockito.doReturn(response).when(getHttpClient(client)).syncInvoke(Mockito.any(HttpRequest.class));
310326
AcsRequest request = initRequest(DescribeEndpointsResponse.class);
311327

@@ -612,7 +628,8 @@ public void userAgentConfigTest() {
612628
client.appendUserAgent("test", "1.2.3");
613629
client.appendUserAgent("order", "1.2.2");
614630
String userAgent = UserAgentConfig.resolve(null, client.getUserAgentConfig());
615-
String resultStr = UserAgentConfig.getDefaultMessage() + " Client/CompatibleUrlConnClient test/1.2.3 order/1.2.2";
631+
String resultStr = UserAgentConfig.getDefaultMessage()
632+
+ " Client/CompatibleUrlConnClient test/1.2.3 order/1.2.2";
616633
Assert.assertEquals(resultStr, userAgent);
617634
}
618635
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.aliyuncs.http;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
import org.mockito.Mockito;
9+
10+
import com.aliyuncs.exceptions.ClientException;
11+
12+
public class HttpUtilTest {
13+
14+
@Test
15+
public void testHttpDebug() {
16+
HttpUtil httpUtil = new HttpUtil();
17+
Assert.assertEquals(HttpUtil.getIsHttpDebug(), "sdk".equalsIgnoreCase(System.getenv("DEBUG")));
18+
Assert.assertEquals(HttpUtil.getIsHttpContentDebug(), "sdk".equalsIgnoreCase(System.getenv("DEBUG")));
19+
if (HttpUtil.getIsHttpDebug()) {
20+
HttpUtil.setIsHttpDebug(false);
21+
Assert.assertFalse(HttpUtil.getIsHttpDebug());
22+
} else {
23+
HttpUtil.setIsHttpDebug(true);
24+
Assert.assertTrue(HttpUtil.getIsHttpDebug());
25+
}
26+
if (HttpUtil.getIsHttpContentDebug()) {
27+
HttpUtil.setIsHttpContentDebug(false);
28+
Assert.assertFalse(HttpUtil.getIsHttpContentDebug());
29+
} else {
30+
HttpUtil.setIsHttpContentDebug(true);
31+
Assert.assertTrue(HttpUtil.getIsHttpContentDebug());
32+
}
33+
HttpUtil.setIsHttpDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
34+
HttpUtil.setIsHttpContentDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
35+
}
36+
37+
@Test
38+
public void testDebugHttpRequest() throws ClientException {
39+
HttpRequest request = Mockito.mock(HttpRequest.class);
40+
Mockito.when(request.getSysMethod()).thenReturn(MethodType.GET);
41+
Mockito.when(request.getSysUrl()).thenReturn("http://test.domain");
42+
Map<String, String> requestHeaders = new HashMap<String, String>();
43+
Mockito.when(request.getHttpContentString()).thenReturn("request body");
44+
requestHeaders.put("test1", "test1");
45+
requestHeaders.put("test2", "test2");
46+
Mockito.when(request.getSysHeaders()).thenReturn(requestHeaders);
47+
String exceptString = "> GET HTTP/1.1\n> test2 : test2\n> test1 : test1\n> \nrequest body";
48+
49+
HttpUtil.setIsHttpDebug(true);
50+
HttpUtil.setIsHttpContentDebug(true);
51+
Assert.assertEquals(HttpUtil.debugHttpRequest(request), exceptString);
52+
53+
HttpUtil.setIsHttpContentDebug(false);
54+
exceptString = "> GET HTTP/1.1\n> test2 : test2\n> test1 : test1\n> ";
55+
Assert.assertEquals(HttpUtil.debugHttpRequest(request), exceptString);
56+
57+
HttpUtil.setIsHttpDebug(false);
58+
Assert.assertNull(HttpUtil.debugHttpRequest(request));
59+
60+
HttpUtil.setIsHttpContentDebug(true);
61+
Assert.assertNull(HttpUtil.debugHttpRequest(request));
62+
63+
HttpUtil.setIsHttpDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
64+
HttpUtil.setIsHttpContentDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
65+
}
66+
67+
@Test
68+
public void testDebugHttpResponse() throws ClientException {
69+
HttpResponse response = Mockito.mock(HttpResponse.class);
70+
Mockito.when(response.getStatus()).thenReturn(200);
71+
Mockito.when(response.getSysUrl()).thenReturn("http://test.domain");
72+
Mockito.when(response.getHttpContentString()).thenReturn("response body");
73+
Map<String, String> reasponseHeaders = new HashMap<String, String>();
74+
reasponseHeaders.put("test1", "test1");
75+
reasponseHeaders.put("test2", "test2");
76+
Mockito.when(response.getSysHeaders()).thenReturn(reasponseHeaders);
77+
String exceptString = "< HTTP/1.1 200\n< test2 : test2\n< test1 : test1\n< \nresponse body";
78+
79+
HttpUtil.setIsHttpDebug(true);
80+
HttpUtil.setIsHttpContentDebug(true);
81+
Assert.assertEquals(HttpUtil.debugHttpResponse(response), exceptString);
82+
83+
HttpUtil.setIsHttpContentDebug(false);
84+
exceptString = "< HTTP/1.1 200\n< test2 : test2\n< test1 : test1\n< ";
85+
Assert.assertEquals(HttpUtil.debugHttpResponse(response), exceptString);
86+
87+
HttpUtil.setIsHttpDebug(false);
88+
Assert.assertNull(HttpUtil.debugHttpResponse(response));
89+
90+
HttpUtil.setIsHttpContentDebug(true);
91+
Assert.assertNull(HttpUtil.debugHttpResponse(response));
92+
93+
HttpUtil.setIsHttpDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
94+
HttpUtil.setIsHttpContentDebug("sdk".equalsIgnoreCase(System.getenv("DEBUG")));
95+
}
96+
}

0 commit comments

Comments
 (0)