diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/FrameReader.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/FrameReader.java index 47ec8cc7e..1371262e6 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/FrameReader.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/FrameReader.java @@ -28,10 +28,22 @@ public interface FrameReader extends Closeable { public interface Handler { void data(boolean inFinished, int streamId, InputStream in, int length) throws IOException; - void synStream(boolean outFinished, boolean inFinished, int streamId, int associatedStreamId, - int priority, int slot, List nameValueBlock); - void synReply(boolean inFinished, int streamId, List nameValueBlock) throws IOException; - void headers(int streamId, List nameValueBlock) throws IOException; + /** + * Create or update incoming headers, creating the corresponding streams + * if necessary. Frames that trigger this are SPDY SYN_STREAM, HEADERS, and + * SYN_REPLY, and HTTP/2.0 HEADERS and PUSH_PROMISE. + * + * @param inFinished true if the sender will not send further frames. + * @param outFinished true if the receiver should not send further frames. + * @param streamId the stream owning these headers. + * @param associatedStreamId the stream that triggered the sender to create + * this stream. + * @param priority or -1 for no priority. For SPDY, priorities range from 0 + * (highest) thru 7 (lowest). For HTTP/2.0, priorities range from 0 + * (highest) thru 2**31-1 (lowest). + */ + void headers(boolean outFinished, boolean inFinished, int streamId, int associatedStreamId, + int priority, List nameValueBlock, HeadersMode headersMode); void rstStream(int streamId, ErrorCode errorCode); void settings(boolean clearPrevious, Settings settings); void noop(); diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HeadersMode.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HeadersMode.java new file mode 100644 index 000000000..e16e176a1 --- /dev/null +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HeadersMode.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Square, Inc. + * + * Licensed 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 com.squareup.okhttp.internal.spdy; + +enum HeadersMode { + SPDY_SYN_STREAM, + SPDY_REPLY, + SPDY_HEADERS, + HTTP_20_HEADERS; + + /** Returns true if it is an error these headers to create a new stream. */ + public boolean failIfStreamAbsent() { + return this == SPDY_REPLY || this == SPDY_HEADERS; + } + + /** Returns true if it is an error these headers to update an existing stream. */ + public boolean failIfStreamPresent() { + return this == SPDY_SYN_STREAM; + } + + /** + * Returns true if it is an error these headers to be the initial headers of a + * response. + */ + public boolean failIfHeadersAbsent() { + return this == SPDY_HEADERS; + } + + /** + * Returns true if it is an error these headers to be update existing headers + * of a response. + */ + public boolean failIfHeadersPresent() { + return this == SPDY_REPLY; + } +} diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft04.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft04.java index 02f4b2361..fedfa9241 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft04.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft04.java @@ -143,7 +143,10 @@ final class Http20Draft04 implements Variant { if ((flags & FLAG_END_HEADERS) != 0) { hpackReader.emitReferenceSet(); List namesAndValues = hpackReader.getAndReset(); - handler.headers(streamId, namesAndValues); + boolean inFinished = (flags & FLAG_END_STREAM) != 0; + int priority = -1; // TODO: priority + handler.headers(false, inFinished, streamId, -1, priority, namesAndValues, + HeadersMode.HTTP_20_HEADERS); return; } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java index 122d371c2..4a1cbb28e 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java @@ -206,8 +206,8 @@ final class Spdy3 implements Variant { boolean inFinished = (flags & FLAG_FIN) != 0; boolean outFinished = (flags & FLAG_UNIDIRECTIONAL) != 0; - handler.synStream(outFinished, inFinished, streamId, associatedStreamId, priority, slot, - nameValueBlock); + handler.headers(outFinished, inFinished, streamId, associatedStreamId, priority, + nameValueBlock, HeadersMode.SPDY_SYN_STREAM); } private void readSynReply(Handler handler, int flags, int length) throws IOException { @@ -215,7 +215,7 @@ final class Spdy3 implements Variant { int streamId = w1 & 0x7fffffff; List nameValueBlock = readNameValueBlock(length - 4); boolean inFinished = (flags & FLAG_FIN) != 0; - handler.synReply(inFinished, streamId, nameValueBlock); + handler.headers(false, inFinished, streamId, -1, -1, nameValueBlock, HeadersMode.SPDY_REPLY); } private void readRstStream(Handler handler, int flags, int length) throws IOException { @@ -233,7 +233,7 @@ final class Spdy3 implements Variant { int w1 = in.readInt(); int streamId = w1 & 0x7fffffff; List nameValueBlock = readNameValueBlock(length - 4); - handler.headers(streamId, nameValueBlock); + handler.headers(false, false, streamId, -1, -1, nameValueBlock, HeadersMode.SPDY_HEADERS); } private void readWindowUpdate(Handler handler, int flags, int length) throws IOException { diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java index 564ca90a6..3e41dc1fe 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java @@ -160,8 +160,8 @@ public final class SpdyConnection implements Closeable { } streamId = nextStreamId; nextStreamId += 2; - stream = new SpdyStream(streamId, this, outFinished, inFinished, priority, slot, - requestHeaders, settings); + stream = new SpdyStream( + streamId, this, outFinished, inFinished, priority, requestHeaders, settings); if (stream.isOpen()) { streams.put(streamId, stream); setIdle(false); @@ -456,55 +456,57 @@ public final class SpdyConnection implements Closeable { } } - @Override public void synStream(boolean outFinished, boolean inFinished, int streamId, - int associatedStreamId, int priority, int slot, List nameValueBlock) { - final SpdyStream synStream; - final SpdyStream previous; + @Override public void headers(boolean outFinished, boolean inFinished, int streamId, + int associatedStreamId, int priority, List nameValueBlock, + HeadersMode headersMode) { + SpdyStream stream; synchronized (SpdyConnection.this) { - synStream = new SpdyStream(streamId, SpdyConnection.this, outFinished, inFinished, priority, - slot, nameValueBlock, settings); - if (shutdown) { + // If we're shutdown, don't bother with this stream. + if (shutdown) return; + + stream = getStream(streamId); + + if (stream == null) { + // The headers claim to be for an existing stream, but we don't have one. + if (headersMode.failIfStreamAbsent()) { + writeSynResetLater(streamId, ErrorCode.INVALID_STREAM); + return; + } + + // If the stream ID is less than the last created ID, assume it's already closed. + if (streamId <= lastGoodStreamId) return; + + // If the stream ID is in the client's namespace, assume it's already closed. + if (streamId % 2 == nextStreamId % 2) return; + + // Create a stream. + final SpdyStream newStream = new SpdyStream(streamId, SpdyConnection.this, outFinished, + inFinished, priority, nameValueBlock, settings); + lastGoodStreamId = streamId; + streams.put(streamId, newStream); + executor.submit(new NamedRunnable("OkHttp Callback %s stream %d", hostName, streamId) { + @Override public void execute() { + try { + handler.receive(newStream); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); return; } - lastGoodStreamId = streamId; - previous = streams.put(streamId, synStream); } - if (previous != null) { - previous.closeLater(ErrorCode.PROTOCOL_ERROR); + + // The headers claim to be for a new stream, but we already have one. + if (headersMode.failIfStreamPresent()) { + stream.closeLater(ErrorCode.PROTOCOL_ERROR); removeStream(streamId); return; } - executor.submit(new NamedRunnable("OkHttp SPDY Callback %s stream %d", hostName, streamId) { - @Override public void execute() { - try { - handler.receive(synStream); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - } - - @Override public void synReply(boolean inFinished, int streamId, List nameValueBlock) - throws IOException { - SpdyStream replyStream = getStream(streamId); - if (replyStream == null) { - writeSynResetLater(streamId, ErrorCode.INVALID_STREAM); - return; - } - replyStream.receiveReply(nameValueBlock); - if (inFinished) { - replyStream.receiveFin(); - } - } - - @Override public void headers(int streamId, List nameValueBlock) - throws IOException { - SpdyStream replyStream = getStream(streamId); - if (replyStream != null) { - replyStream.receiveHeaders(nameValueBlock); - } + // Update an existing stream. + stream.receiveHeaders(nameValueBlock, headersMode); + if (inFinished) stream.receiveFin(); } @Override public void rstStream(int streamId, ErrorCode errorCode) { diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java index 86d314031..e55002203 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java @@ -44,7 +44,6 @@ public final class SpdyStream { private final int id; private final SpdyConnection connection; private final int priority; - private final int slot; private long readTimeoutMillis = 0; private int writeWindowSize; @@ -65,7 +64,7 @@ public final class SpdyStream { private ErrorCode errorCode = null; SpdyStream(int id, SpdyConnection connection, boolean outFinished, boolean inFinished, - int priority, int slot, List requestHeaders, Settings settings) { + int priority, List requestHeaders, Settings settings) { if (connection == null) throw new NullPointerException("connection == null"); if (requestHeaders == null) throw new NullPointerException("requestHeaders == null"); this.id = id; @@ -73,7 +72,6 @@ public final class SpdyStream { this.in.finished = inFinished; this.out.finished = outFinished; this.priority = priority; - this.slot = slot; this.requestHeaders = requestHeaders; setSettings(settings); @@ -240,44 +238,37 @@ public final class SpdyStream { return true; } - void receiveReply(List strings) throws IOException { + void receiveHeaders(List headers, HeadersMode headersMode) { assert (!Thread.holdsLock(SpdyStream.this)); - boolean streamInUseError = false; + ErrorCode errorCode = null; boolean open = true; synchronized (this) { - if (isLocallyInitiated() && responseHeaders == null) { - responseHeaders = strings; - open = isOpen(); - notifyAll(); + if (responseHeaders == null) { + if (headersMode.failIfHeadersAbsent()) { + errorCode = ErrorCode.PROTOCOL_ERROR; + } else { + responseHeaders = headers; + open = isOpen(); + notifyAll(); + } } else { - streamInUseError = true; + if (headersMode.failIfHeadersPresent()) { + errorCode = ErrorCode.STREAM_IN_USE; + } else { + List newHeaders = new ArrayList(); + newHeaders.addAll(responseHeaders); + newHeaders.addAll(headers); + this.responseHeaders = newHeaders; + } } } - if (streamInUseError) { - closeLater(ErrorCode.STREAM_IN_USE); + if (errorCode != null) { + closeLater(errorCode); } else if (!open) { connection.removeStream(id); } } - void receiveHeaders(List headers) { - assert (!Thread.holdsLock(SpdyStream.this)); - boolean protocolError = false; - synchronized (this) { - if (responseHeaders != null) { - List newHeaders = new ArrayList(); - newHeaders.addAll(responseHeaders); - newHeaders.addAll(headers); - this.responseHeaders = newHeaders; - } else { - protocolError = true; - } - } - if (protocolError) { - closeLater(ErrorCode.PROTOCOL_ERROR); - } - } - void receiveData(InputStream in, int length) throws IOException { assert (!Thread.holdsLock(SpdyStream.this)); this.in.receive(in, length); @@ -327,10 +318,6 @@ public final class SpdyStream { return priority; } - int getSlot() { - return slot; - } - /** * An input stream that reads the incoming data frames of a stream. Although * this class uses synchronization to safely receive incoming data frames, diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java index 82459ca5a..dfdd1d09a 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java @@ -174,12 +174,12 @@ public final class MockSpdyPeer implements Closeable { public int streamId; public int associatedStreamId; public int priority; - public int slot; public ErrorCode errorCode; public int deltaWindowSize; public List nameValueBlock; public byte[] data; public Settings settings; + public HeadersMode headersMode; public InFrame(int sequence, FrameReader reader) { this.sequence = sequence; @@ -193,32 +193,18 @@ public final class MockSpdyPeer implements Closeable { this.settings = settings; } - @Override public void synStream(boolean outFinished, boolean inFinished, int streamId, - int associatedStreamId, int priority, int slot, List nameValueBlock) { + @Override public void headers(boolean outFinished, boolean inFinished, int streamId, + int associatedStreamId, int priority, List nameValueBlock, + HeadersMode headersMode) { if (this.type != -1) throw new IllegalStateException(); - this.type = Spdy3.TYPE_SYN_STREAM; + this.type = Spdy3.TYPE_HEADERS; this.outFinished = outFinished; this.inFinished = inFinished; this.streamId = streamId; this.associatedStreamId = associatedStreamId; this.priority = priority; - this.slot = slot; - this.nameValueBlock = nameValueBlock; - } - - @Override public void synReply(boolean inFinished, int streamId, List nameValueBlock) { - if (this.type != -1) throw new IllegalStateException(); - this.type = Spdy3.TYPE_SYN_REPLY; - this.inFinished = inFinished; - this.streamId = streamId; - this.nameValueBlock = nameValueBlock; - } - - @Override public void headers(int streamId, List nameValueBlock) { - if (this.type != -1) throw new IllegalStateException(); - this.type = Spdy3.TYPE_HEADERS; - this.streamId = streamId; this.nameValueBlock = nameValueBlock; + this.headersMode = headersMode; } @Override public void data(boolean inFinished, int streamId, InputStream in, int length) diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java index 45d6ac901..ebc67603d 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java @@ -39,11 +39,10 @@ import static com.squareup.okhttp.internal.spdy.ErrorCode.STREAM_IN_USE; import static com.squareup.okhttp.internal.spdy.Settings.PERSIST_VALUE; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_DATA; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_GOAWAY; +import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_HEADERS; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_NOOP; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_PING; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_RST_STREAM; -import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_SYN_REPLY; -import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_SYN_STREAM; import static com.squareup.okhttp.internal.spdy.Spdy3.TYPE_WINDOW_UPDATE; import static com.squareup.okhttp.internal.spdy.SpdyStream.WINDOW_UPDATE_THRESHOLD; import static org.junit.Assert.assertEquals; @@ -81,7 +80,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertFalse(synStream.inFinished); assertFalse(synStream.outFinished); assertEquals(1, synStream.streamId); @@ -120,7 +120,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); } @@ -139,7 +140,6 @@ public final class SpdyConnectionTest { assertEquals(Arrays.asList("a", "android"), stream.getRequestHeaders()); assertEquals(null, stream.getErrorCode()); assertEquals(5, stream.getPriority()); - assertEquals(129, stream.getSlot()); stream.reply(Arrays.asList("b", "banana"), true); } }; @@ -147,7 +147,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame reply = peer.takeFrame(); - assertEquals(TYPE_SYN_REPLY, reply.type); + assertEquals(TYPE_HEADERS, reply.type); + assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode); assertFalse(reply.inFinished); assertEquals(2, reply.streamId); assertEquals(Arrays.asList("b", "banana"), reply.nameValueBlock); @@ -172,7 +173,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame reply = peer.takeFrame(); - assertEquals(TYPE_SYN_REPLY, reply.type); + assertEquals(TYPE_HEADERS, reply.type); + assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode); assertTrue(reply.inFinished); assertEquals(Arrays.asList("b", "banana"), reply.nameValueBlock); assertEquals(1, receiveCount.get()); @@ -373,7 +375,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertFalse(synStream.inFinished); assertTrue(synStream.outFinished); MockSpdyPeer.InFrame data = peer.takeFrame(); @@ -415,7 +418,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertFalse(synStream.inFinished); assertFalse(synStream.outFinished); MockSpdyPeer.InFrame ping = peer.takeFrame(); @@ -462,7 +466,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertTrue(synStream.inFinished); assertFalse(synStream.outFinished); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); @@ -503,7 +508,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertFalse(synStream.inFinished); assertFalse(synStream.outFinished); MockSpdyPeer.InFrame data = peer.takeFrame(); @@ -536,7 +542,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); assertTrue(synStream.inFinished); assertFalse(synStream.outFinished); } @@ -565,7 +572,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); @@ -596,7 +604,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame reply = peer.takeFrame(); - assertEquals(TYPE_SYN_REPLY, reply.type); + assertEquals(TYPE_HEADERS, reply.type); + assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); assertEquals(TYPE_RST_STREAM, rstStream.type); assertEquals(2, rstStream.streamId); @@ -622,7 +631,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); assertEquals(2, ping.streamId); @@ -645,7 +655,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); assertEquals(TYPE_RST_STREAM, rstStream.type); assertEquals(1, rstStream.streamId); @@ -676,7 +687,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); assertEquals(2, ping.streamId); @@ -716,9 +728,9 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream1 = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream1.type); + assertEquals(TYPE_HEADERS, synStream1.type); MockSpdyPeer.InFrame synStream2 = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream2.type); + assertEquals(TYPE_HEADERS, synStream2.type); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); MockSpdyPeer.InFrame data1 = peer.takeFrame(); @@ -746,7 +758,7 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream1 = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream1.type); + assertEquals(TYPE_HEADERS, synStream1.type); MockSpdyPeer.InFrame pingFrame = peer.takeFrame(); assertEquals(TYPE_PING, pingFrame.type); MockSpdyPeer.InFrame goaway = peer.takeFrame(); @@ -810,7 +822,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame goaway = peer.takeFrame(); assertEquals(TYPE_GOAWAY, goaway.type); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); @@ -857,7 +870,7 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); } @Test public void headers() throws Exception { @@ -877,7 +890,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); } @@ -904,7 +918,8 @@ public final class SpdyConnectionTest { // verify the peer received what was expected MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); + assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode); MockSpdyPeer.InFrame ping = peer.takeFrame(); assertEquals(TYPE_PING, ping.type); MockSpdyPeer.InFrame rstStream = peer.takeFrame(); @@ -939,7 +954,7 @@ public final class SpdyConnectionTest { // Verify the peer received what was expected. MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); for (int i = 0; i < 3; i++) { MockSpdyPeer.InFrame windowUpdate = peer.takeFrame(); assertEquals(TYPE_WINDOW_UPDATE, windowUpdate.type); @@ -971,7 +986,7 @@ public final class SpdyConnectionTest { // Verify the peer received what was expected. MockSpdyPeer.InFrame synStream = peer.takeFrame(); - assertEquals(TYPE_SYN_STREAM, synStream.type); + assertEquals(TYPE_HEADERS, synStream.type); MockSpdyPeer.InFrame data = peer.takeFrame(); assertEquals(TYPE_DATA, data.type); }