diff --git a/okcurl/src/main/java/com/squareup/okhttp/curl/Main.java b/okcurl/src/main/java/com/squareup/okhttp/curl/Main.java
index 4cc8c41da..b3ceb7f0c 100644
--- a/okcurl/src/main/java/com/squareup/okhttp/curl/Main.java
+++ b/okcurl/src/main/java/com/squareup/okhttp/curl/Main.java
@@ -25,7 +25,8 @@ import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.http.StatusLine;
-import com.squareup.okhttp.internal.spdy.Http20Draft12;
+import com.squareup.okhttp.internal.spdy.Http20Draft13;
+
import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.HelpOption;
@@ -265,7 +266,7 @@ public class Main extends HelpOption implements Runnable {
}
private static void enableHttp2FrameLogging() {
- Logger logger = Logger.getLogger(Http20Draft12.class.getName());
+ Logger logger = Logger.getLogger(Http20Draft13.class.getName());
logger.setLevel(Level.FINE);
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft12Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft13Test.java
similarity index 96%
rename from okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft12Test.java
rename to okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft13Test.java
index 5ac3b114b..b78fd1042 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft12Test.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/HttpOverHttp20Draft13Test.java
@@ -24,9 +24,9 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
-public class HttpOverHttp20Draft12Test extends HttpOverSpdyTest {
+public class HttpOverHttp20Draft13Test extends HttpOverSpdyTest {
- public HttpOverHttp20Draft12Test() {
+ public HttpOverHttp20Draft13Test() {
super(Protocol.HTTP_2);
this.hostHeader = ":authority";
}
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft07Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft08Test.java
similarity index 97%
rename from okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft07Test.java
rename to okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft08Test.java
index 6bff540f1..2b74c8df5 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft07Test.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft08Test.java
@@ -30,23 +30,23 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-public class HpackDraft07Test {
+public class HpackDraft08Test {
private final Buffer bytesIn = new Buffer();
- private HpackDraft07.Reader hpackReader;
+ private HpackDraft08.Reader hpackReader;
private Buffer bytesOut = new Buffer();
- private HpackDraft07.Writer hpackWriter;
+ private HpackDraft08.Writer hpackWriter;
@Before public void reset() {
hpackReader = newReader(bytesIn);
- hpackWriter = new HpackDraft07.Writer(bytesOut);
+ hpackWriter = new HpackDraft08.Writer(bytesOut);
}
/**
* Variable-length quantity special cases strings which are longer than 127
* bytes. Values such as cookies can be 4KiB, and should be possible to send.
*
- *
http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-4.1.1
+ *
http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#section-4.1.1
*/
@Test public void largeHeaderValue() throws IOException {
char[] value = new char[4096];
@@ -157,7 +157,7 @@ public class HpackDraft07Test {
// Indexed name (idx = 4) -> :path
bytesIn.writeByte(0x8c); // Literal value Huffman encoded 12 bytes
// decodes to www.example.com which is length 15
- bytesIn.write(decodeHex("e7cf9bebe89b6fb16fa9b6ff"));
+ bytesIn.write(decodeHex("f1e3c2e5f23a6ba0ab90f4ff"));
hpackReader.readHeaders();
hpackReader.emitReferenceSet();
@@ -171,7 +171,7 @@ public class HpackDraft07Test {
}
/**
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.1.1
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.1.1
*/
@Test public void readLiteralHeaderFieldWithIndexing() throws IOException {
bytesIn.writeByte(0x40); // Literal indexed
@@ -195,7 +195,7 @@ public class HpackDraft07Test {
}
/**
- * https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.2.2
+ * https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.2.2
*/
@Test public void literalHeaderFieldWithoutIndexingIndexedName() throws IOException {
List headerBlock = headerEntries(":path", "/sample/path");
@@ -268,7 +268,7 @@ public class HpackDraft07Test {
}
/**
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.1.3
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.1.3
*/
@Test public void readIndexedHeaderField() throws IOException {
bytesIn.writeByte(0x82); // == Indexed - Add ==
@@ -379,7 +379,7 @@ public class HpackDraft07Test {
}
/**
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-3.2.1
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#section-3.2.1
*/
@Test public void toggleIndex() throws IOException {
// Static table entries are copied to the top of the reference set.
@@ -444,7 +444,7 @@ public class HpackDraft07Test {
}
/**
- * https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.2.4
+ * https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.2.4
*/
@Test public void readIndexedHeaderFieldFromStaticTableWithoutBuffering() throws IOException {
bytesIn.writeByte(0x82); // == Indexed - Add ==
@@ -461,7 +461,7 @@ public class HpackDraft07Test {
}
/**
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.2
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.2
*/
@Test public void readRequestExamplesWithoutHuffman() throws IOException {
firstRequestWithoutHuffman();
@@ -648,7 +648,7 @@ public class HpackDraft07Test {
}
/**
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-D.3
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-D.3
*/
@Test public void readRequestExamplesWithHuffman() throws IOException {
firstRequestWithHuffman();
@@ -676,9 +676,9 @@ public class HpackDraft07Test {
// idx = 6 -> :path: /
bytesIn.writeByte(0x44); // == Literal indexed ==
// Indexed name (idx = 4) -> :authority
- bytesIn.writeByte(0x8c); // Literal value Huffman encoded 12 bytes
+ bytesIn.writeByte(0x0f); // Literal value Huffman encoded 12 bytes
// decodes to www.example.com which is length 15
- bytesIn.write(decodeHex("e7cf9bebe89b6fb16fa9b6ff"));
+ bytesIn.write(decodeHex("7777772e6578616d706c652e636f6d"));
}
private void checkReadFirstRequestWithHuffman() {
@@ -720,7 +720,7 @@ public class HpackDraft07Test {
// Indexed name (idx = 28) -> cache-control
bytesIn.writeByte(0x86); // Literal value Huffman encoded 6 bytes
// decodes to no-cache which is length 8
- bytesIn.write(decodeHex("b9b9949556bf"));
+ bytesIn.write(decodeHex("a8eb10649cbf"));
}
private void checkReadSecondRequestWithHuffman() {
@@ -776,10 +776,10 @@ public class HpackDraft07Test {
bytesIn.writeByte(0x40); // Literal indexed
bytesIn.writeByte(0x88); // Literal name Huffman encoded 8 bytes
// decodes to custom-key which is length 10
- bytesIn.write(decodeHex("571c5cdb737b2faf"));
- bytesIn.writeByte(0x89); // Literal value Huffman encoded 6 bytes
+ bytesIn.write(decodeHex("25a849e95ba97d7f"));
+ bytesIn.writeByte(0x89); // Literal value Huffman encoded 9 bytes
// decodes to custom-value which is length 12
- bytesIn.write(decodeHex("571c5cdb73724d9c57"));
+ bytesIn.write(decodeHex("25a849e95bb8e8b4bf"));
}
private void checkReadThirdRequestWithHuffman() {
@@ -906,8 +906,8 @@ public class HpackDraft07Test {
assertEquals(ByteString.EMPTY, newReader(byteStream(0)).readByteString());
}
- private HpackDraft07.Reader newReader(Buffer source) {
- return new HpackDraft07.Reader(4096, source);
+ private HpackDraft08.Reader newReader(Buffer source) {
+ return new HpackDraft08.Reader(4096, source);
}
private Buffer byteStream(int... bytes) {
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12FrameLoggerTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13FrameLoggerTest.java
similarity index 69%
rename from okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12FrameLoggerTest.java
rename to okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13FrameLoggerTest.java
index d0ebd5340..3ab2ca39c 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12FrameLoggerTest.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13FrameLoggerTest.java
@@ -20,22 +20,22 @@ import java.util.Arrays;
import java.util.List;
import org.junit.Test;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_ACK;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_END_HEADERS;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_END_STREAM;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_NONE;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FrameLogger.formatFlags;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FrameLogger.formatHeader;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_CONTINUATION;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_DATA;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_GOAWAY;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_HEADERS;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_PING;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_PUSH_PROMISE;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.TYPE_SETTINGS;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_ACK;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_END_HEADERS;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_END_STREAM;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_NONE;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FrameLogger.formatFlags;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FrameLogger.formatHeader;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_CONTINUATION;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_DATA;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_GOAWAY;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_HEADERS;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_PING;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_PUSH_PROMISE;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.TYPE_SETTINGS;
import static org.junit.Assert.assertEquals;
-public class Http20Draft12FrameLoggerTest {
+public class Http20Draft13FrameLoggerTest {
/** Real stream traffic applied to the log format. */
@Test public void exampleStream() {
@@ -103,14 +103,14 @@ public class Http20Draft12FrameLoggerTest {
"END_STREAM|END_HEADERS",
"END_SEGMENT|END_HEADERS",
"END_STREAM|END_SEGMENT|END_HEADERS",
- "PAD_LOW",
- "END_STREAM|PAD_LOW",
- "END_SEGMENT|PAD_LOW",
- "END_STREAM|END_SEGMENT|PAD_LOW",
+ "PADDED",
+ "END_STREAM|PADDED",
+ "END_SEGMENT|PADDED",
+ "END_STREAM|END_SEGMENT|PADDED",
"00001100",
- "END_STREAM|END_HEADERS|PAD_LOW",
- "END_SEGMENT|END_HEADERS|PAD_LOW",
- "END_STREAM|END_SEGMENT|END_HEADERS|PAD_LOW",
+ "END_STREAM|END_HEADERS|PADDED",
+ "END_SEGMENT|END_HEADERS|PADDED",
+ "END_STREAM|END_SEGMENT|END_HEADERS|PADDED",
"00010000",
"00010001",
"00010010",
@@ -119,14 +119,14 @@ public class Http20Draft12FrameLoggerTest {
"00010101",
"00010110",
"00010111",
- "PAD_LOW|PAD_HIGH",
- "END_STREAM|PAD_LOW|PAD_HIGH",
- "END_SEGMENT|PAD_LOW|PAD_HIGH",
- "END_STREAM|END_SEGMENT|PAD_LOW|PAD_HIGH",
+ "00011000",
+ "00011001",
+ "00011010",
+ "00011011",
"00011100",
- "END_STREAM|END_HEADERS|PAD_LOW|PAD_HIGH",
- "END_SEGMENT|END_HEADERS|PAD_LOW|PAD_HIGH",
- "END_STREAM|END_SEGMENT|END_HEADERS|PAD_LOW|PAD_HIGH",
+ "00011101",
+ "00011110",
+ "00011111",
"PRIORITY",
"END_STREAM|PRIORITY",
"END_SEGMENT|PRIORITY",
@@ -136,13 +136,13 @@ public class Http20Draft12FrameLoggerTest {
"END_SEGMENT|END_HEADERS|PRIORITY",
"END_STREAM|END_SEGMENT|END_HEADERS|PRIORITY",
"00101000",
- "END_STREAM|PRIORITY|PAD_LOW",
- "END_SEGMENT|PRIORITY|PAD_LOW",
- "END_STREAM|END_SEGMENT|PRIORITY|PAD_LOW",
+ "END_STREAM|PRIORITY|PADDED",
+ "END_SEGMENT|PRIORITY|PADDED",
+ "END_STREAM|END_SEGMENT|PRIORITY|PADDED",
"00101100",
- "END_STREAM|END_HEADERS|PRIORITY|PAD_LOW",
- "END_SEGMENT|END_HEADERS|PRIORITY|PAD_LOW",
- "END_STREAM|END_SEGMENT|END_HEADERS|PRIORITY|PAD_LOW",
+ "END_STREAM|END_HEADERS|PRIORITY|PADDED",
+ "END_SEGMENT|END_HEADERS|PRIORITY|PADDED",
+ "END_STREAM|END_SEGMENT|END_HEADERS|PRIORITY|PADDED",
"00110000",
"00110001",
"00110010",
@@ -152,13 +152,13 @@ public class Http20Draft12FrameLoggerTest {
"00110110",
"00110111",
"00111000",
- "END_STREAM|PRIORITY|PAD_LOW|PAD_HIGH",
- "END_SEGMENT|PRIORITY|PAD_LOW|PAD_HIGH",
- "END_STREAM|END_SEGMENT|PRIORITY|PAD_LOW|PAD_HIGH",
+ "00111001",
+ "00111010",
+ "00111011",
"00111100",
- "END_STREAM|END_HEADERS|PRIORITY|PAD_LOW|PAD_HIGH",
- "END_SEGMENT|END_HEADERS|PRIORITY|PAD_LOW|PAD_HIGH",
- "END_STREAM|END_SEGMENT|END_HEADERS|PRIORITY|PAD_LOW|PAD_HIGH"
+ "00111101",
+ "00111110",
+ "00111111"
), formattedFlags);
}
}
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13Test.java
similarity index 55%
rename from okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12Test.java
rename to okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13Test.java
index bf2b43a8a..4f626fa80 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft12Test.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft13Test.java
@@ -15,49 +15,44 @@
*/
package com.squareup.okhttp.internal.spdy;
-import com.squareup.okhttp.Protocol;
-import com.squareup.okhttp.internal.Util;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+
+import com.squareup.okhttp.internal.Util;
+
+import org.junit.Test;
+
import okio.Buffer;
import okio.BufferedSource;
import okio.ByteString;
import okio.GzipSink;
import okio.Okio;
-import org.junit.Test;
-
import static com.squareup.okhttp.internal.Util.headerEntries;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_COMPRESSED;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_END_HEADERS;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_END_STREAM;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_NONE;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_PAD_HIGH;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_PAD_LOW;
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FLAG_PRIORITY;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_COMPRESSED;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_END_HEADERS;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_END_STREAM;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_NONE;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_PADDED;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FLAG_PRIORITY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-public class Http20Draft12Test {
+public class Http20Draft13Test {
final Buffer frame = new Buffer();
- final FrameReader fr = new Http20Draft12.Reader(frame, 4096, false);
+ final FrameReader fr = new Http20Draft13.Reader(frame, 4096, false);
final int expectedStreamId = 15;
- @Test public void unknownFrameTypeProtocolError() throws IOException {
+ @Test public void unknownFrameTypeSkipped() throws IOException {
frame.writeShort(4); // has a 4-byte field
frame.writeByte(99); // type 99
frame.writeByte(0); // no flags
frame.writeInt(expectedStreamId);
frame.writeInt(111111111); // custom data
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR: unknown frame type 99", e.getMessage());
- }
+ fr.nextFrame(new BaseTestHandler()); // Should not callback.
}
@Test public void onlyOneLiteralHeadersFrame() throws IOException {
@@ -65,7 +60,7 @@ public class Http20Draft12Test {
Buffer headerBytes = literalHeaders(sentHeaders);
frame.writeShort((int) headerBytes.size());
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
frame.writeByte(FLAG_END_HEADERS | FLAG_END_STREAM);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeAll(headerBytes);
@@ -91,7 +86,7 @@ public class Http20Draft12Test {
Buffer headerBytes = literalHeaders(sentHeaders);
frame.writeShort((int) (headerBytes.size() + 5));
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
frame.writeByte(FLAG_END_HEADERS | FLAG_PRIORITY);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeInt(0); // Independent stream.
@@ -126,15 +121,15 @@ public class Http20Draft12Test {
Buffer headerBlock = literalHeaders(sentHeaders);
// Write the first headers frame.
- frame.writeShort(Http20Draft12.MAX_FRAME_SIZE);
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
+ frame.writeShort(Http20Draft13.MAX_FRAME_SIZE);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
frame.writeByte(0); // no flags
frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.write(headerBlock, Http20Draft12.MAX_FRAME_SIZE);
+ frame.write(headerBlock, Http20Draft13.MAX_FRAME_SIZE);
// Write the continuation frame, specifying no more frames are expected.
frame.writeShort((int) headerBlock.size());
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
+ frame.writeByte(Http20Draft13.TYPE_CONTINUATION);
frame.writeByte(FLAG_END_HEADERS);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeAll(headerBlock);
@@ -168,8 +163,8 @@ public class Http20Draft12Test {
// Write the push promise frame, specifying the associated stream ID.
Buffer headerBytes = literalHeaders(pushPromise);
frame.writeShort((int) (headerBytes.size() + 4));
- frame.writeByte(Http20Draft12.TYPE_PUSH_PROMISE);
- frame.writeByte(Http20Draft12.FLAG_END_PUSH_PROMISE);
+ frame.writeByte(Http20Draft13.TYPE_PUSH_PROMISE);
+ frame.writeByte(Http20Draft13.FLAG_END_PUSH_PROMISE);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeInt(expectedPromisedStreamId & 0x7fffffff);
frame.writeAll(headerBytes);
@@ -195,8 +190,8 @@ public class Http20Draft12Test {
Buffer headerBlock = literalHeaders(pushPromise);
// Write the first headers frame.
- frame.writeShort(Http20Draft12.MAX_FRAME_SIZE);
- frame.writeByte(Http20Draft12.TYPE_PUSH_PROMISE);
+ frame.writeShort(Http20Draft13.MAX_FRAME_SIZE);
+ frame.writeByte(Http20Draft13.TYPE_PUSH_PROMISE);
frame.writeByte(0); // no flags
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeInt(expectedPromisedStreamId & 0x7fffffff);
@@ -204,7 +199,7 @@ public class Http20Draft12Test {
// Write the continuation frame, specifying no more frames are expected.
frame.writeShort((int) headerBlock.size());
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
+ frame.writeByte(Http20Draft13.TYPE_CONTINUATION);
frame.writeByte(FLAG_END_HEADERS);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeAll(headerBlock);
@@ -224,7 +219,7 @@ public class Http20Draft12Test {
@Test public void readRstStreamFrame() throws IOException {
frame.writeShort(4);
- frame.writeByte(Http20Draft12.TYPE_RST_STREAM);
+ frame.writeByte(Http20Draft13.TYPE_RST_STREAM);
frame.writeByte(0); // No flags
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeInt(ErrorCode.COMPRESSION_ERROR.httpCode);
@@ -240,15 +235,13 @@ public class Http20Draft12Test {
@Test public void readSettingsFrame() throws IOException {
final int reducedTableSizeBytes = 16;
- frame.writeShort(15); // 3 settings * 5 bytes (1 for the code and 4 for the value).
- frame.writeByte(Http20Draft12.TYPE_SETTINGS);
+ frame.writeShort(12); // 2 settings * 6 bytes (2 for the code and 4 for the value).
+ frame.writeByte(Http20Draft13.TYPE_SETTINGS);
frame.writeByte(0); // No flags
frame.writeInt(0); // Settings are always on the connection stream 0.
- frame.writeByte(1); // SETTINGS_HEADER_TABLE_SIZE
+ frame.writeShort(1); // SETTINGS_HEADER_TABLE_SIZE
frame.writeInt(reducedTableSizeBytes);
- frame.writeByte(2); // SETTINGS_ENABLE_PUSH
- frame.writeInt(0);
- frame.writeByte(5); // SETTINGS_COMPRESS_DATA
+ frame.writeShort(2); // SETTINGS_ENABLE_PUSH
frame.writeInt(0);
fr.nextFrame(new BaseTestHandler() {
@@ -256,17 +249,16 @@ public class Http20Draft12Test {
assertFalse(clearPrevious); // No clearPrevious in HTTP/2.
assertEquals(reducedTableSizeBytes, settings.getHeaderTableSize());
assertEquals(false, settings.getEnablePush(true));
- assertEquals(false, settings.getCompressData(true));
}
});
}
@Test public void readSettingsFrameInvalidPushValue() throws IOException {
- frame.writeShort(5); // 1 for the code and 4 for the value
- frame.writeByte(Http20Draft12.TYPE_SETTINGS);
+ frame.writeShort(6); // 2 for the code and 4 for the value
+ frame.writeByte(Http20Draft13.TYPE_SETTINGS);
frame.writeByte(0); // No flags
frame.writeInt(0); // Settings are always on the connection stream 0.
- frame.writeByte(2);
+ frame.writeShort(2);
frame.writeInt(2);
try {
@@ -278,11 +270,11 @@ public class Http20Draft12Test {
}
@Test public void readSettingsFrameInvalidSettingId() throws IOException {
- frame.writeShort(5); // 1 for the code and 4 for the value
- frame.writeByte(Http20Draft12.TYPE_SETTINGS);
+ frame.writeShort(6); // 2 for the code and 4 for the value
+ frame.writeByte(Http20Draft13.TYPE_SETTINGS);
frame.writeByte(0); // No flags
frame.writeInt(0); // Settings are always on the connection stream 0.
- frame.writeByte(7); // old number for SETTINGS_INITIAL_WINDOW_SIZE
+ frame.writeShort(7); // old number for SETTINGS_INITIAL_WINDOW_SIZE
frame.writeInt(1);
try {
@@ -294,11 +286,11 @@ public class Http20Draft12Test {
}
@Test public void readSettingsFrameNegativeWindowSize() throws IOException {
- frame.writeShort(5); // 1 for the code and 4 for the value
- frame.writeByte(Http20Draft12.TYPE_SETTINGS);
+ frame.writeShort(6); // 2 for the code and 4 for the value
+ frame.writeByte(Http20Draft13.TYPE_SETTINGS);
frame.writeByte(0); // No flags
frame.writeInt(0); // Settings are always on the connection stream 0.
- frame.writeByte(4); // SETTINGS_INITIAL_WINDOW_SIZE
+ frame.writeShort(4); // SETTINGS_INITIAL_WINDOW_SIZE
frame.writeInt(Integer.MIN_VALUE);
try {
@@ -314,8 +306,8 @@ public class Http20Draft12Test {
final int expectedPayload2 = 8;
frame.writeShort(8); // length
- frame.writeByte(Http20Draft12.TYPE_PING);
- frame.writeByte(Http20Draft12.FLAG_ACK);
+ frame.writeByte(Http20Draft13.TYPE_PING);
+ frame.writeByte(Http20Draft13.FLAG_ACK);
frame.writeInt(0); // connection-level
frame.writeInt(expectedPayload1);
frame.writeInt(expectedPayload2);
@@ -333,11 +325,11 @@ public class Http20Draft12Test {
}
@Test public void maxLengthDataFrame() throws IOException {
- final byte[] expectedData = new byte[Http20Draft12.MAX_FRAME_SIZE];
+ final byte[] expectedData = new byte[Http20Draft13.MAX_FRAME_SIZE];
Arrays.fill(expectedData, (byte) 2);
frame.writeShort(expectedData.length);
- frame.writeByte(Http20Draft12.TYPE_DATA);
+ frame.writeByte(Http20Draft13.TYPE_DATA);
frame.writeByte(0); // no flags
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.write(expectedData);
@@ -350,7 +342,7 @@ public class Http20Draft12Test {
int length) throws IOException {
assertFalse(inFinished);
assertEquals(expectedStreamId, streamId);
- assertEquals(Http20Draft12.MAX_FRAME_SIZE, length);
+ assertEquals(Http20Draft13.MAX_FRAME_SIZE, length);
ByteString data = source.readByteString(length);
for (byte b : data.toByteArray()) {
assertEquals(2, b);
@@ -361,13 +353,13 @@ public class Http20Draft12Test {
/** We do not send SETTINGS_COMPRESS_DATA = 1, nor want to. Let's make sure we error. */
@Test public void compressedDataFrameWhenSettingDisabled() throws IOException {
- byte[] expectedData = new byte[Http20Draft12.MAX_FRAME_SIZE];
+ byte[] expectedData = new byte[Http20Draft13.MAX_FRAME_SIZE];
Arrays.fill(expectedData, (byte) 2);
Buffer zipped = gzip(expectedData);
int zippedSize = (int) zipped.size();
frame.writeShort(zippedSize);
- frame.writeByte(Http20Draft12.TYPE_DATA);
+ frame.writeByte(Http20Draft13.TYPE_DATA);
frame.writeByte(FLAG_COMPRESSED);
frame.writeInt(expectedStreamId & 0x7fffffff);
zipped.readAll(frame);
@@ -386,15 +378,15 @@ public class Http20Draft12Test {
byte[] expectedData = new byte[dataLength];
Arrays.fill(expectedData, (byte) 2);
- int paddingLength = 257;
+ int paddingLength = 254;
byte[] padding = new byte[paddingLength];
Arrays.fill(padding, (byte) 0);
- frame.writeShort(dataLength + paddingLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_DATA);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
+ frame.writeShort(dataLength + paddingLength + 1);
+ frame.writeByte(Http20Draft13.TYPE_DATA);
+ frame.writeByte(FLAG_PADDED);
frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
+ frame.writeByte(paddingLength);
frame.write(expectedData);
frame.write(padding);
@@ -402,29 +394,14 @@ public class Http20Draft12Test {
assertTrue(frame.exhausted()); // Padding was skipped.
}
- @Test public void readPaddedDataFrameZeroPaddingHigh() throws IOException {
- int dataLength = 1123;
- byte[] expectedData = new byte[dataLength];
- Arrays.fill(expectedData, (byte) 2);
-
- frame.writeShort(dataLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_DATA);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0);
- frame.write(expectedData);
-
- fr.nextFrame(assertData());
- }
-
- @Test public void readPaddedDataFrameZeroPaddingLow() throws IOException {
+ @Test public void readPaddedDataFrameZeroPadding() throws IOException {
int dataLength = 1123;
byte[] expectedData = new byte[dataLength];
Arrays.fill(expectedData, (byte) 2);
frame.writeShort(dataLength + 1);
- frame.writeByte(Http20Draft12.TYPE_DATA);
- frame.writeByte(FLAG_PAD_LOW);
+ frame.writeByte(Http20Draft13.TYPE_DATA);
+ frame.writeByte(FLAG_PADDED);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeByte(0);
frame.write(expectedData);
@@ -432,69 +409,17 @@ public class Http20Draft12Test {
fr.nextFrame(assertData());
}
- @Test public void readPaddedDataFrameMissingLowFlag() throws IOException {
- int dataLength = 1123;
- byte[] expectedData = new byte[dataLength];
- Arrays.fill(expectedData, (byte) 2);
-
- int paddingLength = 257;
- byte[] padding = new byte[paddingLength];
- Arrays.fill(padding, (byte) 0);
-
- frame.writeShort(dataLength + paddingLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_DATA);
- frame.writeByte(FLAG_PAD_HIGH);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
- frame.write(expectedData);
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR FLAG_PAD_HIGH set without FLAG_PAD_LOW", e.getMessage());
- }
- }
-
- /**
- * Padding is encoded over 2 bytes, so maximum value is 65535, but maximum frame size is Http20Draft12.MAX_FRAME_SIZE.
- */
- @Test public void readPaddedDataFrameWithTooMuchPadding() throws IOException {
- int dataLength = 1123;
- byte[] expectedData = new byte[dataLength];
- Arrays.fill(expectedData, (byte) 2);
-
- final byte[] padding = new byte[0xffff];
- Arrays.fill(padding, (byte) 0);
-
- frame.writeShort(dataLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0xffff);
- frame.write(expectedData);
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR padding > 16383: 65535", e.getMessage());
- }
- }
-
@Test public void readPaddedHeadersFrame() throws IOException {
- int paddingLength = 257;
+ int paddingLength = 254;
byte[] padding = new byte[paddingLength];
Arrays.fill(padding, (byte) 0);
Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- frame.writeShort((int) headerBlock.size() + paddingLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_HIGH | FLAG_PAD_LOW);
+ frame.writeShort((int) headerBlock.size() + paddingLength + 1);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
+ frame.writeByte(FLAG_END_HEADERS | FLAG_PADDED);
frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
+ frame.writeByte(paddingLength);
frame.writeAll(headerBlock);
frame.write(padding);
@@ -502,23 +427,11 @@ public class Http20Draft12Test {
assertTrue(frame.exhausted()); // Padding was skipped.
}
- @Test public void readPaddedHeadersFrameZeroPaddingHigh() throws IOException {
+ @Test public void readPaddedHeadersFrameZeroPadding() throws IOException {
Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- frame.writeShort((int) headerBlock.size() + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0);
- frame.writeAll(headerBlock);
-
- fr.nextFrame(assertHeaderBlock());
- }
-
- @Test public void readPaddedHeadersFrameZeroPaddingLow() throws IOException {
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- frame.writeShort((int) headerBlock.size() + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_LOW);
+ frame.writeShort((int) headerBlock.size() + 1);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
+ frame.writeByte(FLAG_END_HEADERS | FLAG_PADDED);
frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeByte(0);
frame.writeAll(headerBlock);
@@ -526,55 +439,9 @@ public class Http20Draft12Test {
fr.nextFrame(assertHeaderBlock());
}
- @Test public void readPaddedHeadersFrameMissingLowFlag() throws IOException {
- int paddingLength = 257;
- byte[] padding = new byte[paddingLength];
- Arrays.fill(padding, (byte) 0);
-
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- frame.writeShort((int) headerBlock.size() + 1);
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_PAD_HIGH);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
- frame.writeAll(headerBlock);
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR FLAG_PAD_HIGH set without FLAG_PAD_LOW", e.getMessage());
- }
- }
-
- /**
- * Padding is encoded over 2 bytes, so maximum value is 65535, but maximum frame size is Http20Draft12.MAX_FRAME_SIZE.
- */
- @Test public void readPaddedHeadersFrameWithTooMuchPadding() throws IOException {
- byte[] padding = new byte[0xffff];
- Arrays.fill(padding, (byte) 0);
-
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- frame.writeShort((int) headerBlock.size() + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0xffff);
- frame.writeAll(headerBlock);
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR padding > 16383: 65535", e.getMessage());
- }
- }
-
/** Headers are compressed, then framed. */
@Test public void readPaddedHeadersFrameThenContinuation() throws IOException {
- int paddingLength = 257;
+ int paddingLength = 254;
byte[] padding = new byte[paddingLength];
Arrays.fill(padding, (byte) 0);
@@ -582,130 +449,23 @@ public class Http20Draft12Test {
Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
// Write the first headers frame.
- frame.writeShort((int) (headerBlock.size() / 2) + paddingLength + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
+ frame.writeShort((int) (headerBlock.size() / 2) + paddingLength + 1);
+ frame.writeByte(Http20Draft13.TYPE_HEADERS);
+ frame.writeByte(FLAG_PADDED);
frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
+ frame.writeByte(paddingLength);
frame.write(headerBlock, headerBlock.size() / 2);
frame.write(padding);
// Write the continuation frame, specifying no more frames are expected.
- frame.writeShort((int) headerBlock.size() + paddingLength + 2);
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION); // 2 for PAD_HIGH,LOW.
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_HIGH | FLAG_PAD_LOW);
+ frame.writeShort((int) headerBlock.size());
+ frame.writeByte(Http20Draft13.TYPE_CONTINUATION);
+ frame.writeByte(FLAG_END_HEADERS);
frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
- frame.writeAll(headerBlock);
- frame.write(padding);
-
- fr.nextFrame(assertHeaderBlock());
- assertTrue(frame.exhausted()); // Padding was skipped.
- }
-
- @Test public void readPaddedContinuationFrameZeroPaddingHigh() throws IOException {
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
-
- // Write the first headers frame.
- frame.writeShort((int) (headerBlock.size() / 2));
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(0);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.write(headerBlock, headerBlock.size() / 2);
-
- // Write the continuation frame, specifying no more frames are expected.
- frame.writeShort((int) headerBlock.size() + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0);
frame.writeAll(headerBlock);
fr.nextFrame(assertHeaderBlock());
- }
-
- @Test public void readPaddedContinuationFrameZeroPaddingLow() throws IOException {
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
-
- // Write the first headers frame.
- frame.writeShort((int) (headerBlock.size() / 2));
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(0);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.write(headerBlock, headerBlock.size() / 2);
-
- // Write the continuation frame, specifying no more frames are expected.
- frame.writeShort((int) headerBlock.size() + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
- frame.writeByte(FLAG_END_HEADERS | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeByte(0);
- frame.writeAll(headerBlock);
-
- fr.nextFrame(assertHeaderBlock());
- }
-
- @Test public void readPaddedContinuationFrameMissingLowFlag() throws IOException {
- int paddingLength = 257;
- byte[] padding = new byte[paddingLength];
- Arrays.fill(padding, (byte) 0);
-
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
-
- // Write the first headers frame.
- frame.writeShort((int) (headerBlock.size() / 2));
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(0);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.write(headerBlock, headerBlock.size() / 2);
-
- // Write the continuation frame, specifying no more frames are expected.
- frame.writeShort((int) headerBlock.size() + 1);
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
- frame.writeByte(FLAG_PAD_HIGH);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(paddingLength);
- frame.writeAll(headerBlock);
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR FLAG_PAD_HIGH set without FLAG_PAD_LOW", e.getMessage());
- }
- }
-
- /**
- * Padding is encoded over 2 bytes, so maximum value is 65535, but maximum frame size is Http20Draft12.MAX_FRAME_SIZE.
- */
- @Test public void readPaddedContinuationFrameWithTooMuchPadding() throws IOException {
- byte[] padding = new byte[0xffff];
- Arrays.fill(padding, (byte) 0);
-
- Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux"));
- // Write the first headers frame.
- frame.writeShort((int) (headerBlock.size() / 2));
- frame.writeByte(Http20Draft12.TYPE_HEADERS);
- frame.writeByte(0);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.write(headerBlock, headerBlock.size() / 2);
-
- // Write the continuation frame, specifying no more frames are expected.
- frame.writeShort((int) (headerBlock.size() / 2) + 2); // 2 for PAD_HIGH,LOW.
- frame.writeByte(Http20Draft12.TYPE_CONTINUATION);
- frame.writeByte(FLAG_PAD_HIGH | FLAG_PAD_LOW);
- frame.writeInt(expectedStreamId & 0x7fffffff);
- frame.writeShort(0xffff);
- frame.write(headerBlock, (headerBlock.size() / 2));
- frame.write(padding);
-
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("PROTOCOL_ERROR padding > 16383: 65535", e.getMessage());
- }
+ assertTrue(frame.exhausted());
}
@Test public void tooLargeDataFrame() throws IOException {
@@ -721,7 +481,7 @@ public class Http20Draft12Test {
final long expectedWindowSizeIncrement = 0x7fffffff;
frame.writeShort(4); // length
- frame.writeByte(Http20Draft12.TYPE_WINDOW_UPDATE);
+ frame.writeByte(Http20Draft13.TYPE_WINDOW_UPDATE);
frame.writeByte(0); // No flags.
frame.writeInt(expectedStreamId);
frame.writeInt((int) expectedWindowSizeIncrement);
@@ -758,7 +518,7 @@ public class Http20Draft12Test {
final ErrorCode expectedError = ErrorCode.PROTOCOL_ERROR;
frame.writeShort(8); // Without debug data there's only 2 32-bit fields.
- frame.writeByte(Http20Draft12.TYPE_GOAWAY);
+ frame.writeByte(Http20Draft13.TYPE_GOAWAY);
frame.writeByte(0); // no flags.
frame.writeInt(0); // connection-scope
frame.writeInt(expectedStreamId); // last good stream.
@@ -783,7 +543,7 @@ public class Http20Draft12Test {
// Compose the expected GOAWAY frame without debug data.
frame.writeShort(8 + expectedData.size());
- frame.writeByte(Http20Draft12.TYPE_GOAWAY);
+ frame.writeByte(Http20Draft13.TYPE_GOAWAY);
frame.writeByte(0); // no flags.
frame.writeInt(0); // connection-scope
frame.writeInt(0); // never read any stream!
@@ -804,10 +564,10 @@ public class Http20Draft12Test {
}
@Test public void frameSizeError() throws IOException {
- Http20Draft12.Writer writer = new Http20Draft12.Writer(new Buffer(), true);
+ Http20Draft13.Writer writer = new Http20Draft13.Writer(new Buffer(), true);
try {
- writer.frameHeader(0, 16384, Http20Draft12.TYPE_DATA, FLAG_NONE);
+ writer.frameHeader(0, 16384, Http20Draft13.TYPE_DATA, FLAG_NONE);
fail();
} catch (IllegalArgumentException e) {
assertEquals("FRAME_SIZE_ERROR length > 16383: 16384", e.getMessage());
@@ -815,140 +575,59 @@ public class Http20Draft12Test {
}
@Test public void streamIdHasReservedBit() throws IOException {
- Http20Draft12.Writer writer = new Http20Draft12.Writer(new Buffer(), true);
+ Http20Draft13.Writer writer = new Http20Draft13.Writer(new Buffer(), true);
try {
int streamId = 3;
streamId |= 1L << 31; // set reserved bit
- writer.frameHeader(streamId, Http20Draft12.MAX_FRAME_SIZE, Http20Draft12.TYPE_DATA, FLAG_NONE);
+ writer.frameHeader(streamId, Http20Draft13.MAX_FRAME_SIZE, Http20Draft13.TYPE_DATA, FLAG_NONE);
fail();
} catch (IllegalArgumentException e) {
assertEquals("reserved bit set: -2147483645", e.getMessage());
}
}
- @Test public void blockedFrameIgnored() throws IOException {
- frame.writeShort(0);
- frame.writeByte(Http20Draft12.TYPE_BLOCKED);
- frame.writeByte(0); // no flags.
- frame.writeInt(0); // connection-scope.
-
- fr.nextFrame(new BaseTestHandler()); // Should not callback.
- }
-
- @Test public void blockedFrameIOEWithPayload() throws IOException {
- frame.writeShort(4);
- frame.writeByte(Http20Draft12.TYPE_BLOCKED);
- frame.writeByte(0); // no flags.
- frame.writeInt(0); // connection-scope.
- frame.writeUtf8("abcd"); // Send a payload even though it is illegal.
-
- // Consume the unknown frame.
- try {
- fr.nextFrame(new BaseTestHandler());
- fail();
- } catch (IOException e) {
- assertEquals("TYPE_BLOCKED length != 0: 4", e.getMessage());
- }
- }
-
- @Test public void readAltSvcStreamOrigin() throws IOException {
- frame.writeShort(9 + Protocol.HTTP_2.toString().length() + "www-2.example.com".length());
- frame.writeByte(Http20Draft12.TYPE_ALTSVC);
- frame.writeByte(0); // No flags.
- frame.writeInt(expectedStreamId); // Use stream origin.
- frame.writeInt(0xffffffff); // Max-Age 32bit number.
- frame.writeShort(443); // Port.
- frame.writeByte(0); // Reserved.
- frame.writeByte(Protocol.HTTP_2.toString().length()); // Proto-Len.
- frame.writeUtf8(Protocol.HTTP_2.toString()); // Protocol-ID.
- frame.writeByte("www-2.example.com".length()); // Host-Len.
- frame.writeUtf8("www-2.example.com");
-
- fr.nextFrame(new BaseTestHandler() { // Consume the alt-svc frame.
- @Override public void alternateService(int streamId, String origin, ByteString protocol,
- String host, int port, long maxAge) {
- assertEquals(expectedStreamId, streamId);
- assertEquals("", origin);
- assertEquals(Protocol.HTTP_2.toString(), protocol.utf8());
- assertEquals("www-2.example.com", host);
- assertEquals(443, port);
- assertEquals(0xffffffffL, maxAge);
- }
- });
- }
-
- @Test public void readAltSvcAlternateOrigin() throws IOException {
- frame.writeShort(9
- + Protocol.HTTP_2.toString().length()
- + "www-2.example.com".length()
- + "https://example.com:443".length());
- frame.writeByte(Http20Draft12.TYPE_ALTSVC);
- frame.writeByte(0); // No flags.
- frame.writeInt(0); // Specify origin.
- frame.writeInt(0xffffffff); // Max-Age 32bit number.
- frame.writeShort(443); // Port.
- frame.writeByte(0); // Reserved.
- frame.writeByte(Protocol.HTTP_2.toString().length()); // Proto-Len.
- frame.writeUtf8(Protocol.HTTP_2.toString()); // Protocol-ID.
- frame.writeByte("www-2.example.com".length()); // Host-Len.
- frame.writeUtf8("www-2.example.com");
- frame.writeUtf8("https://example.com:443"); // Remainder is Origin.
-
- fr.nextFrame(new BaseTestHandler() { // Consume the alt-svc frame.
- @Override public void alternateService(int streamId, String origin, ByteString protocol,
- String host, int port, long maxAge) {
- assertEquals(0, streamId);
- assertEquals("https://example.com:443", origin);
- assertEquals(Protocol.HTTP_2.toString(), protocol.utf8());
- assertEquals("www-2.example.com", host);
- assertEquals(443, port);
- assertEquals(0xffffffffL, maxAge);
- }
- });
- }
-
private Buffer literalHeaders(List sentHeaders) throws IOException {
Buffer out = new Buffer();
- new HpackDraft07.Writer(out).writeHeaders(sentHeaders);
+ new HpackDraft08.Writer(out).writeHeaders(sentHeaders);
return out;
}
private Buffer sendHeaderFrames(boolean outFinished, List headers) throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).headers(outFinished, expectedStreamId, headers);
+ new Http20Draft13.Writer(out, true).headers(outFinished, expectedStreamId, headers);
return out;
}
private Buffer sendPushPromiseFrames(int streamId, List headers) throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).pushPromise(expectedStreamId, streamId, headers);
+ new Http20Draft13.Writer(out, true).pushPromise(expectedStreamId, streamId, headers);
return out;
}
private Buffer sendPingFrame(boolean ack, int payload1, int payload2) throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).ping(ack, payload1, payload2);
+ new Http20Draft13.Writer(out, true).ping(ack, payload1, payload2);
return out;
}
private Buffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData)
throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData);
+ new Http20Draft13.Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData);
return out;
}
private Buffer sendDataFrame(Buffer data) throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).dataFrame(expectedStreamId, FLAG_NONE, data,
+ new Http20Draft13.Writer(out, true).dataFrame(expectedStreamId, FLAG_NONE, data,
(int) data.size());
return out;
}
private Buffer windowUpdate(long windowSizeIncrement) throws IOException {
Buffer out = new Buffer();
- new Http20Draft12.Writer(out, true).windowUpdate(expectedStreamId, windowSizeIncrement);
+ new Http20Draft13.Writer(out, true).windowUpdate(expectedStreamId, windowSizeIncrement);
return out;
}
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http2ConnectionTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http2ConnectionTest.java
index e700dd6c6..5f25e486c 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http2ConnectionTest.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http2ConnectionTest.java
@@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public final class Http2ConnectionTest {
- private static final Variant HTTP_2 = new Http20Draft12();
+ private static final Variant HTTP_2 = new Http20Draft13();
private final MockSpdyPeer peer = new MockSpdyPeer();
@After public void tearDown() throws Exception {
@@ -140,7 +140,7 @@ public final class Http2ConnectionTest {
// verify the peer's settings were read and applied.
assertEquals(0, connection.peerSettings.getHeaderTableSize());
- Http20Draft12.Reader frameReader = (Http20Draft12.Reader) connection.readerRunnable.frameReader;
+ Http20Draft13.Reader frameReader = (Http20Draft13.Reader) connection.readerRunnable.frameReader;
assertEquals(0, frameReader.hpackReader.maxHeaderTableByteCount());
// TODO: when supported, check the frameWriter's compression table is unaffected.
}
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java
index 10025758c..7e1823b73 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java
@@ -278,7 +278,7 @@ public final class MockSpdyPeer implements Closeable {
@Override
public void pushPromise(int streamId, int associatedStreamId, List headerBlock) {
- this.type = Http20Draft12.TYPE_PUSH_PROMISE;
+ this.type = Http20Draft13.TYPE_PUSH_PROMISE;
this.streamId = streamId;
this.associatedStreamId = associatedStreamId;
this.headerBlock = headerBlock;
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SettingsTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SettingsTest.java
index 330566316..a33b1d52e 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SettingsTest.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SettingsTest.java
@@ -62,14 +62,9 @@ public final class SettingsTest {
settings.set(MAX_CONCURRENT_STREAMS, 0, 75);
assertEquals(75, settings.getMaxConcurrentStreams(-3));
- // WARNING: clash on flags between spdy/3 and HTTP/2!
assertEquals(-3, settings.getCurrentCwnd(-3));
settings.set(Settings.CURRENT_CWND, 0, 86);
assertEquals(86, settings.getCurrentCwnd(-3));
- settings.clear();
- assertEquals(true, settings.getCompressData(true));
- settings.set(Settings.COMPRESS_DATA, 0, 1);
- assertEquals(true, settings.getCompressData(false));
assertEquals(-3, settings.getDownloadRetransRate(-3));
settings.set(DOWNLOAD_RETRANS_RATE, 0, 97);
diff --git a/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java b/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java
index 469b1f386..d52c68dca 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java
@@ -399,11 +399,11 @@ public final class OkHttpClient implements Cloneable {
*
*
* This is an evolving set. Future releases may drop
- * support for transitional protocols (like h2-12), in favor of their
+ * support for transitional protocols (like h2-13), in favor of their
* successors (h2). The http/1.1 transport will never be dropped.
*
*
If multiple protocols are specified, This version of OkHttp implements HTTP/2 draft 12
+ * href="http://tools.ietf.org/html/draft-ietf-httpbis-http2-13">draft 12
* with HPACK draft
+ * href="http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08">draft
* 6. Future releases of OkHttp may use this identifier for a newer draft
* of these specs.
*/
- HTTP_2("h2-12");
+ HTTP_2("h2-13");
private final String protocol;
@@ -92,7 +92,7 @@ public enum Protocol {
/**
* Returns the string used to identify this protocol for ALPN and NPN, like
- * "http/1.1", "spdy/3.1" or "h2-12".
+ * "http/1.1", "spdy/3.1" or "h2-13".
*/
@Override public String toString() {
return protocol;
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/ErrorCode.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/ErrorCode.java
index 6d9c784b7..db3028222 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/ErrorCode.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/ErrorCode.java
@@ -15,7 +15,7 @@
*/
package com.squareup.okhttp.internal.spdy;
-// http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-7
+// http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-7
public enum ErrorCode {
/** Not an error! For SPDY stream resets, prefer null over NO_ERROR. */
NO_ERROR(0, -1, 0),
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft07.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft08.java
similarity index 98%
rename from okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft07.java
rename to okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft08.java
index 574e14243..2f7840355 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft07.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft08.java
@@ -30,15 +30,15 @@ import okio.Okio;
import okio.Source;
/**
- * Read and write HPACK v07.
+ * Read and write HPACK v08.
*
- * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
*
* This implementation uses an array for the header table with a bitset for
* references. Dynamic entries are added to the array, starting in the last
* position moving forward. When the array fills, it is doubled.
*/
-final class HpackDraft07 {
+final class HpackDraft08 {
private static final int PREFIX_4_BITS = 0x0f;
private static final int PREFIX_6_BITS = 0x3f;
private static final int PREFIX_7_BITS = 0x7f;
@@ -59,7 +59,7 @@ final class HpackDraft07 {
new Header(Header.RESPONSE_STATUS, "404"),
new Header(Header.RESPONSE_STATUS, "500"),
new Header("accept-charset", ""),
- new Header("accept-encoding", ""),
+ new Header("accept-encoding", "gzip, deflate"),
new Header("accept-language", ""),
new Header("accept-ranges", ""),
new Header("accept", ""),
@@ -107,10 +107,10 @@ final class HpackDraft07 {
new Header("www-authenticate", "")
};
- private HpackDraft07() {
+ private HpackDraft08() {
}
- // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-3.2
+ // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#section-3.2
static final class Reader {
private final List emittedHeaders = new ArrayList<>();
@@ -429,7 +429,7 @@ final class HpackDraft07 {
}
/** This does not use "never indexed" semantics for sensitive headers. */
- // https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-4.3.3
+ // https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#section-4.3.3
void writeHeaders(List headerBlock) throws IOException {
// TODO: implement index tracking
for (int i = 0, size = headerBlock.size(); i < size; i++) {
@@ -447,7 +447,7 @@ final class HpackDraft07 {
}
}
- // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#section-4.1.1
+ // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#section-4.1.1
void writeInt(int value, int prefixMask, int bits) throws IOException {
// Write the raw value for a single byte value.
if (value < prefixMask) {
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft12.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft13.java
similarity index 87%
rename from okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft12.java
rename to okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft13.java
index 887a93a7e..4c40a17a6 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft12.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft13.java
@@ -15,28 +15,29 @@
*/
package com.squareup.okhttp.internal.spdy;
-import com.squareup.okhttp.Protocol;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
+
+import com.squareup.okhttp.Protocol;
+
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.Source;
import okio.Timeout;
-
-import static com.squareup.okhttp.internal.spdy.Http20Draft12.FrameLogger.formatHeader;
+import static com.squareup.okhttp.internal.spdy.Http20Draft13.FrameLogger.formatHeader;
import static java.lang.String.format;
import static java.util.logging.Level.FINE;
import static okio.ByteString.EMPTY;
/**
- * Read and write HTTP/2 v12 frames.
- * http://tools.ietf.org/html/draft-ietf-httpbis-http2-12
+ * Read and write HTTP/2 v13 frames.
+ *
http://tools.ietf.org/html/draft-ietf-httpbis-http2-13
*/
-public final class Http20Draft12 implements Variant {
- private static final Logger logger = Logger.getLogger(Http20Draft12.class.getName());
+public final class Http20Draft13 implements Variant {
+ private static final Logger logger = Logger.getLogger(Http20Draft13.class.getName());
@Override public Protocol getProtocol() {
return Protocol.HTTP_2;
@@ -57,8 +58,6 @@ public final class Http20Draft12 implements Variant {
static final byte TYPE_GOAWAY = 0x7;
static final byte TYPE_WINDOW_UPDATE = 0x8;
static final byte TYPE_CONTINUATION = 0x9;
- static final byte TYPE_ALTSVC = 0xa;
- static final byte TYPE_BLOCKED = 0xb;
static final byte FLAG_NONE = 0x0;
static final byte FLAG_ACK = 0x1; // Used for settings and ping.
@@ -66,8 +65,7 @@ public final class Http20Draft12 implements Variant {
static final byte FLAG_END_SEGMENT = 0x2;
static final byte FLAG_END_HEADERS = 0x4; // Used for headers and continuation.
static final byte FLAG_END_PUSH_PROMISE = 0x4;
- static final byte FLAG_PAD_LOW = 0x8; // Used for headers, data, and continuation.
- static final byte FLAG_PAD_HIGH = 0x10; // Used for headers, data, and continuation.
+ static final byte FLAG_PADDED = 0x8; // Used for headers and data.
static final byte FLAG_PRIORITY = 0x20; // Used for headers.
static final byte FLAG_COMPRESSED = 0x20; // Used for data.
@@ -93,13 +91,13 @@ public final class Http20Draft12 implements Variant {
private final boolean client;
// Visible for testing.
- final HpackDraft07.Reader hpackReader;
+ final HpackDraft08.Reader hpackReader;
Reader(BufferedSource source, int headerTableSize, boolean client) {
this.source = source;
this.client = client;
this.continuation = new ContinuationSource(this.source);
- this.hpackReader = new HpackDraft07.Reader(headerTableSize, continuation);
+ this.hpackReader = new HpackDraft08.Reader(headerTableSize, continuation);
}
@Override public void readConnectionPreface() throws IOException {
@@ -166,16 +164,9 @@ public final class Http20Draft12 implements Variant {
readWindowUpdate(handler, length, flags, streamId);
break;
- case TYPE_ALTSVC:
- readAlternateService(handler, length, flags, streamId);
- break;
-
- case TYPE_BLOCKED: // Ignore as this is experimental.
- if (length != 0) throw ioException("TYPE_BLOCKED length != 0: %s", length);
- break;
-
default:
- throw ioException("PROTOCOL_ERROR: unknown frame type %s", type);
+ // Implementations MUST discard frames that have unknown or unsupported types.
+ source.skip(length);
}
return true;
}
@@ -186,7 +177,7 @@ public final class Http20Draft12 implements Variant {
boolean endStream = (flags & FLAG_END_STREAM) != 0;
- short padding = readPadding(source, flags);
+ short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
if ((flags & FLAG_PRIORITY) != 0) {
readPriority(handler, streamId);
@@ -223,7 +214,7 @@ public final class Http20Draft12 implements Variant {
throw ioException("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA");
}
- short padding = readPadding(source, flags);
+ short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
length = lengthWithoutPadding(length, flags, padding);
handler.data(inFinished, streamId, source, length);
@@ -266,10 +257,10 @@ public final class Http20Draft12 implements Variant {
return;
}
- if (length % 5 != 0) throw ioException("TYPE_SETTINGS length %% 5 != 0: %s", length);
+ if (length % 6 != 0) throw ioException("TYPE_SETTINGS length %% 6 != 0: %s", length);
Settings settings = new Settings();
- for (int i = 0; i < length; i += 5) {
- int id = source.readByte();
+ for (int i = 0; i < length; i += 6) {
+ short id = source.readShort();
int value = source.readInt();
switch (id) {
@@ -307,9 +298,10 @@ public final class Http20Draft12 implements Variant {
if (streamId == 0) {
throw ioException("PROTOCOL_ERROR: TYPE_PUSH_PROMISE streamId == 0");
}
- short padding = readPadding(source, flags);
+ short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
int promisedStreamId = source.readInt() & 0x7fffffff;
length -= 4; // account for above read.
+ length = lengthWithoutPadding(length, flags, padding);
List headerBlock = readHeaderBlock(length, padding, flags, streamId);
handler.pushPromise(streamId, promisedStreamId, headerBlock);
}
@@ -350,20 +342,6 @@ public final class Http20Draft12 implements Variant {
handler.windowUpdate(streamId, increment);
}
- private void readAlternateService(Handler handler, short length, byte flags, int streamId)
- throws IOException {
- long maxAge = source.readInt() & 0xffffffffL;
- int port = source.readShort() & 0xffff;
- source.readByte(); // Reserved.
- int protocolLength = source.readByte() & 0xff;
- ByteString protocol = source.readByteString(protocolLength);
- int hostLength = source.readByte() & 0xff;
- String host = source.readUtf8(hostLength);
- int originLength = length - 9 - protocolLength - hostLength;
- String origin = source.readUtf8(originLength);
- handler.alternateService(streamId, origin, protocol, host, port, maxAge);
- }
-
@Override public void close() throws IOException {
source.close();
}
@@ -373,14 +351,14 @@ public final class Http20Draft12 implements Variant {
private final BufferedSink sink;
private final boolean client;
private final Buffer hpackBuffer;
- private final HpackDraft07.Writer hpackWriter;
+ private final HpackDraft08.Writer hpackWriter;
private boolean closed;
Writer(BufferedSink sink, boolean client) {
this.sink = sink;
this.client = client;
this.hpackBuffer = new Buffer();
- this.hpackWriter = new HpackDraft07.Writer(hpackBuffer);
+ this.hpackWriter = new HpackDraft08.Writer(hpackBuffer);
}
@Override public synchronized void flush() throws IOException {
@@ -506,7 +484,7 @@ public final class Http20Draft12 implements Variant {
@Override public synchronized void settings(Settings settings) throws IOException {
if (closed) throw new IOException("closed");
- int length = settings.size() * 5;
+ int length = settings.size() * 6;
byte type = TYPE_SETTINGS;
byte flags = FLAG_NONE;
int streamId = 0;
@@ -516,7 +494,7 @@ public final class Http20Draft12 implements Variant {
int id = i;
if (id == 4) id = 3; // SETTINGS_MAX_CONCURRENT_STREAMS renumbered.
else if (id == 7) id = 4; // SETTINGS_INITIAL_WINDOW_SIZE renumbered.
- sink.writeByte(id);
+ sink.writeShort(id);
sink.writeInt(settings.get(i));
}
sink.flush();
@@ -594,7 +572,7 @@ public final class Http20Draft12 implements Variant {
/**
* Decompression of the header block occurs above the framing layer. This
* class lazily reads continuation frames as they are needed by {@link
- * HpackDraft07.Reader#readHeaders()}.
+ * HpackDraft08.Reader#readHeaders()}.
*/
static final class ContinuationSource implements Source {
private final BufferedSource source;
@@ -636,41 +614,19 @@ public final class Http20Draft12 implements Variant {
int previousStreamId = streamId;
int w1 = source.readInt();
int w2 = source.readInt();
- length = (short) ((w1 & 0x3fff0000) >> 16);
+ length = left = (short) ((w1 & 0x3fff0000) >> 16);
byte type = (byte) ((w1 & 0xff00) >> 8);
flags = (byte) (w1 & 0xff);
if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags));
- padding = readPadding(source, flags);
- length = left = lengthWithoutPadding(length, flags, padding);
streamId = (w2 & 0x7fffffff);
if (type != TYPE_CONTINUATION) throw ioException("%s != TYPE_CONTINUATION", type);
if (streamId != previousStreamId) throw ioException("TYPE_CONTINUATION streamId changed");
}
}
- private static short readPadding(BufferedSource source, byte flags) throws IOException {
- if ((flags & FLAG_PAD_HIGH) != 0 && (flags & FLAG_PAD_LOW) == 0) {
- throw ioException("PROTOCOL_ERROR FLAG_PAD_HIGH set without FLAG_PAD_LOW");
- }
- int padding = 0;
- if ((flags & FLAG_PAD_HIGH) != 0) {
- padding = source.readShort() & 0xffff;
- } else if ((flags & FLAG_PAD_LOW) != 0) {
- padding = source.readByte() & 0xff;
- }
- if (padding > MAX_FRAME_SIZE) {
- throw ioException("PROTOCOL_ERROR padding > %d: %d", MAX_FRAME_SIZE, padding);
- }
- return (short) padding;
- }
-
private static short lengthWithoutPadding(short length, byte flags, short padding)
throws IOException {
- if ((flags & FLAG_PAD_HIGH) != 0) { // account for reading the padding length.
- length -= 2;
- } else if ((flags & FLAG_PAD_LOW) != 0) {
- length--;
- }
+ if ((flags & FLAG_PADDED) != 0) length--; // Account for reading the padding length.
if (padding > length) {
throw ioException("PROTOCOL_ERROR padding %s > remaining length %s", padding, length);
}
@@ -719,8 +675,6 @@ public final class Http20Draft12 implements Variant {
case TYPE_RST_STREAM:
case TYPE_GOAWAY:
case TYPE_WINDOW_UPDATE:
- case TYPE_ALTSVC:
- case TYPE_BLOCKED:
return BINARY[flags];
}
String result = flags < FLAGS.length ? FLAGS[flags] : BINARY[flags];
@@ -744,9 +698,7 @@ public final class Http20Draft12 implements Variant {
"PING",
"GOAWAY",
"WINDOW_UPDATE",
- "CONTINUATION",
- "ALTSVC",
- "BLOCKED"
+ "CONTINUATION"
};
/**
@@ -768,14 +720,9 @@ public final class Http20Draft12 implements Variant {
int[] prefixFlags =
new int[] {FLAG_END_STREAM, FLAG_END_SEGMENT, FLAG_END_SEGMENT | FLAG_END_STREAM};
- FLAGS[FLAG_PAD_LOW] = "PAD_LOW";
- FLAGS[FLAG_PAD_LOW | FLAG_PAD_HIGH] = "PAD_LOW|PAD_HIGH";
- int[] suffixFlags = new int[] {FLAG_PAD_LOW, FLAG_PAD_LOW | FLAG_PAD_HIGH};
-
+ FLAGS[FLAG_PADDED] = "PADDED";
for (int prefixFlag : prefixFlags) {
- for (int suffixFlag : suffixFlags) {
- FLAGS[prefixFlag | suffixFlag] = FLAGS[prefixFlag] + '|' + FLAGS[suffixFlag];
- }
+ FLAGS[prefixFlag | FLAG_PADDED] = FLAGS[prefixFlag] + "|PADDED";
}
FLAGS[FLAG_END_HEADERS] = "END_HEADERS"; // Same as END_PUSH_PROMISE.
@@ -787,10 +734,8 @@ public final class Http20Draft12 implements Variant {
for (int frameFlag : frameFlags) {
for (int prefixFlag : prefixFlags) {
FLAGS[prefixFlag | frameFlag] = FLAGS[prefixFlag] + '|' + FLAGS[frameFlag];
- for (int suffixFlag : suffixFlags) {
- FLAGS[prefixFlag | frameFlag | suffixFlag] =
- FLAGS[prefixFlag] + '|' + FLAGS[frameFlag] + '|' + FLAGS[suffixFlag];
- }
+ FLAGS[prefixFlag | frameFlag | FLAG_PADDED] =
+ FLAGS[prefixFlag] + '|' + FLAGS[frameFlag] + "|PADDED";
}
}
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Huffman.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Huffman.java
index 5fd2d5478..ab1501115 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Huffman.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Huffman.java
@@ -31,49 +31,47 @@ import java.io.OutputStream;
class Huffman {
// Appendix C: Huffman Codes
- // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-C
+ // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08#appendix-C
private static final int[] CODES = {
- 0x3ffffba, 0x3ffffbb, 0x3ffffbc, 0x3ffffbd, 0x3ffffbe, 0x3ffffbf, 0x3ffffc0, 0x3ffffc1,
- 0x3ffffc2, 0x3ffffc3, 0x3ffffc4, 0x3ffffc5, 0x3ffffc6, 0x3ffffc7, 0x3ffffc8, 0x3ffffc9,
- 0x3ffffca, 0x3ffffcb, 0x3ffffcc, 0x3ffffcd, 0x3ffffce, 0x3ffffcf, 0x3ffffd0, 0x3ffffd1,
- 0x3ffffd2, 0x3ffffd3, 0x3ffffd4, 0x3ffffd5, 0x3ffffd6, 0x3ffffd7, 0x3ffffd8, 0x3ffffd9, 0x6,
- 0x1ffc, 0x1f0, 0x3ffc, 0x7ffc, 0x1e, 0x64, 0x1ffd, 0x3fa, 0x1f1, 0x3fb, 0x3fc, 0x65, 0x66,
- 0x1f, 0x7, 0x0, 0x1, 0x2, 0x8, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0xec, 0x1fffc, 0x27,
- 0x7ffd, 0x3fd, 0x7ffe, 0x67, 0xed, 0xee, 0x68, 0xef, 0x69, 0x6a, 0x1f2, 0xf0, 0x1f3, 0x1f4,
- 0x1f5, 0x6b, 0x6c, 0xf1, 0xf2, 0x1f6, 0x1f7, 0x6d, 0x28, 0xf3, 0x1f8, 0x1f9, 0xf4, 0x1fa,
- 0x1fb, 0x7fc, 0x3ffffda, 0x7fd, 0x3ffd, 0x6e, 0x3fffe, 0x9, 0x6f, 0xa, 0x29, 0xb, 0x70, 0x2a,
- 0x2b, 0xc, 0xf5, 0xf6, 0x2c, 0x2d, 0x2e, 0xd, 0x2f, 0x1fc, 0x30, 0x31, 0xe, 0x71, 0x72, 0x73,
- 0x74, 0x75, 0xf7, 0x1fffd, 0xffc, 0x1fffe, 0xffd, 0x3ffffdb, 0x3ffffdc, 0x3ffffdd, 0x3ffffde,
- 0x3ffffdf, 0x3ffffe0, 0x3ffffe1, 0x3ffffe2, 0x3ffffe3, 0x3ffffe4, 0x3ffffe5, 0x3ffffe6,
- 0x3ffffe7, 0x3ffffe8, 0x3ffffe9, 0x3ffffea, 0x3ffffeb, 0x3ffffec, 0x3ffffed, 0x3ffffee,
- 0x3ffffef, 0x3fffff0, 0x3fffff1, 0x3fffff2, 0x3fffff3, 0x3fffff4, 0x3fffff5, 0x3fffff6,
- 0x3fffff7, 0x3fffff8, 0x3fffff9, 0x3fffffa, 0x3fffffb, 0x3fffffc, 0x3fffffd, 0x3fffffe,
- 0x3ffffff, 0x1ffff80, 0x1ffff81, 0x1ffff82, 0x1ffff83, 0x1ffff84, 0x1ffff85, 0x1ffff86,
- 0x1ffff87, 0x1ffff88, 0x1ffff89, 0x1ffff8a, 0x1ffff8b, 0x1ffff8c, 0x1ffff8d, 0x1ffff8e,
- 0x1ffff8f, 0x1ffff90, 0x1ffff91, 0x1ffff92, 0x1ffff93, 0x1ffff94, 0x1ffff95, 0x1ffff96,
- 0x1ffff97, 0x1ffff98, 0x1ffff99, 0x1ffff9a, 0x1ffff9b, 0x1ffff9c, 0x1ffff9d, 0x1ffff9e,
- 0x1ffff9f, 0x1ffffa0, 0x1ffffa1, 0x1ffffa2, 0x1ffffa3, 0x1ffffa4, 0x1ffffa5, 0x1ffffa6,
- 0x1ffffa7, 0x1ffffa8, 0x1ffffa9, 0x1ffffaa, 0x1ffffab, 0x1ffffac, 0x1ffffad, 0x1ffffae,
- 0x1ffffaf, 0x1ffffb0, 0x1ffffb1, 0x1ffffb2, 0x1ffffb3, 0x1ffffb4, 0x1ffffb5, 0x1ffffb6,
- 0x1ffffb7, 0x1ffffb8, 0x1ffffb9, 0x1ffffba, 0x1ffffbb, 0x1ffffbc, 0x1ffffbd, 0x1ffffbe,
- 0x1ffffbf, 0x1ffffc0, 0x1ffffc1, 0x1ffffc2, 0x1ffffc3, 0x1ffffc4, 0x1ffffc5, 0x1ffffc6,
- 0x1ffffc7, 0x1ffffc8, 0x1ffffc9, 0x1ffffca, 0x1ffffcb, 0x1ffffcc, 0x1ffffcd, 0x1ffffce,
- 0x1ffffcf, 0x1ffffd0, 0x1ffffd1, 0x1ffffd2, 0x1ffffd3, 0x1ffffd4, 0x1ffffd5, 0x1ffffd6,
- 0x1ffffd7, 0x1ffffd8, 0x1ffffd9, 0x1ffffda, 0x1ffffdb
+ 0x1ff8, 0x7fffd8, 0xfffffe2, 0xfffffe3, 0xfffffe4, 0xfffffe5, 0xfffffe6, 0xfffffe7, 0xfffffe8,
+ 0xffffea, 0x3ffffffc, 0xfffffe9, 0xfffffea, 0x3ffffffd, 0xfffffeb, 0xfffffec, 0xfffffed,
+ 0xfffffee, 0xfffffef, 0xffffff0, 0xffffff1, 0xffffff2, 0x3ffffffe, 0xffffff3, 0xffffff4,
+ 0xffffff5, 0xffffff6, 0xffffff7, 0xffffff8, 0xffffff9, 0xffffffa, 0xffffffb, 0x14, 0x3f8,
+ 0x3f9, 0xffa, 0x1ff9, 0x15, 0xf8, 0x7fa, 0x3fa, 0x3fb, 0xf9, 0x7fb, 0xfa, 0x16, 0x17, 0x18,
+ 0x0, 0x1, 0x2, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x5c, 0xfb, 0x7ffc, 0x20, 0xffb,
+ 0x3fc, 0x1ffa, 0x21, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xfc, 0x73, 0xfd, 0x1ffb, 0x7fff0,
+ 0x1ffc, 0x3ffc, 0x22, 0x7ffd, 0x3, 0x23, 0x4, 0x24, 0x5, 0x25, 0x26, 0x27, 0x6, 0x74, 0x75,
+ 0x28, 0x29, 0x2a, 0x7, 0x2b, 0x76, 0x2c, 0x8, 0x9, 0x2d, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7ffe,
+ 0x7fc, 0x3ffd, 0x1ffd, 0xffffffc, 0xfffe6, 0x3fffd2, 0xfffe7, 0xfffe8, 0x3fffd3, 0x3fffd4,
+ 0x3fffd5, 0x7fffd9, 0x3fffd6, 0x7fffda, 0x7fffdb, 0x7fffdc, 0x7fffdd, 0x7fffde, 0xffffeb,
+ 0x7fffdf, 0xffffec, 0xffffed, 0x3fffd7, 0x7fffe0, 0xffffee, 0x7fffe1, 0x7fffe2, 0x7fffe3,
+ 0x7fffe4, 0x1fffdc, 0x3fffd8, 0x7fffe5, 0x3fffd9, 0x7fffe6, 0x7fffe7, 0xffffef, 0x3fffda,
+ 0x1fffdd, 0xfffe9, 0x3fffdb, 0x3fffdc, 0x7fffe8, 0x7fffe9, 0x1fffde, 0x7fffea, 0x3fffdd,
+ 0x3fffde, 0xfffff0, 0x1fffdf, 0x3fffdf, 0x7fffeb, 0x7fffec, 0x1fffe0, 0x1fffe1, 0x3fffe0,
+ 0x1fffe2, 0x7fffed, 0x3fffe1, 0x7fffee, 0x7fffef, 0xfffea, 0x3fffe2, 0x3fffe3, 0x3fffe4,
+ 0x7ffff0, 0x3fffe5, 0x3fffe6, 0x7ffff1, 0x3ffffe0, 0x3ffffe1, 0xfffeb, 0x7fff1, 0x3fffe7,
+ 0x7ffff2, 0x3fffe8, 0x1ffffec, 0x3ffffe2, 0x3ffffe3, 0x3ffffe4, 0x7ffffde, 0x7ffffdf,
+ 0x3ffffe5, 0xfffff1, 0x1ffffed, 0x7fff2, 0x1fffe3, 0x3ffffe6, 0x7ffffe0, 0x7ffffe1, 0x3ffffe7,
+ 0x7ffffe2, 0xfffff2, 0x1fffe4, 0x1fffe5, 0x3ffffe8, 0x3ffffe9, 0xffffffd, 0x7ffffe3,
+ 0x7ffffe4, 0x7ffffe5, 0xfffec, 0xfffff3, 0xfffed, 0x1fffe6, 0x3fffe9, 0x1fffe7, 0x1fffe8,
+ 0x7ffff3, 0x3fffea, 0x3fffeb, 0x1ffffee, 0x1ffffef, 0xfffff4, 0xfffff5, 0x3ffffea, 0x7ffff4,
+ 0x3ffffeb, 0x7ffffe6, 0x3ffffec, 0x3ffffed, 0x7ffffe7, 0x7ffffe8, 0x7ffffe9, 0x7ffffea,
+ 0x7ffffeb, 0xffffffe, 0x7ffffec, 0x7ffffed, 0x7ffffee, 0x7ffffef, 0x7fffff0, 0x3ffffee
};
private static final byte[] CODE_LENGTHS = {
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 5, 13, 9, 14, 15, 6, 7, 13, 10, 9, 10, 10, 7, 7, 6, 5, 4,
- 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 8, 17, 6, 15, 10, 15, 7, 8, 8, 7, 8, 7, 7, 9, 8, 9, 9, 9, 7, 7,
- 8, 8, 9, 9, 7, 6, 8, 9, 9, 8, 9, 9, 11, 26, 11, 14, 7, 18, 5, 7, 5, 6, 5, 7, 6, 6, 5, 8, 8, 6,
- 6, 6, 5, 6, 9, 6, 6, 5, 7, 7, 7, 7, 7, 8, 17, 12, 17, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25
+ 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 30,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, 5,
+ 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6,
+ 6, 6, 5, 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, 20, 22, 20, 20, 22, 22, 22, 23,
+ 22, 23, 23, 23, 23, 23, 24, 23, 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23,
+ 24, 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, 21, 21, 22, 21, 23, 22,
+ 23, 23, 20, 22, 22, 22, 23, 22, 22, 23, 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27,
+ 26, 24, 25, 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, 20, 24, 20, 21,
+ 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27,
+ 27, 27, 27, 27, 26
};
private static final Huffman INSTANCE = new Huffman();
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Settings.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Settings.java
index 4a034e6cf..9c914db86 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Settings.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Settings.java
@@ -50,8 +50,6 @@ public final class Settings {
static final int MAX_CONCURRENT_STREAMS = 4;
/** spdy/3: Current CWND in Packets. */
static final int CURRENT_CWND = 5;
- /** HTTP/2: The peer must not gzip a DATA frame when this is 0. */
- static final int COMPRESS_DATA = 5;
/** spdy/3: Retransmission rate. Percentage */
static final int DOWNLOAD_RETRANS_RATE = 6;
/** Window size in bytes. */
@@ -173,13 +171,6 @@ public final class Settings {
return (bit & set) != 0 ? values[CURRENT_CWND] : defaultValue;
}
- /** HTTP/2 only. */
- // TODO: honor this setting in HTTP/2.
- boolean getCompressData(boolean defaultValue) {
- int bit = 1 << COMPRESS_DATA;
- return ((bit & set) != 0 ? values[COMPRESS_DATA] : defaultValue ? 1 : 0) == 1;
- }
-
/** spdy/3 only. */
int getDownloadRetransRate(int defaultValue) {
int bit = 1 << DOWNLOAD_RETRANS_RATE;
diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java
index 8e22f702c..ed342a2e0 100644
--- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java
+++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java
@@ -133,7 +133,7 @@ public final class SpdyConnection implements Closeable {
pushObserver = builder.pushObserver;
client = builder.client;
handler = builder.handler;
- // http://tools.ietf.org/html/draft-ietf-httpbis-http2-12#section-5.1.1
+ // http://tools.ietf.org/html/draft-ietf-httpbis-http2-13#section-5.1.1
nextStreamId = builder.client ? 1 : 2;
if (builder.client && protocol == Protocol.HTTP_2) {
nextStreamId += 2; // In HTTP/2, 1 on client is reserved for Upgrade.
@@ -152,7 +152,7 @@ public final class SpdyConnection implements Closeable {
hostName = builder.hostName;
if (protocol == Protocol.HTTP_2) {
- variant = new Http20Draft12();
+ variant = new Http20Draft13();
// Like newSingleThreadExecutor, except lazy creates the thread.
pushExecutor = new ThreadPoolExecutor(0, 1,
0L, TimeUnit.MILLISECONDS,