private void writeUntilFull(NetSocket so, Handler<Void> handler) { if (so.writeQueueFull()) { handler.handle(null); } else { // Give enough time to report a proper full so.write(TestUtils.randomBuffer(16384)); vertx.setTimer(10, id -> writeUntilFull(so, handler)); } }
@Test public void testInvalidTrailerInHttpServerRequest() throws Exception { testHttpServerRequestDecodeError(so -> { so.write("0\r\n"); // Empty chunk // Send large trailer for (int i = 0;i < 2000;i++) { so.write("01234567"); } }, errors -> { assertEquals(2, errors.size()); assertEquals(TooLongFrameException.class, errors.get(0).getClass()); }); }
synchronized void writeMessage(ClusteredMessage message) { if (connected) { Buffer data = message.encodeToWire(); if (metrics != null) { metrics.messageWritten(message.address(), data.length()); } socket.write(data); } else { if (pending == null) { if (log.isDebugEnabled()) { log.debug("Not connected to server " + serverID + " - starting queuing"); } pending = new ArrayDeque<>(); } pending.add(message); } }
@Test public void testConnectionCloseHttp_1_1_NoClose() throws Exception { testConnectionClose(HttpClientRequest::end, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 4\r\n" + "\r\n" + "xxx\n"); } else { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 1\r\n" + "Connection: close\r\n" + "\r\n" + "\r\n"); } })); }); }
@Test public void testInvalidChunkInHttpServerRequest() throws Exception { testHttpServerRequestDecodeError(so -> { so.write("invalid\r\n"); // Empty chunk }, errors -> { assertEquals(2, errors.size()); assertEquals(NumberFormatException.class, errors.get(0).getClass()); }); }
@Test public void testConnectionCloseHttp_1_1_Close() throws Exception { testConnectionClose(HttpClientRequest::end, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 3\r\n" + "\r\n" + "xxx"); } else { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"); socket.close(); } })); }); }
void testEchoStringWithEncoding(String encoding) { String sent = TestUtils.randomUnicodeString(100); Buffer buffSent = Buffer.buffer(sent, encoding); testEcho(sock -> sock.write(sent, encoding), buff -> assertEquals(buffSent, buff), buffSent.length()); }
@Test public void testConnectionCloseHttp_1_0_NoClose() throws Exception { testConnectionClose(req -> { req.putHeader("Connection", "close"); req.end(); }, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 4\n" + "Connection: keep-alive\n" + "\n" + "xxx\n"); } else { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 1\n" + "\n" + "\n"); } })); }); }
@Test public void testConnectionCloseHttp_1_0_Close() throws Exception { testConnectionClose(req -> { req.putHeader("Connection", "close"); req.end(); }, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 4\n" + "Connection: keep-alive\n" + "\n" + "xxx\n"); } else { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 1\n" + "\n" + "\n"); socket.close(); } })); }); }
@Test public void testEchoString() { String sent = TestUtils.randomUnicodeString(100); Buffer buffSent = Buffer.buffer(sent); testEcho(sock -> sock.write(sent), buff -> assertEquals(buffSent, buff), buffSent.length()); }
@Test public void testRequestHandlerNotCalledInvalidRequest() { server.requestHandler(req -> { fail(); }); server.listen(onSuccess(s -> { vertx.createNetClient(new NetClientOptions()).connect(8080, "127.0.0.1", onSuccess(socket -> { socket.closeHandler(r -> { testComplete(); }); socket.write("GET HTTP1/1\r\n"); // trigger another write to be sure we detect that the other peer has closed the connection. socket.write("X-Header: test\r\n"); })); })); await(); }
@Test public void testClientConnectionExceptionHandler() throws Exception { server.requestHandler(req -> { NetSocket so = req.netSocket(); so.write(Buffer.buffer(TestUtils.randomAlphaString(40) + "\r\n")); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { }); req.connectionHandler(conn -> { conn.exceptionHandler(err -> { testComplete(); }); }); req.sendHead(); await(); }
@Test public void testEchoBytes() { Buffer sent = TestUtils.randomBuffer(100); testEcho(sock -> sock.write(sent), buff -> assertEquals(sent, buff), sent.length()); }
@Test public void testReportProtocolViolationOnServer() { server = vertx.createHttpServer(new HttpServerOptions().setPort(DEFAULT_HTTP_PORT)).websocketHandler(ws -> { AtomicReference<Throwable> failure = new AtomicReference<>(); ws.closeHandler(v -> { assertNotNull(failure.get()); testComplete(); }); ws.exceptionHandler(failure::set); }); server.listen(ar -> { assertTrue(ar.succeeded()); handshake(sock -> { // Let's write an invalid frame Buffer buff = Buffer.buffer(); buff.appendByte((byte)(0x8)).appendByte((byte)0); // Violates protocol with V13 (final control frame) sock.write(buff); }); }); await(); }
@Test public void testWriteHandlerSuccess() throws Exception { CompletableFuture<Void> close = new CompletableFuture<>(); server.connectHandler(socket -> { socket.pause(); close.thenAccept(v -> { socket.resume(); }); }); startServer(); client.connect(testAddress, onSuccess(so -> { writeUntilFull(so, v -> { so.write(Buffer.buffer("lost buffer"), onSuccess(ack -> testComplete())); close.complete(null); }); })); await(); }
@Test public void testPartialH2CAmbiguousRequest() throws Exception { server.requestHandler(req -> { assertEquals("POST", req.rawMethod()); testComplete(); }); Buffer fullRequest = Buffer.buffer("POST /whatever HTTP/1.1\r\n\r\n"); startServer(); NetClient client = vertx.createNetClient(); client.connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, onSuccess(so -> { so.write(fullRequest.slice(0, 1)); vertx.setTimer(1000, id -> { so.write(fullRequest.slice(1, fullRequest.length())); }); })); await(); }
@Test public void testWriteHandlerFailure() throws Exception { CompletableFuture<Void> close = new CompletableFuture<>(); server.connectHandler(socket -> { socket.pause(); close.thenAccept(v -> { socket.close(); }); }); startServer(); client.connect(testAddress, onSuccess(so -> { writeUntilFull(so, v -> { so.write(Buffer.buffer("lost buffer"), onFailure(err -> { testComplete(); })); close.complete(null); }); })); await(); }
private void schedulePing() { EventBusOptions options = eventBus.options(); pingTimeoutID = vertx.setTimer(options.getClusterPingInterval(), id1 -> { // If we don't get a pong back in time we close the connection timeoutID = vertx.setTimer(options.getClusterPingReplyInterval(), id2 -> { // Didn't get pong in time - consider connection dead log.warn("No pong from server " + serverID + " - will consider it dead"); close(); }); ClusteredMessage pingMessage = new ClusteredMessage<>(serverID, PING_ADDRESS, null, null, null, new PingMessageCodec(), true, eventBus); Buffer data = pingMessage.encodeToWire(); socket.write(data); }); }
private NetSocket getUpgradedNetSocket(HttpServerRequest req, String path) { assertEquals(path, req.path()); assertEquals("upgrade", req.headers().get("Connection")); NetSocket sock = req.netSocket(); String secHeader = req.headers().get("Sec-WebSocket-Key"); String tmp = secHeader + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; String encoded = sha1(tmp); sock.write("HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + "Upgrade: WebSocket\r\n" + "Connection: upgrade\r\n" + "Sec-WebSocket-Accept: " + encoded + "\r\n" + "\r\n"); return sock; }
private TestLoggerFactory testLogging() throws Exception { return TestUtils.testLogging(() -> { server.connectHandler(so -> { so.write("fizzbuzz").end(); }); server.listen(testAddress, onSuccess(v1 -> { client.connect(testAddress, onSuccess(so -> { so.closeHandler(v2 -> testComplete()); })); })); await(); }); }