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

Merge pull request #480 from adriancole/backfill-tests

Backfill spdy and http/2 related tests wrt zero-length messages.
This commit is contained in:
Adrian Cole
2014-01-24 12:09:45 -08:00
3 changed files with 161 additions and 5 deletions

View File

@@ -57,6 +57,10 @@ public final class MockSpdyPeer implements Closeable {
frameCount++;
}
public int frameCount() {
return frameCount;
}
public FrameWriter sendFrame() {
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), Integer.MAX_VALUE));
return frameWriter;

View File

@@ -162,6 +162,17 @@ public final class SpdyConnectionTest {
}
@Test public void replyWithNoData() throws Exception {
MockSpdyPeer.InFrame reply = replyWithNoData(SPDY3);
assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
}
@Test public void replyWithNoDataHttp2() throws Exception {
MockSpdyPeer.InFrame reply = replyWithNoData(HTTP_20_DRAFT_09);
assertEquals(HeadersMode.HTTP_20_HEADERS, reply.headersMode);
}
private MockSpdyPeer.InFrame replyWithNoData(Variant variant) throws Exception {
MockSpdyPeer peer = new MockSpdyPeer(variant, false);
// write the mocking script
peer.sendFrame().synStream(false, false, 2, 0, 0, 0, headerEntries("a", "android"));
peer.acceptFrame(); // SYN_REPLY
@@ -175,15 +186,15 @@ public final class SpdyConnectionTest {
receiveCount.incrementAndGet();
}
};
new SpdyConnection.Builder(true, peer.openSocket()).handler(handler).build();
connectionBuilder(peer, variant).handler(handler).build();
// verify the peer received what was expected
MockSpdyPeer.InFrame reply = peer.takeFrame();
assertEquals(TYPE_HEADERS, reply.type);
assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
assertTrue(reply.inFinished);
assertEquals(headerEntries("b", "banana"), reply.headerBlock);
assertEquals(1, receiveCount.get());
return reply;
}
@Test public void noop() throws Exception {
@@ -1056,6 +1067,66 @@ public final class SpdyConnectionTest {
}
}
@Test public void serverSendsEmptyDataClientDoesntSendWindowUpdate() throws Exception {
serverSendsEmptyDataClientDoesntSendWindowUpdate(SPDY3);
}
@Test public void serverSendsEmptyDataClientDoesntSendWindowUpdateHttp2() throws Exception {
serverSendsEmptyDataClientDoesntSendWindowUpdate(HTTP_20_DRAFT_09);
}
private void serverSendsEmptyDataClientDoesntSendWindowUpdate(Variant variant)
throws IOException, InterruptedException {
MockSpdyPeer peer = new MockSpdyPeer(variant, false);
// Write the mocking script.
peer.acceptFrame(); // SYN_STREAM
peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
peer.sendFrame().data(true, 1, new byte[0]);
peer.play();
// Play it back.
SpdyConnection connection = connection(peer, variant);
SpdyStream client = connection.newStream(headerEntries("b", "banana"), false, true);
assertEquals(-1, client.getInputStream().read());
// Verify the peer received what was expected.
MockSpdyPeer.InFrame synStream = peer.takeFrame();
assertEquals(TYPE_HEADERS, synStream.type);
assertEquals(3, peer.frameCount());
}
@Test public void clientSendsEmptyDataServerDoesntSendWindowUpdate() throws Exception {
clientSendsEmptyDataServerDoesntSendWindowUpdate(SPDY3);
}
@Test public void clientSendsEmptyDataServerDoesntSendWindowUpdateHttp2() throws Exception {
clientSendsEmptyDataServerDoesntSendWindowUpdate(HTTP_20_DRAFT_09);
}
private void clientSendsEmptyDataServerDoesntSendWindowUpdate(Variant variant)
throws IOException, InterruptedException {
MockSpdyPeer peer = new MockSpdyPeer(variant, false);
// Write the mocking script.
peer.acceptFrame(); // SYN_STREAM
peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
peer.play();
// Play it back.
SpdyConnection connection = connection(peer, variant);
SpdyStream client = connection.newStream(headerEntries("b", "banana"), true, true);
assertEquals(0, client.getInputStream().available());
client.getOutputStream().write(Util.EMPTY_BYTE_ARRAY);
client.getOutputStream().flush();
client.getOutputStream().close();
// Verify the peer received what was expected.
MockSpdyPeer.InFrame synStream = peer.takeFrame();
assertEquals(TYPE_HEADERS, synStream.type);
assertEquals(2, peer.frameCount());
}
@Test public void writeAwaitsWindowUpdate() throws Exception {
int windowSize = 65535;
@@ -1215,9 +1286,12 @@ public final class SpdyConnectionTest {
}
private SpdyConnection connection(MockSpdyPeer peer, Variant variant) throws IOException {
return new SpdyConnection.Builder(true, peer.openSocket())
.protocol(variant.getProtocol())
.handler(REJECT_INCOMING_STREAMS).build();
return connectionBuilder(peer, variant).handler(REJECT_INCOMING_STREAMS).build();
}
private SpdyConnection.Builder connectionBuilder(MockSpdyPeer peer, Variant variant)
throws IOException {
return new SpdyConnection.Builder(true, peer.openSocket()).protocol(variant.getProtocol());
}
private void writeAndClose(SpdyStream stream, String data) throws IOException {

View File

@@ -76,6 +76,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static com.squareup.okhttp.internal.http.OkHeaders.SELECTED_PROTOCOL;
import static com.squareup.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
import static com.squareup.okhttp.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
import static com.squareup.okhttp.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
@@ -2527,6 +2528,71 @@ public final class URLConnectionTest {
assertTrue(call, call.contains("challenges=[Basic realm=\"protected area\"]"));
}
@Test public void npnSetsProtocolHeader_SPDY_3() throws Exception {
npnSetsProtocolHeader(Protocol.SPDY_3);
}
@Test public void npnSetsProtocolHeader_HTTP_2() throws Exception {
npnSetsProtocolHeader(Protocol.HTTP_2);
}
private void npnSetsProtocolHeader(Protocol protocol) throws IOException {
enableNpn(protocol);
server.enqueue(new MockResponse().setBody("A"));
server.play();
client.setProtocols(Arrays.asList(Protocol.HTTP_11, protocol));
HttpURLConnection connection = client.open(server.getUrl("/"));
List<String> protocolValues = connection.getHeaderFields().get(SELECTED_PROTOCOL);
assertEquals(Arrays.asList(protocol.name.utf8()), protocolValues);
assertContent("A", connection);
}
/** For example, empty Protobuf RPC messages end up as a zero-length POST. */
@Test public void zeroLengthPost() throws IOException, InterruptedException {
zeroLengthPayload("POST");
}
@Test public void zeroLengthPost_SPDY_3() throws Exception {
enableNpn(Protocol.SPDY_3);
zeroLengthPost();
}
@Test public void zeroLengthPost_HTTP_2() throws Exception {
enableNpn(Protocol.HTTP_2);
zeroLengthPost();
}
/** For example, creating an Amazon S3 bucket ends up as a zero-length POST. */
@Test public void zeroLengthPut() throws IOException, InterruptedException {
zeroLengthPayload("PUT");
}
@Test public void zeroLengthPut_SPDY_3() throws Exception {
enableNpn(Protocol.SPDY_3);
zeroLengthPut();
}
@Test public void zeroLengthPut_HTTP_2() throws Exception {
enableNpn(Protocol.HTTP_2);
zeroLengthPut();
}
private void zeroLengthPayload(String method)
throws IOException, InterruptedException {
server.enqueue(new MockResponse());
server.play();
HttpURLConnection connection = client.open(server.getUrl("/"));
connection.setRequestProperty("Content-Length", "0");
connection.setRequestMethod(method);
connection.setFixedLengthStreamingMode(0);
connection.setDoOutput(true);
assertContent("", connection);
RecordedRequest zeroLengthPayload = server.takeRequest();
assertEquals(method, zeroLengthPayload.getMethod());
assertEquals("0", zeroLengthPayload.getHeader("content-length"));
assertEquals(0L, zeroLengthPayload.getBodySize());
}
@Test public void setProtocols() throws Exception {
server.enqueue(new MockResponse().setBody("A"));
server.play();
@@ -2772,4 +2838,16 @@ public final class URLConnectionTest {
@Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
}
}
/**
* Tests that use this will fail unless boot classpath is set. Ex. {@code
* -Xbootclasspath/p:/tmp/npn-boot-8.1.2.v20120308.jar}
*/
private void enableNpn(Protocol protocol) {
server.useHttps(sslContext.getSocketFactory(), false);
server.setNpnEnabled(true);
client.setSslSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
client.setProtocols(Arrays.asList(protocol, Protocol.HTTP_11));
}
}