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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to