Author: markt
Date: Wed Aug 19 21:34:01 2015
New Revision: 1696671
URL: http://svn.apache.org/r1696671
Log:
Add another test case for 6.9
Fix a bug where end of stream was never sent for responses with zero content
length.
Modified:
tomcat/trunk/java/org/apache/coyote/http2/Stream.java
tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java
tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_6_9.java
Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1696671&r1=1696670&r2=1696671&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed Aug 19 21:34:01
2015
@@ -259,6 +259,7 @@ public class Stream extends AbstractStre
void sentEndOfStream() {
+ outputBuffer.endOfStreamSent = true;
state.sentEndOfStream();
}
@@ -288,6 +289,7 @@ public class Stream extends AbstractStre
private final ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
private volatile long written = 0;
private volatile boolean closed = false;
+ private volatile boolean endOfStreamSent = false;
/* The write methods are synchronized to ensure that only one thread at
* a time is able to access the buffer. Without this protection, a
@@ -331,6 +333,11 @@ public class Stream extends AbstractStre
coyoteResponse.sendHeaders();
}
if (buffer.position() == 0) {
+ if (closed && !endOfStreamSent) {
+ // Handling this special case here is simpler than trying
+ // to modify the following code to handle it.
+ handler.writeBody(Stream.this, buffer, 0, true);
+ }
// Buffer is empty. Nothing to do.
return;
}
Modified: tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java?rev=1696671&r1=1696670&r2=1696671&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java Wed Aug 19
21:34:01 2015
@@ -114,6 +114,15 @@ public abstract class Http2TestBase exte
}
+ protected void sendEmptyGetRequest(int streamId) throws IOException {
+ byte[] frameHeader = new byte[9];
+ ByteBuffer headersPayload = ByteBuffer.allocate(128);
+
+ buildEmptyGetRequest(frameHeader, headersPayload, null, streamId);
+ writeFrame(frameHeader, headersPayload);
+ }
+
+
protected void sendSimpleGetRequest(int streamId) throws IOException {
sendSimpleGetRequest(streamId, null);
}
@@ -137,6 +146,12 @@ public abstract class Http2TestBase exte
}
+ protected void buildEmptyGetRequest(byte[] frameHeader, ByteBuffer
headersPayload,
+ byte[] padding, int streamId) {
+ buildGetRequest(frameHeader, headersPayload, padding, streamId,
"/empty");
+ }
+
+
protected void buildSimpleGetRequest(byte[] frameHeader, ByteBuffer
headersPayload,
byte[] padding, int streamId) {
buildGetRequest(frameHeader, headersPayload, padding, streamId,
"/simple");
@@ -301,7 +316,17 @@ public abstract class Http2TestBase exte
}
+ protected String getEmptyResponseTrace(int streamId) {
+ return getSingleResponseBodyFrameTrace(streamId, 0);
+ }
+
+
protected String getSimpleResponseTrace(int streamId) {
+ return getSingleResponseBodyFrameTrace(streamId, 8192);
+ }
+
+
+ private String getSingleResponseBodyFrameTrace(int streamId, int bodySize)
{
StringBuilder result = new StringBuilder();
result.append(streamId);
result.append("-HeadersStart\n");
@@ -310,7 +335,9 @@ public abstract class Http2TestBase exte
result.append(streamId);
result.append("-HeadersEnd\n");
result.append(streamId);
- result.append("-Body-8192\n");
+ result.append("-Body-");
+ result.append(bodySize);
+ result.append("\n");
result.append(streamId);
result.append("-EndOfStream\n");
@@ -338,6 +365,8 @@ public abstract class Http2TestBase exte
Tomcat tomcat = getTomcatInstance();
Context ctxt = tomcat.addContext("", null);
+ Tomcat.addServlet(ctxt, "empty", new EmptyServlet());
+ ctxt.addServletMapping("/empty", "empty");
Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
ctxt.addServletMapping("/simple", "simple");
Tomcat.addServlet(ctxt, "large", new LargeServlet());
@@ -805,6 +834,20 @@ public abstract class Http2TestBase exte
}
}
+
+ private static class EmptyServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ // Generate an empty response
+ resp.setContentLength(0);
+ resp.flushBuffer();
+ }
+ }
+
private static class SimpleServlet extends HttpServlet {
Modified: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_6_9.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_6_9.java?rev=1696671&r1=1696670&r2=1696671&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_6_9.java
(original)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_6_9.java Wed Aug
19 21:34:01 2015
@@ -94,5 +94,36 @@ public class TestHttp2Section_6_9 extend
"0-Goaway-[1]-[" + Http2Error.FRAME_SIZE_ERROR.getCode() +
"]-["));
}
+
+ @Test
+ public void testEmptyDataFrameWithNoAvailableFlowControl() throws
Exception {
+ http2Connect();
+
+ // Default connection window size is 64k - 1. Initial request will have
+ // used 8k (56k -1).
+
+ // Use up the remaining connection window. These requests require 56k
+ // but there is only 56k - 1 available.
+ for (int i = 3; i < 17; i += 2) {
+ sendSimpleGetRequest(i);
+ readSimpleGetResponse();
+ }
+ output.clearTrace();
+
+ // It should be possible to send a request that generates an empty
+ // response at this point
+ sendEmptyGetRequest(17);
+ // Headers
+ parser.readFrame(true);
+ // Body
+ parser.readFrame(true);
+
+ // Release Stream 15 which is waiting for a single byte.
+ sendWindowUpdate(0, 1024);
+
+ Assert.assertEquals(getEmptyResponseTrace(17), output.getTrace());
+ }
+
+
// TODO: Remaining 6.9 tests
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]