Skip to content

Commit 2535007

Browse files
author
Stephane Landelle
committed
Close channel when chunking with 401 and 407
1 parent b606e09 commit 2535007

File tree

7 files changed

+64
-90
lines changed

7 files changed

+64
-90
lines changed

api/src/test/java/org/asynchttpclient/async/BasicAuthTest.java

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,25 +126,24 @@ private static class RedirectHandler extends AbstractHandler {
126126
public void handle(String s, Request r, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
127127

128128
LOGGER.info("request: " + request.getRequestURI());
129-
if ("/uff".equals(request.getRequestURI())) {
130129

130+
if ("/uff".equals(request.getRequestURI())) {
131131
LOGGER.info("redirect to /bla");
132132
response.setStatus(302);
133+
response.setContentLength(0);
133134
response.setHeader("Location", "/bla");
134-
response.getOutputStream().flush();
135-
response.getOutputStream().close();
136-
137-
return;
138135

139136
} else {
140137
LOGGER.info("got redirected" + request.getRequestURI());
138+
response.setStatus(200);
141139
response.addHeader("X-Auth", request.getHeader("Authorization"));
142140
response.addHeader("X-Content-Length", String.valueOf(request.getContentLength()));
143-
response.setStatus(200);
144-
response.getOutputStream().write("content".getBytes(UTF_8));
145-
response.getOutputStream().flush();
146-
response.getOutputStream().close();
141+
byte[] b = "content".getBytes(UTF_8);
142+
response.setContentLength(b.length);
143+
response.getOutputStream().write(b);
147144
}
145+
response.getOutputStream().flush();
146+
response.getOutputStream().close();
148147
}
149148
}
150149

@@ -154,25 +153,27 @@ public void handle(String s, Request r, HttpServletRequest request, HttpServletR
154153

155154
if (request.getHeader("X-401") != null) {
156155
response.setStatus(401);
157-
response.getOutputStream().flush();
158-
response.getOutputStream().close();
159-
160-
return;
161-
}
162-
response.addHeader("X-Auth", request.getHeader("Authorization"));
163-
response.addHeader("X-Content-Length", String.valueOf(request.getContentLength()));
164-
response.setStatus(200);
156+
response.setContentLength(0);
165157

166-
int size = 10 * 1024;
167-
if (request.getContentLength() > 0) {
168-
size = request.getContentLength();
169-
}
170-
byte[] bytes = new byte[size];
171-
if (bytes.length > 0) {
172-
int read = request.getInputStream().read(bytes);
173-
if (read > 0) {
174-
response.getOutputStream().write(bytes, 0, read);
158+
} else {
159+
response.addHeader("X-Auth", request.getHeader("Authorization"));
160+
response.addHeader("X-Content-Length", String.valueOf(request.getContentLength()));
161+
response.setStatus(200);
162+
163+
int size = 10 * 1024;
164+
if (request.getContentLength() > 0) {
165+
size = request.getContentLength();
166+
}
167+
byte[] bytes = new byte[size];
168+
int contentLength = 0;
169+
if (bytes.length > 0) {
170+
int read = request.getInputStream().read(bytes);
171+
if (read > 0) {
172+
contentLength = read;
173+
response.getOutputStream().write(bytes, 0, read);
174+
}
175175
}
176+
response.setContentLength(contentLength);
176177
}
177178
response.getOutputStream().flush();
178179
response.getOutputStream().close();

api/src/test/java/org/asynchttpclient/async/Relative302Test.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ private class Relative302Handler extends AbstractHandler {
5050
public void handle(String s, Request r, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException {
5151

5252
String param;
53+
httpResponse.setStatus(200);
5354
httpResponse.setContentType(TEXT_HTML_CONTENT_TYPE_WITH_UTF_8_CHARSET);
5455
Enumeration<?> e = httpRequest.getHeaderNames();
5556
while (e.hasMoreElements()) {
@@ -58,12 +59,10 @@ public void handle(String s, Request r, HttpServletRequest httpRequest, HttpServ
5859
if (param.startsWith("X-redirect") && !isSet.getAndSet(true)) {
5960
httpResponse.addHeader("Location", httpRequest.getHeader(param));
6061
httpResponse.setStatus(302);
61-
httpResponse.getOutputStream().flush();
62-
httpResponse.getOutputStream().close();
63-
return;
62+
break;
6463
}
6564
}
66-
httpResponse.setStatus(200);
65+
httpResponse.setContentLength(0);
6766
httpResponse.getOutputStream().flush();
6867
httpResponse.getOutputStream().close();
6968
}

providers/netty3/src/main/java/org/asynchttpclient/providers/netty3/channel/ChannelManager.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,11 @@ public void call() {
451451
}
452452

453453
public void drainChannelAndOffer(final Channel channel, final NettyResponseFuture<?> future) {
454-
Channels.setAttribute(channel, newDrainCallback(future, channel, future.isKeepAlive(), getPartitionId(future)));
454+
drainChannelAndOffer(channel, future, future.isKeepAlive(), getPartitionId(future));
455+
}
456+
457+
public void drainChannelAndOffer(final Channel channel, final NettyResponseFuture<?> future, boolean keepAlive, String poolKey) {
458+
Channels.setAttribute(channel, newDrainCallback(future, channel, keepAlive, poolKey));
455459
}
456460

457461
public void flushPartition(String partitionId) {

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

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@
3535
import org.asynchttpclient.ntlm.NTLMEngine;
3636
import org.asynchttpclient.ntlm.NTLMEngineException;
3737
import org.asynchttpclient.providers.netty.commons.handler.ConnectionStrategy;
38-
import org.asynchttpclient.providers.netty3.Callback;
3938
import org.asynchttpclient.providers.netty3.NettyAsyncHttpProviderConfig;
4039
import org.asynchttpclient.providers.netty3.channel.ChannelManager;
41-
import org.asynchttpclient.providers.netty3.channel.Channels;
4240
import org.asynchttpclient.providers.netty3.future.NettyResponseFuture;
4341
import org.asynchttpclient.providers.netty3.request.NettyRequestSender;
4442
import org.asynchttpclient.providers.netty3.response.NettyResponseBodyPart;
@@ -257,22 +255,13 @@ private boolean exitAfterHandling401(//
257255
final Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(request.getHeaders()).setRealm(newRealm).build();
258256

259257
logger.debug("Sending authentication to {}", request.getUri());
260-
if (future.isKeepAlive()) {
261-
if (HttpHeaders.isTransferEncodingChunked(response)) {
262-
Channels.setAttribute(channel, new Callback(future) {
263-
public void call() throws IOException {
264-
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
265-
}
266-
});
267-
} else {
268-
future.setReuseChannel(true);
269-
requestSender.sendNextRequest(nextRequest, future);
270-
}
258+
if (future.isKeepAlive() && !HttpHeaders.isTransferEncodingChunked(response) && !response.isChunked()) {
259+
future.setReuseChannel(true);
271260
} else {
272261
channelManager.closeChannel(channel);
273-
requestSender.sendNextRequest(nextRequest, future);
274262
}
275263

264+
requestSender.sendNextRequest(nextRequest, future);
276265
return true;
277266
}
278267
}
@@ -336,22 +325,15 @@ private boolean exitAfterHandling407(//
336325

337326
final Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(request.getHeaders()).setRealm(newRealm).build();
338327

339-
logger.debug("Sending authentication to {}", request.getUri());
340-
if (future.isKeepAlive()) {
328+
logger.debug("Sending proxy authentication to {}", request.getUri());
329+
if (future.isKeepAlive() && !HttpHeaders.isTransferEncodingChunked(response) && !response.isChunked()) {
330+
future.setConnectAllowed(true);
341331
future.setReuseChannel(true);
342-
if (HttpHeaders.isTransferEncodingChunked(response)) {
343-
Channels.setAttribute(channel, new Callback(future) {
344-
public void call() throws IOException {
345-
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
346-
}
347-
});
348-
} else {
349-
requestSender.sendNextRequest(nextRequest, future);
350-
}
351332
} else {
352333
channelManager.closeChannel(channel);
353-
requestSender.sendNextRequest(nextRequest, future);
354334
}
335+
336+
requestSender.sendNextRequest(nextRequest, future);
355337
return true;
356338
}
357339
}

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.asynchttpclient.filter.FilterException;
4141
import org.asynchttpclient.filter.IOExceptionFilter;
4242
import org.asynchttpclient.listener.TransferCompletionHandler;
43-
import org.asynchttpclient.providers.netty3.Callback;
4443
import org.asynchttpclient.providers.netty3.NettyAsyncHttpProviderConfig;
4544
import org.asynchttpclient.providers.netty3.channel.ChannelManager;
4645
import org.asynchttpclient.providers.netty3.channel.Channels;
@@ -540,18 +539,4 @@ public void replayRequest(final NettyResponseFuture<?> future, FilterContext fc,
540539
public boolean isClosed() {
541540
return closed.get();
542541
}
543-
544-
public final Callback newExecuteNextRequestCallback(final NettyResponseFuture<?> future, final Request nextRequest) {
545-
546-
return new Callback(future) {
547-
@Override
548-
public void call() throws IOException {
549-
sendNextRequest(nextRequest, future);
550-
}
551-
};
552-
}
553-
554-
public void drainChannelAndExecuteNextRequest(final Channel channel, final NettyResponseFuture<?> future, Request nextRequest) {
555-
Channels.setAttribute(channel, newExecuteNextRequestCallback(future, nextRequest));
556-
}
557542
}

providers/netty4/src/main/java/org/asynchttpclient/providers/netty4/channel/ChannelManager.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.asynchttpclient.providers.netty.commons.channel.pool.ChannelPoolPartitionSelector;
5151
import org.asynchttpclient.providers.netty4.Callback;
5252
import org.asynchttpclient.providers.netty4.NettyAsyncHttpProviderConfig;
53+
import org.asynchttpclient.providers.netty4.channel.Channels;
5354
import org.asynchttpclient.providers.netty4.channel.pool.ChannelPool;
5455
import org.asynchttpclient.providers.netty4.channel.pool.DefaultChannelPool;
5556
import org.asynchttpclient.providers.netty4.channel.pool.NoopChannelPool;
@@ -425,7 +426,11 @@ public void call() {
425426
}
426427

427428
public void drainChannelAndOffer(final Channel channel, final NettyResponseFuture<?> future) {
428-
Channels.setAttribute(channel, newDrainCallback(future, channel, future.isKeepAlive(), getPartitionId(future)));
429+
drainChannelAndOffer(channel, future, future.isKeepAlive(), getPartitionId(future));
430+
}
431+
432+
public void drainChannelAndOffer(final Channel channel, final NettyResponseFuture<?> future, boolean keepAlive, String poolKey) {
433+
Channels.setAttribute(channel, newDrainCallback(future, channel, keepAlive, poolKey));
429434
}
430435

431436
public void flushPartition(String partitionId) {

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@
4242
import org.asynchttpclient.ntlm.NTLMEngine;
4343
import org.asynchttpclient.ntlm.NTLMEngineException;
4444
import org.asynchttpclient.providers.netty.commons.handler.ConnectionStrategy;
45-
import org.asynchttpclient.providers.netty4.Callback;
4645
import org.asynchttpclient.providers.netty4.NettyAsyncHttpProviderConfig;
4746
import org.asynchttpclient.providers.netty4.channel.ChannelManager;
48-
import org.asynchttpclient.providers.netty4.channel.Channels;
4947
import org.asynchttpclient.providers.netty4.future.NettyResponseFuture;
5048
import org.asynchttpclient.providers.netty4.request.NettyRequestSender;
5149
import org.asynchttpclient.providers.netty4.response.NettyResponseBodyPart;
@@ -253,17 +251,9 @@ private boolean exitAfterHandling401(//
253251
final Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(request.getHeaders()).setRealm(newRealm).build();
254252

255253
logger.debug("Sending authentication to {}", request.getUri());
256-
if (future.isKeepAlive()) {
254+
if (future.isKeepAlive() && !HttpHeaders.isTransferEncodingChunked(response)) {
257255
future.setReuseChannel(true);
258-
if (HttpHeaders.isTransferEncodingChunked(response)) {
259-
Channels.setAttribute(channel, new Callback(future) {
260-
public void call() throws IOException {
261-
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
262-
}
263-
});
264-
} else {
265-
requestSender.sendNextRequest(nextRequest, future);
266-
}
256+
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
267257
} else {
268258
channelManager.closeChannel(channel);
269259
requestSender.sendNextRequest(nextRequest, future);
@@ -332,10 +322,18 @@ private boolean exitAfterHandling407(//
332322
.build();
333323
}
334324

335-
future.setReuseChannel(true);
336-
future.setConnectAllowed(true);
337-
Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(requestHeaders).setRealm(newRealm).build();
338-
requestSender.sendNextRequest(nextRequest, future);
325+
final Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(request.getHeaders()).setRealm(newRealm).build();
326+
327+
logger.debug("Sending proxy authentication to {}", request.getUri());
328+
if (future.isKeepAlive() && !HttpHeaders.isTransferEncodingChunked(response)) {
329+
future.setConnectAllowed(true);
330+
future.setReuseChannel(true);
331+
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
332+
} else {
333+
channelManager.closeChannel(channel);
334+
requestSender.sendNextRequest(nextRequest, future);
335+
}
336+
339337
return true;
340338
}
341339
}
@@ -439,7 +437,7 @@ public void handle(final Channel channel, final NettyResponseFuture<?> future, f
439437
try {
440438
if (e instanceof HttpResponse) {
441439
HttpResponse response = (HttpResponse) e;
442-
// we buffer the response until we get the LastHttpContent
440+
// we buffer the response until we get the first HttpContent
443441
future.setPendingResponse(response);
444442
return;
445443

0 commit comments

Comments
 (0)