Skip to content

Commit acaab6f

Browse files
author
Vyom Tewari
committedAug 24, 2023
8306040: HttpResponseInputStream.available() returns 1 on empty stream
Reviewed-by: dfuchs
1 parent 76b9011 commit acaab6f

File tree

2 files changed

+163
-2
lines changed

2 files changed

+163
-2
lines changed
 

‎src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ public int available() throws IOException {
538538
if (available != 0) return available;
539539
Iterator<?> iterator = currentListItr;
540540
if (iterator != null && iterator.hasNext()) return 1;
541-
if (buffers.isEmpty()) return 0;
542-
return 1;
541+
if (!buffers.isEmpty() && buffers.peek() != LAST_LIST ) return 1;
542+
return available;
543543
}
544544

545545
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8306040
27+
* @summary HttpResponseInputStream.available() returns 1 on empty stream
28+
* @library /test/lib /test/jdk/java/net/httpclient/lib
29+
* @run junit/othervm HttpInputStreamAvailableTest
30+
*
31+
*/
32+
import com.sun.net.httpserver.HttpExchange;
33+
import com.sun.net.httpserver.HttpHandler;
34+
import com.sun.net.httpserver.HttpServer;
35+
import jdk.test.lib.net.URIBuilder;
36+
37+
import java.io.IOException;
38+
import java.io.InputStream;
39+
import java.io.OutputStream;
40+
import java.net.InetAddress;
41+
import java.net.InetSocketAddress;
42+
import java.net.URI;
43+
import java.net.http.HttpClient;
44+
import java.net.http.HttpRequest;
45+
import java.net.http.HttpResponse;
46+
47+
import org.junit.jupiter.api.AfterAll;
48+
import org.junit.jupiter.api.BeforeAll;
49+
import org.junit.jupiter.api.Test;
50+
import org.junit.jupiter.api.TestInstance;
51+
import static org.junit.jupiter.api.Assertions.assertEquals;
52+
53+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
54+
public class HttpInputStreamAvailableTest {
55+
56+
private HttpServer server;
57+
private int port;
58+
static final String TEST_MESSAGE = "This is test message";
59+
static final int ZERO = 0;
60+
61+
@BeforeAll
62+
void setup() throws Exception {
63+
InetAddress loopback = InetAddress.getLoopbackAddress();
64+
InetSocketAddress addr = new InetSocketAddress(loopback, 0);
65+
server = HttpServer.create(addr, 0);
66+
port = server.getAddress().getPort();
67+
FirstHandler fHandler = new FirstHandler();
68+
server.createContext("/NonZeroResponse/", fHandler);
69+
SecondHandler sHandler = new SecondHandler();
70+
server.createContext("/ZeroResponse/", sHandler);
71+
server.start();
72+
}
73+
74+
@AfterAll
75+
void teardown() throws Exception {
76+
server.stop(0);
77+
}
78+
79+
@Test
80+
public void test() throws Exception {
81+
HttpClient client = HttpClient
82+
.newBuilder()
83+
.proxy(HttpClient.Builder.NO_PROXY)
84+
.build();
85+
86+
URI uri = URIBuilder.newBuilder()
87+
.scheme("http")
88+
.loopback()
89+
.port(port)
90+
.path("/NonZeroResponse/")
91+
.build();
92+
93+
HttpRequest request = HttpRequest
94+
.newBuilder(uri)
95+
.GET()
96+
.build();
97+
98+
// Send a httpRequest and assert the bytes available
99+
HttpResponse<InputStream> response = client.send(request,
100+
HttpResponse.BodyHandlers.ofInputStream());
101+
try ( InputStream in = response.body()) {
102+
in.readNBytes(2);
103+
// this is not guaranteed, but a failure here would be surprising
104+
assertEquals(TEST_MESSAGE.length() - 2, in.available());
105+
//read the remaining data
106+
in.readAllBytes();
107+
//available should return 0
108+
assertEquals(ZERO, in.available());
109+
}
110+
}
111+
112+
@Test
113+
public void test1() throws Exception {
114+
HttpClient client = HttpClient
115+
.newBuilder()
116+
.proxy(HttpClient.Builder.NO_PROXY)
117+
.build();
118+
119+
URI uri = URIBuilder.newBuilder()
120+
.scheme("http")
121+
.loopback()
122+
.port(port)
123+
.path("/ZeroResponse/")
124+
.build();
125+
126+
HttpRequest request = HttpRequest
127+
.newBuilder(uri)
128+
.GET()
129+
.build();
130+
131+
// Send a httpRequest and assert the bytes available
132+
HttpResponse<InputStream> response = client.send(request,
133+
HttpResponse.BodyHandlers.ofInputStream());
134+
try ( InputStream in = response.body()) {
135+
assertEquals(ZERO, in.available());
136+
in.readAllBytes();
137+
assertEquals(ZERO, in.available());
138+
}
139+
}
140+
141+
static class FirstHandler implements HttpHandler {
142+
143+
@Override
144+
public void handle(HttpExchange exchange) throws IOException {
145+
try ( OutputStream os = exchange.getResponseBody()) {
146+
byte[] workingResponse = TEST_MESSAGE.getBytes();
147+
exchange.sendResponseHeaders(200, workingResponse.length);
148+
os.write(workingResponse);
149+
os.flush();
150+
}
151+
}
152+
}
153+
154+
static class SecondHandler implements HttpHandler {
155+
156+
@Override
157+
public void handle(HttpExchange exchange) throws IOException {
158+
exchange.sendResponseHeaders(204, -1);
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)
Please sign in to comment.