Author: markt Date: Wed Sep 30 23:33:55 2015 New Revision: 1706173 URL: http://svn.apache.org/viewvc?rev=1706173&view=rev Log: Add 100-continue support to HTTP/2
Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java (with props) Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java tomcat/trunk/java/org/apache/coyote/http2/Stream.java tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.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/Http2UpgradeHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1706173&r1=1706172&r2=1706173&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed Sep 30 23:33:55 2015 @@ -458,7 +458,8 @@ public class Http2UpgradeHandler extends } - void writeHeaders(Stream stream, Response coyoteResponse) throws IOException { + void writeHeaders(Stream stream, Response coyoteResponse, int payloadSize) + throws IOException { if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.writeHeaders", connectionId, stream.getIdentifier())); @@ -468,10 +469,8 @@ public class Http2UpgradeHandler extends headers.addValue(":status").setString(Integer.toString(coyoteResponse.getStatus())); // This ensures the Stream processing thread has control of the socket. synchronized (socketWrapper) { - // Frame sizes are allowed to be bigger than 4k but for headers that - // should be plenty byte[] header = new byte[9]; - ByteBuffer target = ByteBuffer.allocate(4 * 1024); + ByteBuffer target = ByteBuffer.allocate(payloadSize); boolean first = true; State state = null; while (state != State.COMPLETE) { 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=1706173&r1=1706172&r2=1706173&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed Sep 30 23:33:55 2015 @@ -37,6 +37,12 @@ public class Stream extends AbstractStre private static final Log log = LogFactory.getLog(Stream.class); private static final StringManager sm = StringManager.getManager(Stream.class); + private static final Response ACK_RESPONSE = new Response(); + + static { + ACK_RESPONSE.setStatus(101); + } + private volatile int weight = Constants.DEFAULT_WEIGHT; private final Http2UpgradeHandler handler; @@ -225,6 +231,9 @@ public class Stream extends AbstractStre break; } default: { + if ("expect".equals(name) && "100-continue".equals(value)) { + coyoteRequest.setExpectation(true); + } // Assume other HTTP header coyoteRequest.getMimeHeaders().addValue(name).setString(value); } @@ -233,9 +242,16 @@ public class Stream extends AbstractStre void writeHeaders() throws IOException { - handler.writeHeaders(this, coyoteResponse); + // TODO: Is 1k the optimal value? + handler.writeHeaders(this, coyoteResponse, 1024); } + void writeAck() throws IOException { + // TODO: Is 64 too big? Just the status header with compression + handler.writeHeaders(this, ACK_RESPONSE, 64); + } + + void flushData() throws IOException { if (log.isDebugEnabled()) { Modified: tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java?rev=1706173&r1=1706172&r2=1706173&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java Wed Sep 30 23:33:55 2015 @@ -139,6 +139,16 @@ public class StreamProcessor extends Abs } break; } + case ACK: { + if (!response.isCommitted() && request.hasExpectation()) { + try { + stream.writeAck(); + } catch (IOException ioe) { + // TODO + } + } + break; + } case CLIENT_FLUSH: { action(ActionCode.COMMIT, null); try { @@ -330,7 +340,6 @@ public class StreamProcessor extends Abs sm.getString("streamProcessor.httpupgrade.notsupported")); // Unimplemented / to review - case ACK: case CLOSE_NOW: case DISABLE_SWALLOW_INPUT: case END_REQUEST: 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=1706173&r1=1706172&r2=1706173&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java (original) +++ tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java Wed Sep 30 23:33:55 2015 @@ -232,12 +232,17 @@ public abstract class Http2TestBase exte protected void sendSimplePostRequest(int streamId, byte[] padding, boolean writeBody) throws IOException { + sendSimplePostRequest(streamId, padding, writeBody, false); + } + + protected void sendSimplePostRequest(int streamId, byte[] padding, boolean writeBody, + boolean useExpectation) throws IOException { byte[] headersFrameHeader = new byte[9]; ByteBuffer headersPayload = ByteBuffer.allocate(128); byte[] dataFrameHeader = new byte[9]; ByteBuffer dataPayload = ByteBuffer.allocate(128); - buildPostRequest(headersFrameHeader, headersPayload, + buildPostRequest(headersFrameHeader, headersPayload, useExpectation, dataFrameHeader, dataPayload, padding, streamId); writeFrame(headersFrameHeader, headersPayload); if (writeBody) { @@ -247,11 +252,15 @@ public abstract class Http2TestBase exte protected void buildPostRequest(byte[] headersFrameHeader, ByteBuffer headersPayload, - byte[] dataFrameHeader, ByteBuffer dataPayload, byte[] padding, int streamId) { + boolean useExpectation, byte[] dataFrameHeader, ByteBuffer dataPayload, byte[] padding, + int streamId) { MimeHeaders headers = new MimeHeaders(); headers.addValue(":method").setString("POST"); headers.addValue(":path").setString("/simple"); headers.addValue(":authority").setString("localhost:" + getPort()); + if (useExpectation) { + headers.addValue("expect").setString("100-continue"); + } hpackEncoder.encode(headers, headersPayload); headersPayload.flip(); 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=1706173&r1=1706172&r2=1706173&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 Sep 30 23:33:55 2015 @@ -167,7 +167,7 @@ public class TestHttp2Section_6_9 extend byte[] dataFrameHeader = new byte[9]; ByteBuffer dataPayload = ByteBuffer.allocate(8 * 1024); - buildPostRequest(headersFrameHeader, headersPayload, + buildPostRequest(headersFrameHeader, headersPayload, false, dataFrameHeader, dataPayload, null, 3); // Write the headers Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java?rev=1706173&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java (added) +++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java Wed Sep 30 23:33:55 2015 @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.coyote.http2; + +import java.nio.ByteBuffer; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit tests for Section 8.1 of + * <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a>. + * <br> + * The order of tests in this class is aligned with the order of the + * examples in the RFC. + */ +public class TestHttp2Section_8_1 extends Http2TestBase { + + @Test + public void testPostWithContinuation() throws Exception { + http2Connect(); + + } + + @Test + public void testSendAck() throws Exception { + http2Connect(); + + byte[] headersFrameHeader = new byte[9]; + ByteBuffer headersPayload = ByteBuffer.allocate(128); + byte[] dataFrameHeader = new byte[9]; + ByteBuffer dataPayload = ByteBuffer.allocate(256); + + buildPostRequest(headersFrameHeader, headersPayload, true, + dataFrameHeader, dataPayload, null, 3); + + // Write the headers + writeFrame(headersFrameHeader, headersPayload); + + parser.readFrame(true); + + Assert.assertEquals("3-HeadersStart\n" + + "3-Header-[:status]-[101]\n" + + "3-HeadersEnd\n", + output.getTrace()); + output.clearTrace(); + + // Write the body + writeFrame(dataFrameHeader, dataPayload); + + parser.readFrame(true); + parser.readFrame(true); + parser.readFrame(true); + parser.readFrame(true); + + Assert.assertEquals("0-WindowSize-[256]\n" + + "3-WindowSize-[256]\n" + + "3-HeadersStart\n" + + "3-Header-[:status]-[200]\n" + + "3-HeadersEnd\n" + + "3-Body-256\n" + + "3-EndOfStream\n", + output.getTrace()); + + } +} Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org