Spring RestTemplate或HttpClient 4.3.x不通过Authenticated Proxy传递压缩数据

时间:2015-12-14 01:36:05

标签: java apache-httpclient-4.x resttemplate

尝试使用HttpClient和Spring来完成代理服务器。很多问题和帮助。但是,我需要通过REST调用发送COMPRESSED数据。目前,它没有代理服务器正常工作。另外,我从访问日志中看到它也通过代理(未经身份验证)。以下是访问日志中的一些数据(此处使用Squid3,但与其他代理也有相同的行为)

1449876389.237      9 10.1.10.100 TCP_MISS/204 297 POST http://mymachine.domain.com:8080/j_spring_security_check - DIRECT/10.1.0.16 -
1449876389.377     16 10.1.10.100 TCP_MISS/201 1458 POST http://mymachine.domain.com:8080/api/items - DIRECT/10.1.0.16 application/json
1449876390.727      9 10.1.10.100 TCP_MISS/204 222 POST http://mymachine.domain.com:8080/j_spring_security_check - DIRECT/10.1.0.16 -
1449876391.031    241 10.1.10.100 TCP_MISS/201 1492 PUT http://mymachine.domain.com:8080/api/items/8fee3734-39ee-43eb-8009-6308d5c1aff1 - DIRECT/10.1.0.16 application/json

关键行是最后一行 - 数据被压缩为1492,返回了201的HTTPStatus。在不更改软件的情况下,只需将系统设置定义为指向Authenticated(摘要)代理服务器,即可看到这些行:

1449876352.292     44 10.1.10.100 TCP_MISS/201 1403 POST http://mymachine.domain.com:8080/api/items myuser DIRECT/10.1.0.16 application/json
1449876353.782      0 10.1.10.100 TCP_DENIED/407 4151 POST http://mymachine.domain.com:8080/j_spring_security_check - NONE/- text/html
1449876353.795     11 10.1.10.100 TCP_MISS/204 222 POST http://mymachine.domain.com:8080/j_spring_security_check myuser DIRECT/10.1.0.16 -
1449876353.853      0 10.1.10.100 TCP_DENIED/407 4239 PUT http://mymachine.domain.com:8080/api/items/3b505ae1-dc0c-4432-8604-8a107ab30bc6 - NONE/- text/html

注意,这次,数据显示为未压缩(4239),导致HTTPStatus为407.此外,不是内容类型显示为text / html而不是application / json。我使用的是Spring 4.1.x和HttpClient 4.3.6。有谁知道如何纠正这种行为并使其工作?

我相信使用的代码遵循相当常见的模式来通过代理服务器。如下所示。我尝试了很多变体(在一个或两个位置注释掉set代理,强制内容类型为' application / json'等)。不知道原因使得找到这个特定问题的解决方案变得不可能!最后,可能是最重要的事实之一:非常小的内容工作也可以完全成功地使用经过身份验证的代理,只有当PUT大小超过4K - 6K(不是那么大!)时才会失败( 407s)开始发生 - 而且每次都会发生。

HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.useSystemProperties();
String proxyUsername = System.getProperty("http.proxyUser", "");
if (StringUtils.isNotBlank(proxyUsername)) {
    String proxyPassword = System.getProperty("http.proxyPassword", "");
    String scheme = StringUtils.isNotBlank(System.getProperty("http.proxyHost", "")) ? "http" : "https";
    String proxyHost = System.getProperty("http.proxyHost",
                System.getProperty("https.proxyHost", ""));
    String proxyPortStr = System.getProperty("http.proxyPort",
                System.getProperty("https.proxyPort", ""));
    Integer proxyPort = Integer.decode(proxyPortStr);

    HttpHost proxy = new HttpHost(proxyHost, proxyPort, scheme);
    httpClientBuilder.setProxy(proxy);
    DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
    httpClientBuilder.setRoutePlanner(routePlanner);
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
                new UsernamePasswordCredentials(proxyUsername, proxyPassword));

    httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
}
HttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

0 个答案:

没有答案