Skip to content

Commit 536ce8e

Browse files
author
Stephane Landelle
committed
headers.getAll is already case insensitive
1 parent db22c15 commit 536ce8e

File tree

1 file changed

+52
-67
lines changed
  • providers/netty/src/main/java/org/asynchttpclient/providers/netty/handler

1 file changed

+52
-67
lines changed

providers/netty/src/main/java/org/asynchttpclient/providers/netty/handler/HttpProtocol.java

Lines changed: 52 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@
2929
import java.io.IOException;
3030
import java.net.MalformedURLException;
3131
import java.net.URI;
32-
import java.util.ArrayList;
3332
import java.util.List;
34-
import java.util.Map.Entry;
3533

3634
import org.asynchttpclient.AsyncHandler;
3735
import org.asynchttpclient.AsyncHandler.STATE;
@@ -67,6 +65,10 @@ public HttpProtocol(Channels channels, AsyncHttpClientConfig config, NettyAsyncH
6765
super(channels, config, nettyConfig, requestSender);
6866
}
6967

68+
private Realm.RealmBuilder newRealmBuilder(Realm realm) {
69+
return realm != null ? new Realm.RealmBuilder().clone(realm) : new Realm.RealmBuilder();
70+
}
71+
7072
private Realm kerberosChallenge(List<String> proxyAuth, Request request, ProxyServer proxyServer, FluentCaseInsensitiveStringsMap headers, Realm realm,
7173
NettyResponseFuture<?> future) throws NTLMEngineException {
7274

@@ -78,13 +80,12 @@ private Realm kerberosChallenge(List<String> proxyAuth, Request request, ProxySe
7880
headers.remove(HttpHeaders.Names.AUTHORIZATION);
7981
headers.add(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challengeHeader);
8082

81-
Realm.RealmBuilder realmBuilder;
82-
if (realm != null) {
83-
realmBuilder = new Realm.RealmBuilder().clone(realm);
84-
} else {
85-
realmBuilder = new Realm.RealmBuilder();
86-
}
87-
return realmBuilder.setUri(uri.getRawPath()).setMethodName(request.getMethod()).setScheme(Realm.AuthScheme.KERBEROS).build();
83+
return newRealmBuilder(realm)//
84+
.setUri(uri.getRawPath())//
85+
.setMethodName(request.getMethod())//
86+
.setScheme(Realm.AuthScheme.KERBEROS)//
87+
.build();
88+
8889
} catch (Throwable throwable) {
8990
if (isNTLM(proxyAuth)) {
9091
return ntlmChallenge(proxyAuth, request, proxyServer, headers, realm, future);
@@ -97,38 +98,35 @@ private Realm kerberosChallenge(List<String> proxyAuth, Request request, ProxySe
9798
private Realm ntlmChallenge(List<String> wwwAuth, Request request, ProxyServer proxyServer, FluentCaseInsensitiveStringsMap headers, Realm realm, NettyResponseFuture<?> future)
9899
throws NTLMEngineException {
99100

100-
boolean useRealm = (proxyServer == null && realm != null);
101+
boolean useRealm = proxyServer == null && realm != null;
101102

102103
String ntlmDomain = useRealm ? realm.getNtlmDomain() : proxyServer.getNtlmDomain();
103104
String ntlmHost = useRealm ? realm.getNtlmHost() : proxyServer.getHost();
104105
String principal = useRealm ? realm.getPrincipal() : proxyServer.getPrincipal();
105106
String password = useRealm ? realm.getPassword() : proxyServer.getPassword();
106107

107-
Realm newRealm;
108108
if (realm != null && !realm.isNtlmMessageType2Received()) {
109109
String challengeHeader = NTLMEngine.INSTANCE.generateType1Msg(ntlmDomain, ntlmHost);
110110

111111
URI uri = request.getURI();
112112
headers.add(HttpHeaders.Names.AUTHORIZATION, "NTLM " + challengeHeader);
113-
newRealm = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme()).setUri(uri.getRawPath()).setMethodName(request.getMethod())
114-
.setNtlmMessageType2Received(true).build();
115113
future.getAndSetAuth(false);
114+
return newRealmBuilder(realm)//
115+
.setScheme(realm.getAuthScheme())//
116+
.setUri(uri.getRawPath())//
117+
.setMethodName(request.getMethod())//
118+
.setNtlmMessageType2Received(true)//
119+
.build();
120+
116121
} else {
117122
addType3NTLMAuthorizationHeader(wwwAuth, headers, principal, password, ntlmDomain, ntlmHost);
118-
119-
Realm.RealmBuilder realmBuilder;
120-
Realm.AuthScheme authScheme;
121-
if (realm != null) {
122-
realmBuilder = new Realm.RealmBuilder().clone(realm);
123-
authScheme = realm.getAuthScheme();
124-
} else {
125-
realmBuilder = new Realm.RealmBuilder();
126-
authScheme = Realm.AuthScheme.NTLM;
127-
}
128-
newRealm = realmBuilder.setScheme(authScheme).setUri(request.getURI().getPath()).setMethodName(request.getMethod()).build();
123+
Realm.AuthScheme authScheme = realm != null ? realm.getAuthScheme() : Realm.AuthScheme.NTLM;
124+
return newRealmBuilder(realm)//
125+
.setScheme(authScheme)//
126+
.setUri(request.getURI().getPath())//
127+
.setMethodName(request.getMethod())//
128+
.build();
129129
}
130-
131-
return newRealm;
132130
}
133131

134132
private Realm ntlmProxyChallenge(List<String> wwwAuth, Request request, ProxyServer proxyServer, FluentCaseInsensitiveStringsMap headers, Realm realm,
@@ -138,17 +136,10 @@ private Realm ntlmProxyChallenge(List<String> wwwAuth, Request request, ProxySer
138136

139137
addType3NTLMAuthorizationHeader(wwwAuth, headers, proxyServer.getPrincipal(), proxyServer.getPassword(), proxyServer.getNtlmDomain(), proxyServer.getHost());
140138

141-
Realm newRealm;
142-
Realm.RealmBuilder realmBuilder;
143-
if (realm != null) {
144-
realmBuilder = new Realm.RealmBuilder().clone(realm);
145-
} else {
146-
realmBuilder = new Realm.RealmBuilder();
147-
}
148-
newRealm = realmBuilder// .setScheme(realm.getAuthScheme())
149-
.setUri(request.getURI().getPath()).setMethodName(request.getMethod()).build();
150-
151-
return newRealm;
139+
return newRealmBuilder(realm)//
140+
// .setScheme(realm.getAuthScheme())
141+
.setUri(request.getURI().getPath())//
142+
.setMethodName(request.getMethod()).build();
152143
}
153144

154145
private void addType3NTLMAuthorizationHeader(List<String> auth, FluentCaseInsensitiveStringsMap headers, String username, String password, String domain, String workstation)
@@ -163,16 +154,6 @@ private void addType3NTLMAuthorizationHeader(List<String> auth, FluentCaseInsens
163154
}
164155
}
165156

166-
private List<String> getAuthorizationToken(Iterable<Entry<String, String>> list, String headerAuth) {
167-
ArrayList<String> l = new ArrayList<String>();
168-
for (Entry<String, String> e : list) {
169-
if (e.getKey().equalsIgnoreCase(headerAuth)) {
170-
l.add(e.getValue().trim());
171-
}
172-
}
173-
return l;
174-
}
175-
176157
private void finishUpdate(final NettyResponseFuture<?> future, ChannelHandlerContext ctx, boolean lastValidChunk) throws IOException {
177158
if (lastValidChunk && future.isKeepAlive()) {
178159
channels.drainChannel(ctx, future);
@@ -211,43 +192,47 @@ private void markAsDone(NettyResponseFuture<?> future, final ChannelHandlerConte
211192

212193
private boolean handleResponseAndExit(final ChannelHandlerContext ctx, final NettyResponseFuture<?> future, AsyncHandler<?> handler, HttpRequest nettyRequest,
213194
ProxyServer proxyServer, HttpResponse response) throws Exception {
214-
Request request = future.getRequest();
215-
int statusCode = response.getStatus().code();
216-
HttpResponseStatus status = new ResponseStatus(future.getURI(), response, config);
217-
HttpResponseHeaders responseHeaders = new ResponseHeaders(future.getURI(), response.headers());
218-
final FluentCaseInsensitiveStringsMap headers = request.getHeaders();
219-
final RequestBuilder builder = new RequestBuilder(future.getRequest());
220-
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
221195

222196
// store the original headers so we can re-send all them to
223197
// the handler in case of trailing headers
224198
future.setHttpHeaders(response.headers());
225199

226200
future.setKeepAlive(!HttpHeaders.Values.CLOSE.equalsIgnoreCase(response.headers().get(HttpHeaders.Names.CONNECTION)));
227201

202+
HttpResponseStatus status = new ResponseStatus(future.getURI(), response, config);
203+
HttpResponseHeaders responseHeaders = new ResponseHeaders(future.getURI(), response.headers());
204+
228205
if (applyResponseFiltersAndReplayRequest(ctx, future, status, responseHeaders)) {
229206
return true;
230207
}
231208

209+
int statusCode = response.getStatus().code();
210+
Request request = future.getRequest();
211+
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
212+
final FluentCaseInsensitiveStringsMap headers = request.getHeaders();
213+
final RequestBuilder builder = new RequestBuilder(future.getRequest());
214+
232215
// FIXME handle without returns
233216
if (statusCode == UNAUTHORIZED.code() && realm != null) {
234-
List<String> wwwAuth = getAuthorizationToken(response.headers(), HttpHeaders.Names.WWW_AUTHENTICATE);
235-
if (!wwwAuth.isEmpty() && !future.getAndSetAuth(true)) {
217+
218+
List<String> authenticateHeaders = response.headers().getAll(HttpHeaders.Names.WWW_AUTHENTICATE);
219+
220+
if (!authenticateHeaders.isEmpty() && !future.getAndSetAuth(true)) {
236221
future.setState(NettyResponseFuture.STATE.NEW);
237222
Realm newRealm = null;
238223
// NTLM
239-
boolean negociate = wwwAuth.contains("Negotiate");
240-
if (!wwwAuth.contains("Kerberos") && (isNTLM(wwwAuth) || negociate)) {
241-
newRealm = ntlmChallenge(wwwAuth, request, proxyServer, headers, realm, future);
224+
boolean negociate = authenticateHeaders.contains("Negotiate");
225+
if (!authenticateHeaders.contains("Kerberos") && (isNTLM(authenticateHeaders) || negociate)) {
226+
newRealm = ntlmChallenge(authenticateHeaders, request, proxyServer, headers, realm, future);
242227
// SPNEGO KERBEROS
243228
} else if (negociate) {
244-
newRealm = kerberosChallenge(wwwAuth, request, proxyServer, headers, realm, future);
229+
newRealm = kerberosChallenge(authenticateHeaders, request, proxyServer, headers, realm, future);
245230
if (newRealm == null) {
246231
return true;
247232
}
248233
} else {
249234
newRealm = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme()).setUri(request.getURI().getPath()).setMethodName(request.getMethod())
250-
.setUsePreemptiveAuth(true).parseWWWAuthenticateHeader(wwwAuth.get(0)).build();
235+
.setUsePreemptiveAuth(true).parseWWWAuthenticateHeader(authenticateHeaders.get(0)).build();
251236
}
252237

253238
final Realm nr = new Realm.RealmBuilder().clone(newRealm).setUri(URI.create(request.getUrl()).getPath()).build();
@@ -279,19 +264,19 @@ public void call() throws Exception {
279264
return true;
280265

281266
} else if (statusCode == PROXY_AUTHENTICATION_REQUIRED.code()) {
282-
List<String> proxyAuth = getAuthorizationToken(response.headers(), HttpHeaders.Names.PROXY_AUTHENTICATE);
283-
if (realm != null && !proxyAuth.isEmpty() && !future.getAndSetAuth(true)) {
267+
List<String> proxyAuthenticateHeaders = response.headers().getAll(HttpHeaders.Names.PROXY_AUTHENTICATE);
268+
if (realm != null && !proxyAuthenticateHeaders.isEmpty() && !future.getAndSetAuth(true)) {
284269
LOGGER.debug("Sending proxy authentication to {}", request.getUrl());
285270

286271
future.setState(NettyResponseFuture.STATE.NEW);
287272
Realm newRealm = null;
288273

289-
boolean negociate = proxyAuth.contains("Negotiate");
290-
if (!proxyAuth.contains("Kerberos") && (isNTLM(proxyAuth) || negociate)) {
291-
newRealm = ntlmProxyChallenge(proxyAuth, request, proxyServer, headers, realm, future);
274+
boolean negociate = proxyAuthenticateHeaders.contains("Negotiate");
275+
if (!proxyAuthenticateHeaders.contains("Kerberos") && (isNTLM(proxyAuthenticateHeaders) || negociate)) {
276+
newRealm = ntlmProxyChallenge(proxyAuthenticateHeaders, request, proxyServer, headers, realm, future);
292277
// SPNEGO KERBEROS
293278
} else if (negociate) {
294-
newRealm = kerberosChallenge(proxyAuth, request, proxyServer, headers, realm, future);
279+
newRealm = kerberosChallenge(proxyAuthenticateHeaders, request, proxyServer, headers, realm, future);
295280
if (newRealm == null) {
296281
return true;
297282
}

0 commit comments

Comments
 (0)