init
This commit is contained in:
288
test/org/apache/coyote/http2/TestHttp2Section_5_1.java
Normal file
288
test/org/apache/coyote/http2/TestHttp2Section_5_1.java
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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 5.§ 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
|
||||
* requirements in the RFC.
|
||||
*/
|
||||
public class TestHttp2Section_5_1 extends Http2TestBase {
|
||||
|
||||
@Test
|
||||
public void testIdleStateInvalidFrame01() throws Exception {
|
||||
http2Connect();
|
||||
|
||||
sendWindowUpdate(3, 200);
|
||||
|
||||
handleGoAwayResponse(1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIdleStateInvalidFrame02() throws Exception {
|
||||
http2Connect();
|
||||
|
||||
sendData(3, new byte[] {});
|
||||
|
||||
handleGoAwayResponse(1);
|
||||
}
|
||||
|
||||
|
||||
// TODO: reserved local
|
||||
// TODO: reserved remote
|
||||
|
||||
|
||||
@Test
|
||||
public void halfClosedRemoteInvalidFrame() throws Exception {
|
||||
http2Connect();
|
||||
|
||||
// This half-closes the stream since it includes the end of stream flag
|
||||
sendSimpleGetRequest(3);
|
||||
readSimpleGetResponse();
|
||||
Assert.assertEquals(getSimpleResponseTrace(3), output.getTrace());
|
||||
output.clearTrace();
|
||||
|
||||
// This should trigger a connection error
|
||||
sendData(3, new byte[] {});
|
||||
|
||||
handleGoAwayResponse(3, Http2Error.STREAM_CLOSED);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testClosedInvalidFrame01() throws Exception {
|
||||
// HTTP2 upgrade
|
||||
http2Connect();
|
||||
|
||||
// Build the simple request
|
||||
byte[] frameHeader = new byte[9];
|
||||
ByteBuffer headersPayload = ByteBuffer.allocate(128);
|
||||
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);
|
||||
|
||||
// Remove the end of stream and end of headers flags
|
||||
frameHeader[4] = 0;
|
||||
|
||||
// Process the request
|
||||
writeFrame(frameHeader, headersPayload);
|
||||
|
||||
// Send a rst
|
||||
sendRst(3, Http2Error.INTERNAL_ERROR.getCode());
|
||||
|
||||
// Then try sending some data (which should fail)
|
||||
sendData(3, new byte[] {});
|
||||
parser.readFrame(true);
|
||||
|
||||
Assert.assertTrue(output.getTrace(),
|
||||
output.getTrace().startsWith("3-RST-[" + Http2Error.STREAM_CLOSED.getCode() + "]"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testClosedInvalidFrame02() throws Exception {
|
||||
http2Connect();
|
||||
|
||||
// Stream 1 is closed. This should trigger a connection error
|
||||
sendData(1, new byte[] {});
|
||||
|
||||
handleGoAwayResponse(1, Http2Error.STREAM_CLOSED);
|
||||
}
|
||||
|
||||
|
||||
// TODO: Invalid frames for each of the remaining states
|
||||
|
||||
// Section 5.1.1
|
||||
|
||||
@Test
|
||||
public void testClientSendEvenStream() throws Exception {
|
||||
// HTTP2 upgrade
|
||||
http2Connect();
|
||||
|
||||
// Part 1
|
||||
byte[] frameHeader = new byte[9];
|
||||
ByteBuffer headersPayload = ByteBuffer.allocate(128);
|
||||
buildSimpleGetRequestPart1(frameHeader, headersPayload, 4);
|
||||
writeFrame(frameHeader, headersPayload);
|
||||
|
||||
handleGoAwayResponse(1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testClientSendOldStream() throws Exception {
|
||||
http2Connect();
|
||||
sendSimpleGetRequest(5);
|
||||
readSimpleGetResponse();
|
||||
Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace());
|
||||
output.clearTrace();
|
||||
|
||||
|
||||
// Build the simple request on an old stream
|
||||
byte[] frameHeader = new byte[9];
|
||||
ByteBuffer headersPayload = ByteBuffer.allocate(128);
|
||||
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);
|
||||
|
||||
os.write(frameHeader);
|
||||
os.flush();
|
||||
|
||||
handleGoAwayResponse(5);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testImplicitClose() throws Exception {
|
||||
http2Connect();
|
||||
|
||||
sendPriority(3, 0, 16);
|
||||
sendPriority(5, 0, 16);
|
||||
|
||||
sendSimpleGetRequest(5);
|
||||
readSimpleGetResponse();
|
||||
Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace());
|
||||
output.clearTrace();
|
||||
|
||||
// Should trigger an error since stream 3 should have been implicitly
|
||||
// closed.
|
||||
sendSimpleGetRequest(3);
|
||||
|
||||
handleGoAwayResponse(5);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExceedMaxActiveStreams() throws Exception {
|
||||
// http2Connect() - modified
|
||||
enableHttp2(1);
|
||||
configureAndStartWebApplication();
|
||||
openClientConnection();
|
||||
doHttpUpgrade();
|
||||
sendClientPreface();
|
||||
|
||||
// validateHttp2InitialResponse() - modified
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
|
||||
Assert.assertEquals("0-Settings-[3]-[1]\n" +
|
||||
"0-Settings-End\n" +
|
||||
"0-Settings-Ack\n" +
|
||||
"0-Ping-[0,0,0,0,0,0,0,1]\n" +
|
||||
getSimpleResponseTrace(1)
|
||||
, output.getTrace());
|
||||
output.clearTrace();
|
||||
|
||||
sendLargeGetRequest(3);
|
||||
|
||||
sendSimpleGetRequest(5);
|
||||
|
||||
// Default connection window size is 64k-1.
|
||||
// Initial request will have used 8k leaving 56k-1.
|
||||
// Stream window will be 64k-1.
|
||||
// Expecting
|
||||
// 1 * headers
|
||||
// 56k-1 of body (7 * ~8k)
|
||||
// 1 * error (could be in any order)
|
||||
for (int i = 0; i < 8; i++) {
|
||||
parser.readFrame(true);
|
||||
}
|
||||
parser.readFrame(true);
|
||||
|
||||
Assert.assertTrue(output.getTrace(),
|
||||
output.getTrace().contains("5-RST-[" +
|
||||
Http2Error.REFUSED_STREAM.getCode() + "]"));
|
||||
output.clearTrace();
|
||||
|
||||
// Connection window is zero.
|
||||
// Stream window is 8k
|
||||
|
||||
// Release the remaining body
|
||||
sendWindowUpdate(0, (1 << 31) - 2);
|
||||
// Allow for the 8k still in the stream window
|
||||
sendWindowUpdate(3, (1 << 31) - 8193);
|
||||
|
||||
// 192k of body (24 * 8k)
|
||||
// 1 * error (could be in any order)
|
||||
for (int i = 0; i < 24; i++) {
|
||||
parser.readFrame(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testErrorOnWaitingStream() throws Exception {
|
||||
// http2Connect() - modified
|
||||
enableHttp2(1);
|
||||
configureAndStartWebApplication();
|
||||
openClientConnection();
|
||||
doHttpUpgrade();
|
||||
sendClientPreface();
|
||||
|
||||
// validateHttp2InitialResponse() - modified
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
parser.readFrame(true);
|
||||
|
||||
Assert.assertEquals("0-Settings-[3]-[1]\n" +
|
||||
"0-Settings-End\n" +
|
||||
"0-Settings-Ack\n" +
|
||||
"0-Ping-[0,0,0,0,0,0,0,1]\n" +
|
||||
getSimpleResponseTrace(1)
|
||||
, output.getTrace());
|
||||
output.clearTrace();
|
||||
|
||||
sendLargeGetRequest(3);
|
||||
|
||||
sendSimpleGetRequest(5);
|
||||
|
||||
// Default connection window size is 64k-1.
|
||||
// Initial request will have used 8k leaving 56k-1.
|
||||
// Stream window will be 64k-1.
|
||||
// Expecting
|
||||
// 1 * headers
|
||||
// 56k-1 of body (7 * ~8k)
|
||||
// 1 * error (could be in any order)
|
||||
for (int i = 0; i < 8; i++) {
|
||||
parser.readFrame(true);
|
||||
}
|
||||
parser.readFrame(true);
|
||||
|
||||
Assert.assertTrue(output.getTrace(),
|
||||
output.getTrace().contains("5-RST-[" +
|
||||
Http2Error.REFUSED_STREAM.getCode() + "]"));
|
||||
output.clearTrace();
|
||||
|
||||
// Connection window is zero.
|
||||
// Stream window is 8k
|
||||
|
||||
// Expand the stream window too much to trigger an error
|
||||
// Allow for the 8k still in the stream window
|
||||
sendWindowUpdate(3, (1 << 31) - 1);
|
||||
|
||||
parser.readFrame(true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user