@Test public void testPING() throws Exception { // PING is per hop, and it does not carry the information to which server to ping to // We just verify that it works InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter())); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); final CountDownLatch pingLatch = new CountDownLatch(1); Session client = factory .newSPDYClient(version) .connect( proxyAddress, new SessionFrameListener.Adapter() { @Override public void onPing(Session session, PingResultInfo pingInfo) { pingLatch.countDown(); } }) .get(5, TimeUnit.SECONDS); client.ping(new PingInfo(5, TimeUnit.SECONDS)); Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS)); client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS)); }
@Test public void testSYNThenREPLYAndDATA() throws Exception { final byte[] data = "0123456789ABCDEF".getBytes("UTF-8"); final String header = "foo"; InetSocketAddress proxyAddress = startProxy( startServer( new ServerSessionFrameListener.Adapter() { @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) { Fields requestHeaders = synInfo.getHeaders(); Assert.assertNotNull(requestHeaders.get("via")); Assert.assertNotNull(requestHeaders.get(header)); Fields responseHeaders = new Fields(); responseHeaders.put(header, "baz"); stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter()); stream.data(new BytesDataInfo(data, true), new Callback.Adapter()); return null; } })); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); Session client = factory.newSPDYClient(version).connect(proxyAddress, null).get(5, TimeUnit.SECONDS); final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1); Fields headers = new Fields(); headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort()); headers.put(header, "bar"); client.syn( new SynInfo(headers, true), new StreamFrameListener.Adapter() { private final ByteArrayOutputStream result = new ByteArrayOutputStream(); @Override public void onReply(Stream stream, ReplyInfo replyInfo) { Fields headers = replyInfo.getHeaders(); Assert.assertNotNull(headers.get(header)); replyLatch.countDown(); } @Override public void onData(Stream stream, DataInfo dataInfo) { result.write(dataInfo.asBytes(true), 0, dataInfo.length()); if (dataInfo.isClose()) { Assert.assertArrayEquals(data, result.toByteArray()); dataLatch.countDown(); } } }); Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS)); Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS)); client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS)); }
protected Session startClient( short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception { if (clientFactory == null) { QueuedThreadPool threadPool = new QueuedThreadPool(); threadPool.setName(threadPool.getName() + "-client"); clientFactory = newSPDYClientFactory(threadPool); clientFactory.start(); } return clientFactory .newSPDYClient(version) .connect(socketAddress, listener) .get(5, TimeUnit.SECONDS); }
@Test public void testSYNThenReset() throws Exception { InetSocketAddress proxyAddress = startProxy( startServer( new ServerSessionFrameListener.Adapter() { @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) { Assert.assertTrue(synInfo.isClose()); Fields requestHeaders = synInfo.getHeaders(); Assert.assertNotNull(requestHeaders.get("via")); stream .getSession() .rst( new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter()); return null; } })); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); final CountDownLatch resetLatch = new CountDownLatch(1); Session client = factory .newSPDYClient(version) .connect( proxyAddress, new SessionFrameListener.Adapter() { @Override public void onRst(Session session, RstInfo rstInfo) { resetLatch.countDown(); } }) .get(5, TimeUnit.SECONDS); Fields headers = new Fields(); headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort()); client.syn(new SynInfo(headers, true), null); Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS)); client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS)); }
@Test public void testSYNThenREPLY() throws Exception { final String header = "foo"; InetSocketAddress proxyAddress = startProxy( startServer( new ServerSessionFrameListener.Adapter() { @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) { Fields requestHeaders = synInfo.getHeaders(); Assert.assertNotNull(requestHeaders.get("via")); Assert.assertNotNull(requestHeaders.get(header)); Fields responseHeaders = new Fields(); responseHeaders.put(header, "baz"); stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter()); return null; } })); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); Session client = factory.newSPDYClient(version).connect(proxyAddress, null).get(5, TimeUnit.SECONDS); final CountDownLatch replyLatch = new CountDownLatch(1); Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/"); headers.put(header, "bar"); client.syn( new SynInfo(headers, true), new StreamFrameListener.Adapter() { @Override public void onReply(Stream stream, ReplyInfo replyInfo) { Fields headers = replyInfo.getHeaders(); Assert.assertNotNull(headers.get(header)); replyLatch.countDown(); } }); Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS)); client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS)); }
@Test public void testSYNThenRSTFromUpstreamServer() throws Exception { final String header = "foo"; InetSocketAddress proxyAddress = startProxy( startServer( new ServerSessionFrameListener.Adapter() { @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) { Fields requestHeaders = synInfo.getHeaders(); Assert.assertNotNull(requestHeaders.get("via")); Assert.assertNotNull(requestHeaders.get(header)); stream .getSession() .rst( new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter()); return null; } })); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); final CountDownLatch resetLatch = new CountDownLatch(1); Session client = factory .newSPDYClient(version) .connect( proxyAddress, new SessionFrameListener.Adapter() { @Override public void onRst(Session session, RstInfo rstInfo) { resetLatch.countDown(); } }); Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/"); headers.put(header, "bar"); client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()); assertThat("reset is received by client", resetLatch.await(5, TimeUnit.SECONDS), is(true)); }
@Test public void testSYNThenSPDYNestedPushIsReceived() throws Exception { final byte[] data = "0123456789ABCDEF".getBytes("UTF-8"); InetSocketAddress proxyAddress = startProxy( startServer( new ServerSessionFrameListener.Adapter() { @Override public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) { Fields responseHeaders = new Fields(); responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1"); responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK"); stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter()); final Fields pushHeaders = new Fields(); pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push"); stream.push( new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>() { @Override public void succeeded(Stream pushStream) { pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/nestedpush"); pushStream.push( new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Adapter<Stream>() { @Override public void succeeded(Stream pushStream) { pushHeaders.put( HTTPSPDYHeader.URI.name(version), "/anothernestedpush"); pushStream.push( new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Adapter<Stream>() { @Override public void succeeded(Stream pushStream) { pushStream.data( new BytesDataInfo(data, true), new Callback.Adapter()); } }); pushStream.data( new BytesDataInfo(data, true), new Callback.Adapter()); } }); pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter()); } }); stream.data(new BytesDataInfo(data, true), new Callback.Adapter()); return null; } })); proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version)); final CountDownLatch pushSynLatch = new CountDownLatch(3); final CountDownLatch pushDataLatch = new CountDownLatch(3); Session client = factory.newSPDYClient(version).connect(proxyAddress, null).get(5, TimeUnit.SECONDS); Fields headers = new Fields(); headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort()); final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1); client.syn( new SynInfo(headers, true), new StreamFrameListener.Adapter() { // onPush for 1st push stream @Override public StreamFrameListener onPush(Stream stream, PushInfo pushInfo) { pushSynLatch.countDown(); return new StreamFrameListener.Adapter() { // onPush for 2nd nested push stream @Override public StreamFrameListener onPush(Stream stream, PushInfo pushInfo) { pushSynLatch.countDown(); return new Adapter() { // onPush for 3rd nested push stream @Override public StreamFrameListener onPush(Stream stream, PushInfo pushInfo) { pushSynLatch.countDown(); return new Adapter() { @Override public void onData(Stream stream, DataInfo dataInfo) { dataInfo.consume(dataInfo.length()); if (dataInfo.isClose()) pushDataLatch.countDown(); } }; } @Override public void onData(Stream stream, DataInfo dataInfo) { dataInfo.consume(dataInfo.length()); if (dataInfo.isClose()) pushDataLatch.countDown(); } }; } @Override public void onData(Stream stream, DataInfo dataInfo) { dataInfo.consume(dataInfo.length()); if (dataInfo.isClose()) pushDataLatch.countDown(); } }; } @Override public void onReply(Stream stream, ReplyInfo replyInfo) { replyLatch.countDown(); } @Override public void onData(Stream stream, DataInfo dataInfo) { dataInfo.consume(dataInfo.length()); if (dataInfo.isClose()) dataLatch.countDown(); } }); Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS)); Assert.assertTrue(pushSynLatch.await(5, TimeUnit.SECONDS)); Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS)); Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS)); client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS)); }