1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-24 04:02:07 +03:00

Use one callback for SYN_STREAM, SYN_REPLY and HEADERS.

This is closer to the semantics of HTTP/2.0, which uses the HEADERS
frame for all three types. SPDY is a bit more strict because it
relies on redundancy; it's an error to send a SYN_REPLY after a
HEADERS frame. With HTTP/2.0, there's only one type so there's
no error to detect.
This commit is contained in:
jwilson
2013-09-01 13:56:26 -04:00
parent dd82416bc5
commit a91124b6d4
8 changed files with 186 additions and 132 deletions

View File

@@ -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<String> nameValueBlock);
void synReply(boolean inFinished, int streamId, List<String> nameValueBlock) throws IOException;
void headers(int streamId, List<String> 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<String> nameValueBlock, HeadersMode headersMode);
void rstStream(int streamId, ErrorCode errorCode);
void settings(boolean clearPrevious, Settings settings);
void noop();

View File

@@ -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;
}
}

View File

@@ -143,7 +143,10 @@ final class Http20Draft04 implements Variant {
if ((flags & FLAG_END_HEADERS) != 0) {
hpackReader.emitReferenceSet();
List<String> 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;
}

View File

@@ -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<String> 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<String> 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 {

View File

@@ -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<String> nameValueBlock) {
final SpdyStream synStream;
final SpdyStream previous;
@Override public void headers(boolean outFinished, boolean inFinished, int streamId,
int associatedStreamId, int priority, List<String> 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<String> 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<String> 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) {

View File

@@ -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<String> requestHeaders, Settings settings) {
int priority, List<String> 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<String> strings) throws IOException {
void receiveHeaders(List<String> 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<String> newHeaders = new ArrayList<String>();
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<String> headers) {
assert (!Thread.holdsLock(SpdyStream.this));
boolean protocolError = false;
synchronized (this) {
if (responseHeaders != null) {
List<String> newHeaders = new ArrayList<String>();
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,

View File

@@ -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<String> 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<String> nameValueBlock) {
@Override public void headers(boolean outFinished, boolean inFinished, int streamId,
int associatedStreamId, int priority, List<String> 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<String> 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<String> 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)

View File

@@ -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);
}