I am using apache http client v4.5 to do a HTTP POST to an authorized required http proxy server.
Because of some other dependencies, I tend to use enabled Expect-Continue handshake in the http client config.
Related code snips:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(host, port, AuthScope.ANY_REALM),
new UsernamePasswordCredentials(username, password));
credsProvider.setCredentials(
new AuthScope(proxyHost, proxyPort,AuthScope.ANY_REALM),
new UsernamePasswordCredentials(proxyUsername, proxyPassword));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider).build();
try {
HttpHost target = new HttpHost(host, port, "http");
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.setExpectContinueEnabled(true)
.build();
HttpPost httppost = new HttpPost("/URI");
httppost.setConfig(config);
StringEntity reqEntity = new StringEntity(entityString,"UTF-8");
reqEntity.setContentType("application/json");
httppost.setEntity(reqEntity);
CloseableHttpResponse response = httpclient.execute(target, httppost);
try {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
} finally {
httpclient.close();
}
As the target proxy server is required authorization, the first response from the proxy server is 407, then the proxy authorization is sent by http client as recorded in its log, but the header "Proxy-Authorization" is not included from the actual http request according to wireshark capture. As a result, 400 bad request is returned ... Here is the apache log
http-outgoing-0 >> POST http://targetHost:targetPort/uri/ HTTP/1.1
http-outgoing-0 >> Content-Length: 217
http-outgoing-0 >> Content-Type: application/json
http-outgoing-0 >> Host: targetHost:targetPort
http-outgoing-0 >> Proxy-Connection: Keep-Alive
http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5 (Java/1.7.0)
http-outgoing-0 >> Expect: 100-continue
http-outgoing-0 >> Accept-Encoding: gzip,deflate
http-outgoing-0 >> Proxy-Authorization: Basic xxxxxxx
http-outgoing-0 << HTTP/1.1 400 Bad Request
http-outgoing-0 << Server: squid/3.3.8
http-outgoing-0 << Mime-Version: 1.0
http-outgoing-0 << Date: Mon, 31 Aug 2015 02:03:28 GMT
http-outgoing-0 << Content-Type: text/html
http-outgoing-0 << Content-Length: 3166
http-outgoing-0 << X-Squid-Error: ERR_INVALID_URL 0
http-outgoing-0 << Vary: Accept-Language
http-outgoing-0 << Content-Language: en
http-outgoing-0 << X-Cache: MISS from proxyHost
http-outgoing-0 << X-Cache-Lookup: NONE from proxyHost:proxyPort
http-outgoing-0 << Via: 1.1 proxyHost (squid/3.3.8)
http-outgoing-0 << Connection: close
Here is the snapshot of wireshark capture in which "Proxy-Authorization" header is disappeared!
POST http://targetHost:targetPort/uri/ HTTP/1.1
Content-Length: 217
Content-Type: application/json
Host: targetHost:targetPort
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5 (Java/1.7.0)
Expect: 100-continue
Accept-Encoding: gzip,deflate
I tried without Expect-continue handshake as blow, and it works fine to get 201 response.
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.setExpectContinueEnabled(false)
.build();
Anyone would help to understand why it fails with expect-continue on an authorized http proxy? If I really need to set expect-continue attribute, how to overcome the problem?
Thanks a lot!