diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java index 3468b6ced80..7bcb3dfe684 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java @@ -26,6 +26,10 @@ import java.io.PrintWriter; import java.net.Socket; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -46,6 +50,8 @@ import static org.junit.Assert.assertThat; public abstract class AbstractHttpTest { + private final static Set __noBodyCodes = new HashSet<>(Arrays.asList(new String[]{"100","101","102","204","304"})); + @Rule public TestTracker tracker = new TestTracker(); @@ -91,8 +97,10 @@ public abstract class AbstractHttpTest writer.flush(); SimpleHttpResponse response = httpParser.readResponse(reader); - if ("HTTP/1.1".equals(httpVersion) && response.getHeaders().get("content-length") == null && response - .getHeaders().get("transfer-encoding") == null) + if ("HTTP/1.1".equals(httpVersion) + && response.getHeaders().get("content-length") == null + && response.getHeaders().get("transfer-encoding") == null + && !__noBodyCodes.contains(response.getCode())) assertThat("If HTTP/1.1 response doesn't contain transfer-encoding or content-length headers, " + "it should contain connection:close", response.getHeaders().get("connection"), is("close")); return response; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java index 08c7a0349b1..29da973fe13 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java @@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -1502,6 +1503,71 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture } } + @Test + public void testWriteBodyAfterNoBodyResponse() throws Exception + { + configureServer(new WriteBodyAfterNoBodyResponseHandler()); + Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()); + final OutputStream out=client.getOutputStream(); + + out.write("GET / HTTP/1.1\r\nHost: test\r\n\r\n".getBytes()); + out.write("GET / HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n".getBytes()); + out.flush(); + + + BufferedReader in =new BufferedReader(new InputStreamReader(client.getInputStream())); + + String line=in.readLine(); + assertThat(line, containsString(" 304 ")); + while (true) + { + line=in.readLine(); + if (line==null) + throw new EOFException(); + if (line.length()==0) + break; + + assertThat(line, not(containsString("Content-Length"))); + assertThat(line, not(containsString("Content-Type"))); + assertThat(line, not(containsString("Transfer-Encoding"))); + } + + line=in.readLine(); + assertThat(line, containsString(" 304 ")); + while (true) + { + line=in.readLine(); + if (line==null) + throw new EOFException(); + if (line.length()==0) + break; + + assertThat(line, not(containsString("Content-Length"))); + assertThat(line, not(containsString("Content-Type"))); + assertThat(line, not(containsString("Transfer-Encoding"))); + } + + do + { + line=in.readLine(); + } + while (line!=null); + + } + + private class WriteBodyAfterNoBodyResponseHandler extends AbstractHandler + { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + response.setStatus(304); + response.getOutputStream().print("yuck"); + response.flushBuffer(); + } + } + + public class NoopHandler extends AbstractHandler { @Override