Skip to content

Commit 8164dd7

Browse files
committed
Fix two conditions where HTTPRequestProcessor might not complete the response
This resolves #12 where HEAD requests were not being handled correctly by the HTTPClient. This also resolves a newly found condition where 204 responses that don't contain a content length were also not completing.
1 parent 9d1be81 commit 8164dd7

File tree

5 files changed

+23
-14
lines changed

5 files changed

+23
-14
lines changed

client/src/main/java/org/threadly/litesockets/client/http/HTTPClient.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,17 @@ public void onRead(Client client) {
498498
*/
499499
private class HTTPRequestWrapper implements HTTPResponseCallback {
500500
private final SettableListenableFuture<HTTPResponseData> slf = new SettableListenableFuture<>(false);
501-
private final HTTPResponseProcessor hrp = new HTTPResponseProcessor();
501+
private final HTTPResponseProcessor hrp;
502502
private final ClientHTTPRequest chr;
503503
private HTTPResponse response;
504504
private ReuseableMergedByteBuffers responseMBB = new ReuseableMergedByteBuffers();
505505
private TCPClient client;
506506
private long lastRead = Clock.lastKnownForwardProgressingMillis();
507507

508508
public HTTPRequestWrapper(ClientHTTPRequest chr) {
509+
hrp = new HTTPResponseProcessor(chr.getHTTPRequest()
510+
.getHTTPRequestHeader()
511+
.getRequestType().equals("HEAD"));
509512
hrp.addHTTPResponseCallback(this);
510513
this.chr = chr;
511514
}
@@ -534,7 +537,8 @@ public void bodyData(ByteBuffer bb) {
534537

535538
@Override
536539
public void finished() {
537-
slf.setResult(new HTTPResponseData(HTTPClient.this, chr.getHTTPRequest(), response, responseMBB.duplicateAndClean()));
540+
slf.setResult(new HTTPResponseData(HTTPClient.this, chr.getHTTPRequest(), response,
541+
responseMBB.duplicateAndClean()));
538542
hrp.removeHTTPResponseCallback(this);
539543
inProcess.remove(client);
540544
addBackTCPClient(chr.getHTTPAddress(), client);

client/src/main/java/org/threadly/litesockets/client/http/HTTPStreamClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public HTTPStreamClient(TCPClient client, String host) {
7373
this.host = host;
7474
port = client.getRemoteSocketAddress().getPort();
7575
client.addCloseListener(classCloser);
76-
httpProcessor = new HTTPResponseProcessor();
76+
httpProcessor = new HTTPResponseProcessor(false);
7777
httpProcessor.addHTTPResponseCallback(requestCB);
7878
slfResponse = new SettableListenableFuture<HTTPResponse>();
7979
isConnected = true;
@@ -95,7 +95,7 @@ public HTTPStreamClient(SocketExecuter se, String host, int port) throws IOExcep
9595
client = se.createTCPClient(host, port);
9696
client.setConnectionTimeout(DEFAULT_TIMEOUT);
9797
client.addCloseListener(classCloser);
98-
httpProcessor = new HTTPResponseProcessor();
98+
httpProcessor = new HTTPResponseProcessor(false);
9999
httpProcessor.addHTTPResponseCallback(requestCB);
100100
}
101101

protocol/src/main/java/org/threadly/litesockets/protocols/http/request/HTTPRequestHeader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public HTTPRequestHeader(String requestType, String requestPath, Map<String, Str
110110
*
111111
* @return the request type.
112112
*/
113-
public String getRequestType() {
113+
public String getRequestType() { // TODO - rename to method?
114114
return requestType;
115115
}
116116

protocol/src/main/java/org/threadly/litesockets/protocols/http/response/HTTPResponseProcessor.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ public class HTTPResponseProcessor {
2424

2525
private final ReuseableMergedByteBuffers buffers = new ReuseableMergedByteBuffers();
2626
private final ListenerHelper<HTTPResponseCallback> listeners = new ListenerHelper<>(HTTPResponseCallback.class);
27+
private final boolean headRequest;
2728
private HTTPResponse response;
2829
private int nextChunkSize = -1;
2930
private int currentBodySize = 0;
3031

3132
/**
3233
* Creates a new {@link HTTPResponseProcessor}.
3334
*/
34-
public HTTPResponseProcessor() {}
35+
public HTTPResponseProcessor(boolean headRequest) {
36+
this.headRequest = headRequest;
37+
}
3538

3639
/**
3740
* Adds an {@link HTTPResponseCallback} to this processor that will be called back as
@@ -103,10 +106,11 @@ public void processData(MergedByteBuffers bb) {
103106
}
104107
response = new HTTPResponse(hrh, hh);
105108
listeners.call().headersFinished(response);
106-
if(!response.getHeaders().isChunked() && response.getHeaders().getContentLength() == 0) {
107-
if(response.getResponseCode() != HTTPResponseCode.SwitchingProtocols ) {
108-
reset(null);
109-
}
109+
if(!response.getHeaders().isChunked() &&
110+
response.getResponseCode() != HTTPResponseCode.SwitchingProtocols &&
111+
(headRequest || response.getResponseCode() == HTTPResponseCode.NoContent ||
112+
response.getHeaders().getContentLength() == 0)) {
113+
reset(null);
110114
}
111115
} catch(Exception e) {
112116
reset(e);
@@ -120,10 +124,10 @@ public void processData(MergedByteBuffers bb) {
120124

121125

122126
/**
123-
* Called when an http response connection is closes. Some types of responses are only completed when the connection is closed (http1.0).
127+
* Called when an http response connection is closes. Some types of responses are only completed
128+
* when the connection is closed (http1.0).
124129
*
125130
* This will finish all the callback and then reset the processor to be able to be reused if wanted.
126-
*
127131
*/
128132
public void connectionClosed() {
129133
if(response != null) {
@@ -216,7 +220,8 @@ private void processBody() {
216220
if(currentBodySize >= response.getHeaders().getContentLength()) {
217221
reset(null);
218222
}
219-
} else if (response.getHeaders().getContentLength() == -1 || response.getResponseCode() == HTTPResponseCode.SwitchingProtocols) {
223+
} else if (response.getHeaders().getContentLength() == -1 ||
224+
response.getResponseCode() == HTTPResponseCode.SwitchingProtocols) {
220225
sendDuplicateBBtoListeners(buffers.pullBuffer(buffers.remaining()));
221226
}
222227
}

protocol/src/test/java/org/threadly/litesockets/protocols/http/ResponseTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public void responseCompareTest1() {
5151

5252
@Test
5353
public void responseProcessorTest1() throws InterruptedException, ExecutionException, TimeoutException {
54-
HTTPResponseProcessor hrp = new HTTPResponseProcessor();
54+
HTTPResponseProcessor hrp = new HTTPResponseProcessor(false);
5555
final SettableListenableFuture<HTTPResponse> header = new SettableListenableFuture<>();
5656
final SettableListenableFuture<Boolean> finished = new SettableListenableFuture<>();
5757
hrp.addHTTPResponseCallback(new HTTPResponseCallback() {

0 commit comments

Comments
 (0)