Skip to content

Commit

Permalink
Add support for header padding to the tests.
Browse files Browse the repository at this point in the history
Add a simple test for a header frame with padding.
Fix a bug in the parser when parsing header frames with padding.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1687117 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed Jun 23, 2015
1 parent e6c8968 commit e7f0e5b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 12 deletions.
1 change: 1 addition & 0 deletions java/org/apache/coyote/http2/Http2Parser.java
Expand Up @@ -225,6 +225,7 @@ private void readHeadersFrame(int streamId, int flags, int payloadSize)
}

payloadSize -= optionalLen;
payloadSize -= padLength;
}

boolean endOfHeaders = Flags.isEndOfHeaders(flags);
Expand Down
28 changes: 21 additions & 7 deletions test/org/apache/coyote/http2/Http2TestBase.java
Expand Up @@ -109,10 +109,15 @@ protected void validateHttp2InitialResponse() throws Exception {


protected void sendSimpleGetRequest(int streamId) throws IOException {
sendSimpleGetRequest(streamId, null);
}


protected void sendSimpleGetRequest(int streamId, byte[] padding) throws IOException {
byte[] frameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);

buildSimpleGetRequest(frameHeader, headersPayload, streamId);
buildSimpleGetRequest(frameHeader, headersPayload, padding, streamId);
writeFrame(frameHeader, headersPayload);
}

Expand All @@ -126,31 +131,40 @@ protected void sendLargeGetRequest(int streamId) throws IOException {
}


protected void buildSimpleGetRequest(byte[] frameHeader, ByteBuffer headersPayload, int streamId) {
buildGetRequest(frameHeader, headersPayload, streamId, "/simple");
protected void buildSimpleGetRequest(byte[] frameHeader, ByteBuffer headersPayload,
byte[] padding, int streamId) {
buildGetRequest(frameHeader, headersPayload, padding, streamId, "/simple");
}


protected void buildLargeGetRequest(byte[] frameHeader, ByteBuffer headersPayload, int streamId) {
buildGetRequest(frameHeader, headersPayload, streamId, "/large");
buildGetRequest(frameHeader, headersPayload, null, streamId, "/large");
}


protected void buildGetRequest(byte[] frameHeader, ByteBuffer headersPayload, int streamId,
String url) {
protected void buildGetRequest(byte[] frameHeader, ByteBuffer headersPayload, byte[] padding,
int streamId, String url) {
if (padding != null) {
headersPayload.put((byte) (0xFF & padding.length));
}
MimeHeaders headers = new MimeHeaders();
headers.addValue(":method").setString("GET");
headers.addValue(":path").setString(url);
headers.addValue(":authority").setString("localhost:" + getPort());
hpackEncoder.encode(headers, headersPayload);

if (padding != null) {
headersPayload.put(padding);
}
headersPayload.flip();

ByteUtil.setThreeBytes(frameHeader, 0, headersPayload.limit());
// Header frame is type 0x01
frameHeader[3] = 0x01;
// Flags. end of headers (0x04). end of stream (0x01)
frameHeader[4] = 0x05;
if (padding != null) {
frameHeader[4] += 0x08;
}
// Stream id
ByteUtil.set31Bits(frameHeader, 5, streamId);
}
Expand Down
2 changes: 1 addition & 1 deletion test/org/apache/coyote/http2/TestHttp2Section_4_1.java
Expand Up @@ -58,7 +58,7 @@ public void testReservedBitIgnored() throws Exception {
// Build the simple request
byte[] frameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);
buildSimpleGetRequest(frameHeader, headersPayload, 3);
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);

// Tweak the header to set the reserved bit
frameHeader[5] = (byte) (frameHeader[5] | 0x80);
Expand Down
2 changes: 1 addition & 1 deletion test/org/apache/coyote/http2/TestHttp2Section_4_3.java
Expand Up @@ -38,7 +38,7 @@ public void testHeaderDecodingError() throws Exception {
// Build the simple request
byte[] frameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);
buildSimpleGetRequest(frameHeader, headersPayload, 3);
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);

// Try and corrupt the headerPayload
headersPayload.put(0, (byte) (headersPayload.get(0) + 128));
Expand Down
4 changes: 2 additions & 2 deletions test/org/apache/coyote/http2/TestHttp2Section_5_1.java
Expand Up @@ -87,7 +87,7 @@ public void testClosedInvalidFrame01() throws Exception {
// Build the simple request
byte[] frameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);
buildSimpleGetRequest(frameHeader, headersPayload, 3);
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);

// Remove the end of stream and end of headers flags
frameHeader[4] = 0;
Expand Down Expand Up @@ -155,7 +155,7 @@ public void testClientSendOldStream() throws Exception {
// Build the simple request on an old stream
byte[] frameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);
buildSimpleGetRequest(frameHeader, headersPayload, 3);
buildSimpleGetRequest(frameHeader, headersPayload, null, 3);

os.write(frameHeader);
os.flush();
Expand Down
21 changes: 20 additions & 1 deletion test/org/apache/coyote/http2/TestHttp2Section_6_2.java
Expand Up @@ -31,7 +31,7 @@
public class TestHttp2Section_6_2 extends Http2TestBase {

@Test
public void testHeaderOnStreamZero() throws Exception {
public void testHeaderFrameOnStreamZero() throws Exception {
// HTTP2 upgrade
http2Connect();

Expand All @@ -47,4 +47,23 @@ public void testHeaderOnStreamZero() throws Exception {
Assert.assertTrue(output.getTrace(), output.getTrace().startsWith(
"0-Goaway-[1]-[" + Http2Error.PROTOCOL_ERROR.getCode() + "]-["));
}


@Test
public void testHeaderFrameWithPadding() throws Exception {
http2Connect();

byte[] padding= new byte[8];

sendSimpleGetRequest(3, padding);
readSimpleGetResponse();
Assert.assertEquals(getSimpleResponseTrace(3), output.getTrace());
output.clearTrace();
}

// with non-zero padding

// too much padding

// zero length padding
}

0 comments on commit e7f0e5b

Please sign in to comment.