package com.limegroup.gnutella.handshaking; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.util.Map; import java.util.Properties; import junit.framework.Test; import com.limegroup.gnutella.util.BaseTestCase; public class BlockingIncomingHandshakerTest extends BaseTestCase { public BlockingIncomingHandshakerTest(String name) { super(name); } public static Test suite() { return buildTestSuite(BlockingIncomingHandshakerTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public void testSimpleSuccess() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.6\r\n" + "RequestHeader: RequestValue\r\n" + "\r\n" + "GNUTELLA/0.6 200 OK DOKIE\r\n" + "ResponseHeader: ResponseValue\r\n" + "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Properties outProps = new Properties(); outProps.put("OutHeader", "OutValue"); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse(200, "OK!", outProps)); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); shaker.shake(); Map respondedTo = responder.getRespondedToProps(); assertEquals(1, respondedTo.size()); assertEquals("RequestValue", respondedTo.get("RequestHeader")); assertFalse(responder.isOutgoing()); HandshakeResponse read = shaker.getReadHeaders(); assertEquals(2, read.props().size()); assertEquals("RequestValue", read.props().get("RequestHeader")); assertEquals("ResponseValue", read.props().get("ResponseHeader")); HandshakeResponse written = shaker.getWrittenHeaders(); assertEquals(1, written.props().size()); assertEquals("OutValue", written.props().get("OutHeader")); assertEquals("GNUTELLA/0.6 200 OK!\r\nOutHeader: OutValue\r\n\r\n".getBytes(), out.toByteArray()); } public void testBelowPointSixFails() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.5\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Handshaker shaker = new BlockingIncomingHandshaker( new StubHandshakeResponder(), socket, in, out); try { shaker.shake(); fail("shouldn't have succeeded!"); } catch(IOException iox) { assertEquals("Unexpected connect string: GNUTELLA CONNECT/0.5", iox.getMessage()); } } public void testAbovePointSixSucceeds() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.7\r\n" + "RequestHeader: RequestValue\r\n" + "\r\n" + "GNUTELLA/0.6 200 OK DOKIE\r\n" + "ResponseHeader: ResponseValue\r\n" + "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Properties outProps = new Properties(); outProps.put("OutHeader", "OutValue"); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse(200, "OK!", outProps)); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); shaker.shake(); Map respondedTo = responder.getRespondedToProps(); assertEquals(1, respondedTo.size()); assertEquals("RequestValue", respondedTo.get("RequestHeader")); assertFalse(responder.isOutgoing()); HandshakeResponse read = shaker.getReadHeaders(); assertEquals(2, read.props().size()); assertEquals("RequestValue", read.props().get("RequestHeader")); assertEquals("ResponseValue", read.props().get("ResponseHeader")); HandshakeResponse written = shaker.getWrittenHeaders(); assertEquals(1, written.props().size()); assertEquals("OutValue", written.props().get("OutHeader")); assertEquals("GNUTELLA/0.6 200 OK!\r\nOutHeader: OutValue\r\n\r\n".getBytes(), out.toByteArray()); } public void testCrawlerDiscosEarly() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.6\r\n" + "Crawler: 0.1\r\n" + "\r\n" + // extra \r\n just so we don't disco early "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse()); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); try { shaker.shake(); fail("shouldn't have succeeded!"); } catch(IOException iox) { assertEquals("crawler", iox.getMessage()); } } public void testDiscoOnBadResponder() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.6\r\n" + "RequestHeader: RequestValue\r\n" + "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Properties outProps = new Properties(); outProps.put("OutHeader", "OutValue"); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse(599, "NOPE", outProps)); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); try { shaker.shake(); fail("should have failed!"); } catch(NoGnutellaOkException ngok) { assertEquals(599, ngok.getCode()); } assertEquals(1, shaker.getReadHeaders().props().size()); assertEquals("RequestValue", shaker.getReadHeaders().props().get("RequestHeader")); assertEquals(1, shaker.getWrittenHeaders().props().size()); assertEquals("OutValue", shaker.getWrittenHeaders().props().get("OutHeader")); } public void testDiscoOnBadResponse() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.6\r\n" + "RequestHeader: RequestValue\r\n" + "\r\n" + "GNUTELLA/0.6 333 SUX\r\n" + "ResponseHeader: ResponseValue\r\n" + "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Properties outProps = new Properties(); outProps.put("OutHeader", "OutValue"); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse(200, "SURE", outProps)); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); try { shaker.shake(); fail("should have failed!"); } catch(NoGnutellaOkException ngok) { assertEquals(333, ngok.getCode()); } assertEquals(2, shaker.getReadHeaders().props().size()); assertEquals("RequestValue", shaker.getReadHeaders().props().get("RequestHeader")); assertEquals("ResponseValue", shaker.getReadHeaders().props().get("ResponseHeader")); assertEquals(1, shaker.getWrittenHeaders().props().size()); assertEquals("OutValue", shaker.getWrittenHeaders().props().get("OutHeader")); } public void testDiscoOnBadResponseConnectLine() throws Exception { Socket socket = new AddressedSocket(); InputStream in = new ByteArrayInputStream( ("GNUTELLA CONNECT/0.6\r\n" + "RequestHeader: RequestValue\r\n" + "\r\n" + "HTTP/1.1 543 WHAT ARE YOU DOING?\r\n" + "ResponseHeader: ResponseValue\r\n" + "\r\n").getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); Properties outProps = new Properties(); outProps.put("OutHeader", "OutValue"); StubHandshakeResponder responder = new StubHandshakeResponder(new StubHandshakeResponse(200, "SURE", outProps)); Handshaker shaker = new BlockingIncomingHandshaker(responder, socket, in, out); try { shaker.shake(); fail("should have failed!"); } catch(IOException iox) { assertEquals("Bad connect string", iox.getMessage()); } assertEquals(1, shaker.getReadHeaders().props().size()); assertEquals("RequestValue", shaker.getReadHeaders().props().get("RequestHeader")); assertEquals(1, shaker.getWrittenHeaders().props().size()); assertEquals("OutValue", shaker.getWrittenHeaders().props().get("OutHeader")); } private static class AddressedSocket extends Socket { public InetAddress getInetAddress() { try { return InetAddress.getByName("127.0.0.1"); } catch(IOException iox) { return null; } } } }