Skip to content

Commit 91c0f63

Browse files
committed
Use HTTP/1.0 when connection pooling is disabled AsyncHttpClient#909
1 parent 79238a2 commit 91c0f63

File tree

5 files changed

+113
-167
lines changed

5 files changed

+113
-167
lines changed

api/src/main/java/org/asynchttpclient/netty/request/NettyRequestFactoryBase.java

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@
1313
*/
1414
package org.asynchttpclient.netty.request;
1515

16+
import static org.asynchttpclient.ntlm.NtlmUtils.getNTLM;
17+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.getAuthority;
18+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.getNonEmptyPath;
1619
import static org.asynchttpclient.util.AuthenticatorUtils.computeBasicAuthentication;
1720
import static org.asynchttpclient.util.AuthenticatorUtils.computeDigestAuthentication;
21+
import static org.asynchttpclient.util.HttpUtils.useProxyConnect;
1822
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
1923

2024
import java.io.IOException;
25+
import java.util.List;
2126

2227
import org.asynchttpclient.AsyncHttpClientConfig;
2328
import org.asynchttpclient.Realm;
2429
import org.asynchttpclient.Request;
30+
import org.asynchttpclient.Realm.AuthScheme;
2531
import org.asynchttpclient.ntlm.NtlmEngine;
2632
import org.asynchttpclient.proxy.ProxyServer;
2733
import org.asynchttpclient.spnego.SpnegoEngine;
@@ -34,7 +40,77 @@ public abstract class NettyRequestFactoryBase {
3440
public NettyRequestFactoryBase(AsyncHttpClientConfig config) {
3541
this.config = config;
3642
}
43+
44+
protected abstract List<String> getProxyAuthorizationHeader(Request request);
45+
46+
protected String firstRequestOnlyProxyAuthorizationHeader(Request request, ProxyServer proxyServer, boolean connect) throws IOException {
47+
String proxyAuthorization = null;
48+
49+
if (connect) {
50+
List<String> auth = getProxyAuthorizationHeader(request);
51+
String ntlmHeader = getNTLM(auth);
52+
if (ntlmHeader != null) {
53+
proxyAuthorization = ntlmHeader;
54+
}
55+
56+
} else if (proxyServer != null && proxyServer.getPrincipal() != null && isNonEmpty(proxyServer.getNtlmDomain())) {
57+
List<String> auth = getProxyAuthorizationHeader(request);
58+
if (getNTLM(auth) == null) {
59+
String msg = NtlmEngine.INSTANCE.generateType1Msg();
60+
proxyAuthorization = "NTLM " + msg;
61+
}
62+
}
63+
64+
return proxyAuthorization;
65+
}
3766

67+
protected String requestUri(Uri uri, ProxyServer proxyServer, boolean connect) {
68+
if (connect)
69+
return getAuthority(uri);
70+
71+
else if (proxyServer != null && !useProxyConnect(uri))
72+
return uri.toUrl();
73+
74+
else {
75+
String path = getNonEmptyPath(uri);
76+
if (isNonEmpty(uri.getQuery()))
77+
return path + "?" + uri.getQuery();
78+
else
79+
return path;
80+
}
81+
}
82+
83+
protected String systematicProxyAuthorizationHeader(Request request, ProxyServer proxyServer, Realm realm, boolean connect) {
84+
85+
String proxyAuthorization = null;
86+
87+
if (!connect && proxyServer != null && proxyServer.getPrincipal() != null && proxyServer.getScheme() == AuthScheme.BASIC) {
88+
proxyAuthorization = computeBasicAuthentication(proxyServer);
89+
} else if (realm != null && realm.getUsePreemptiveAuth() && realm.isTargetProxy()) {
90+
91+
switch (realm.getScheme()) {
92+
case BASIC:
93+
proxyAuthorization = computeBasicAuthentication(realm);
94+
break;
95+
case DIGEST:
96+
if (isNonEmpty(realm.getNonce()))
97+
proxyAuthorization = computeDigestAuthentication(realm);
98+
break;
99+
case NTLM:
100+
case KERBEROS:
101+
case SPNEGO:
102+
// NTLM, KERBEROS and SPNEGO are only set on the first request,
103+
// see firstRequestOnlyAuthorizationHeader
104+
case NONE:
105+
break;
106+
default:
107+
throw new IllegalStateException("Invalid Authentication " + realm);
108+
}
109+
}
110+
111+
return proxyAuthorization;
112+
}
113+
38114
protected String firstRequestOnlyAuthorizationHeader(Request request, Uri uri, ProxyServer proxyServer, Realm realm) throws IOException {
39115
String authorizationHeader = null;
40116

@@ -64,10 +140,10 @@ else if (request.getVirtualHost() != null)
64140
break;
65141
}
66142
}
67-
143+
68144
return authorizationHeader;
69145
}
70-
146+
71147
protected String systematicAuthorizationHeader(Request request, Uri uri, Realm realm) {
72148

73149
String authorizationHeader = null;
@@ -85,7 +161,8 @@ protected String systematicAuthorizationHeader(Request request, Uri uri, Realm r
85161
case NTLM:
86162
case KERBEROS:
87163
case SPNEGO:
88-
// NTLM, KERBEROS and SPNEGO are only set on the first request, see firstRequestOnlyAuthorizationHeader
164+
// NTLM, KERBEROS and SPNEGO are only set on the first request,
165+
// see firstRequestOnlyAuthorizationHeader
89166
case NONE:
90167
break;
91168
default:

providers/netty3/src/main/java/org/asynchttpclient/netty/request/NettyRequestFactory.java

Lines changed: 15 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313
*/
1414
package org.asynchttpclient.netty.request;
1515

16-
import static org.asynchttpclient.ntlm.NtlmUtils.getNTLM;
17-
import static org.asynchttpclient.util.AsyncHttpProviderUtils.*;
18-
import static org.asynchttpclient.util.AuthenticatorUtils.computeBasicAuthentication;
19-
import static org.asynchttpclient.util.AuthenticatorUtils.computeDigestAuthentication;
16+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.DEFAULT_CHARSET;
17+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.hostHeader;
18+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.keepAliveHeaderValue;
19+
import static org.asynchttpclient.util.AsyncHttpProviderUtils.urlEncodeFormParams;
2020
import static org.asynchttpclient.util.HttpUtils.isSecure;
2121
import static org.asynchttpclient.util.HttpUtils.isWebSocket;
22-
import static org.asynchttpclient.util.HttpUtils.useProxyConnect;
2322
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
2423
import static org.asynchttpclient.ws.WebSocketUtils.getKey;
2524

@@ -30,7 +29,6 @@
3029

3130
import org.asynchttpclient.AsyncHttpClientConfig;
3231
import org.asynchttpclient.Realm;
33-
import org.asynchttpclient.Realm.AuthScheme;
3432
import org.asynchttpclient.Request;
3533
import org.asynchttpclient.cookie.CookieEncoder;
3634
import org.asynchttpclient.netty.request.body.NettyBody;
@@ -42,7 +40,6 @@
4240
import org.asynchttpclient.netty.request.body.NettyFileBody;
4341
import org.asynchttpclient.netty.request.body.NettyInputStreamBody;
4442
import org.asynchttpclient.netty.request.body.NettyMultipartBody;
45-
import org.asynchttpclient.ntlm.NtlmEngine;
4643
import org.asynchttpclient.proxy.ProxyServer;
4744
import org.asynchttpclient.request.body.generator.FileBodyGenerator;
4845
import org.asynchttpclient.request.body.generator.InputStreamBodyGenerator;
@@ -63,77 +60,13 @@ public NettyRequestFactory(AsyncHttpClientConfig config) {
6360
super(config);
6461
}
6562

66-
private String requestUri(Uri uri, ProxyServer proxyServer, HttpMethod method) {
67-
if (method == HttpMethod.CONNECT)
68-
return getAuthority(uri);
69-
70-
else if (proxyServer != null && !useProxyConnect(uri))
71-
return uri.toUrl();
72-
73-
else {
74-
String path = getNonEmptyPath(uri);
75-
if (isNonEmpty(uri.getQuery()))
76-
return path + "?" + uri.getQuery();
77-
else
78-
return path;
79-
}
80-
}
81-
82-
public String firstRequestOnlyProxyAuthorizationHeader(Request request, ProxyServer proxyServer, HttpMethod method) throws IOException {
83-
String proxyAuthorization = null;
84-
85-
if (method == HttpMethod.CONNECT) {
86-
List<String> auth = request.getHeaders().get(HttpHeaders.Names.PROXY_AUTHORIZATION);
87-
String ntlmHeader = getNTLM(auth);
88-
if (ntlmHeader != null) {
89-
proxyAuthorization = ntlmHeader;
90-
}
91-
92-
} else if (proxyServer != null && proxyServer.getPrincipal() != null && isNonEmpty(proxyServer.getNtlmDomain())) {
93-
List<String> auth = request.getHeaders().get(HttpHeaders.Names.PROXY_AUTHORIZATION);
94-
if (getNTLM(auth) == null) {
95-
String msg = NtlmEngine.INSTANCE.generateType1Msg();
96-
proxyAuthorization = "NTLM " + msg;
97-
}
98-
}
99-
100-
return proxyAuthorization;
63+
protected List<String> getProxyAuthorizationHeader(Request request) {
64+
return request.getHeaders().get(HttpHeaders.Names.PROXY_AUTHORIZATION);
10165
}
10266

103-
private String systematicProxyAuthorizationHeader(Request request, ProxyServer proxyServer, Realm realm, HttpMethod method) {
104-
105-
String proxyAuthorization = null;
106-
107-
if (method != HttpMethod.CONNECT && proxyServer != null && proxyServer.getPrincipal() != null && proxyServer.getScheme() == AuthScheme.BASIC) {
108-
proxyAuthorization = computeBasicAuthentication(proxyServer);
109-
110-
} else if (realm != null && realm.getUsePreemptiveAuth() && realm.isTargetProxy()) {
111-
112-
switch (realm.getScheme()) {
113-
case BASIC:
114-
proxyAuthorization = computeBasicAuthentication(realm);
115-
break;
116-
case DIGEST:
117-
if (isNonEmpty(realm.getNonce()))
118-
proxyAuthorization = computeDigestAuthentication(realm);
119-
break;
120-
case NTLM:
121-
case KERBEROS:
122-
case SPNEGO:
123-
// NTLM, KERBEROS and SPNEGO are only set on the first request, see firstRequestOnlyAuthorizationHeader
124-
case NONE:
125-
break;
126-
default:
127-
throw new IllegalStateException("Invalid Authentication " + realm);
128-
}
129-
}
130-
131-
return proxyAuthorization;
132-
}
133-
134-
private NettyBody body(Request request, HttpMethod method) throws IOException {
67+
private NettyBody body(Request request, boolean connect) throws IOException {
13568
NettyBody nettyBody = null;
136-
if (method != HttpMethod.CONNECT) {
69+
if (!connect) {
13770

13871
Charset bodyCharset = request.getBodyCharset() == null ? DEFAULT_CHARSET : request.getBodyCharset();
13972

@@ -193,10 +126,12 @@ public NettyRequest newNettyRequest(Request request, Uri uri, boolean forceConne
193126
throws IOException {
194127

195128
HttpMethod method = forceConnect ? HttpMethod.CONNECT : HttpMethod.valueOf(request.getMethod());
196-
HttpVersion httpVersion = method == HttpMethod.CONNECT && proxyServer.isForceHttp10() ? HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1;
197-
String requestUri = requestUri(uri, proxyServer, method);
129+
boolean connect = method == HttpMethod.CONNECT;
130+
131+
HttpVersion httpVersion = connect && proxyServer.isForceHttp10() ? HttpVersion.HTTP_1_0 : HttpVersion.HTTP_1_1;
132+
String requestUri = requestUri(uri, proxyServer, connect);
198133

199-
NettyBody body = body(request, method);
134+
NettyBody body = body(request, connect);
200135

201136
HttpRequest httpRequest;
202137
NettyRequest nettyRequest;
@@ -214,7 +149,7 @@ public NettyRequest newNettyRequest(Request request, Uri uri, boolean forceConne
214149

215150
HttpHeaders headers = httpRequest.headers();
216151

217-
if (method != HttpMethod.CONNECT) {
152+
if (!connect) {
218153
// assign headers as configured on request
219154
for (Entry<String, List<String>> header : request.getHeaders()) {
220155
headers.set(header.getKey(), header.getValue());
@@ -259,7 +194,7 @@ public NettyRequest newNettyRequest(Request request, Uri uri, boolean forceConne
259194
// don't override authorization but append
260195
addAuthorizationHeader(headers, systematicAuthorizationHeader(request, uri, realm));
261196

262-
setProxyAuthorizationHeader(headers, systematicProxyAuthorizationHeader(request, proxyServer, realm, method));
197+
setProxyAuthorizationHeader(headers, systematicProxyAuthorizationHeader(request, proxyServer, realm, connect));
263198

264199
// Add default accept headers
265200
if (!headers.contains(HttpHeaders.Names.ACCEPT))

providers/netty3/src/main/java/org/asynchttpclient/netty/request/NettyRequestSender.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ private <T> ListenableFuture<T> sendRequestWithNewChannel(//
254254
// some headers are only set when performing the first request
255255
HttpHeaders headers = future.getNettyRequest().getHttpRequest().headers();
256256
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
257-
HttpMethod method = future.getNettyRequest().getHttpRequest().getMethod();
257+
boolean connect = future.getNettyRequest().getHttpRequest().getMethod() == HttpMethod.CONNECT;
258258
requestFactory.addAuthorizationHeader(headers, requestFactory.firstRequestOnlyAuthorizationHeader(request, uri, proxy, realm));
259-
requestFactory.setProxyAuthorizationHeader(headers, requestFactory.firstRequestOnlyProxyAuthorizationHeader(request, proxy, method));
259+
requestFactory.setProxyAuthorizationHeader(headers, requestFactory.firstRequestOnlyProxyAuthorizationHeader(request, proxy, connect));
260260

261261
// Do not throw an exception when we need an extra connection for a
262262
// redirect

0 commit comments

Comments
 (0)