@Test
  public void testResponseWithContentLength() {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    ch.writeInbound(
        Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\n" + "Content-Length: 10\r\n" + "\r\n", CharsetUtil.US_ASCII));

    byte[] data = new byte[10];
    for (int i = 0; i < data.length; i++) {
      data[i] = (byte) i;
    }
    ch.writeInbound(Unpooled.wrappedBuffer(data, 0, data.length / 2));
    ch.writeInbound(Unpooled.wrappedBuffer(data, 5, data.length / 2));

    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));

    HttpContent firstContent = ch.readInbound();
    assertThat(firstContent.content().readableBytes(), is(5));
    assertEquals(Unpooled.wrappedBuffer(data, 0, 5), firstContent.content());
    firstContent.release();

    LastHttpContent lastContent = ch.readInbound();
    assertEquals(5, lastContent.content().readableBytes());
    assertEquals(Unpooled.wrappedBuffer(data, 5, 5), lastContent.content());
    lastContent.release();

    assertThat(ch.finish(), is(false));
    assertThat(ch.readInbound(), is(nullValue()));
  }
  private static void testSpdySessionHandlerPing(SpdyVersion version, boolean server) {
    EmbeddedChannel sessionHandler =
        new EmbeddedChannel(
            new SpdySessionHandler(version, server), new EchoHandler(closeSignal, server));

    while (sessionHandler.readOutbound() != null) {
      continue;
    }

    int localStreamId = server ? 1 : 2;
    int remoteStreamId = server ? 2 : 1;

    SpdyPingFrame localPingFrame = new DefaultSpdyPingFrame(localStreamId);
    SpdyPingFrame remotePingFrame = new DefaultSpdyPingFrame(remoteStreamId);

    // Check if session handler returns identical local PINGs
    sessionHandler.writeInbound(localPingFrame);
    assertPing(sessionHandler.readOutbound(), localPingFrame.getId());
    assertNull(sessionHandler.readOutbound());

    // Check if session handler ignores un-initiated remote PINGs
    sessionHandler.writeInbound(remotePingFrame);
    assertNull(sessionHandler.readOutbound());

    sessionHandler.finish();
  }
  private static void testLastResponseWithTrailingHeaderFragmented(
      byte[] content, int fragmentSize) {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    int headerLength = 47;
    // split up the header
    for (int a = 0; a < headerLength; ) {
      int amount = fragmentSize;
      if (a + amount > headerLength) {
        amount = headerLength - a;
      }

      // if header is done it should produce a HttpRequest
      boolean headerDone = a + amount == headerLength;
      assertEquals(headerDone, ch.writeInbound(Unpooled.wrappedBuffer(content, a, amount)));
      a += amount;
    }

    ch.writeInbound(Unpooled.wrappedBuffer(content, headerLength, content.length - headerLength));
    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));

    LastHttpContent lastContent = ch.readInbound();
    assertThat(lastContent.content().isReadable(), is(false));
    HttpHeaders headers = lastContent.trailingHeaders();
    assertEquals(1, headers.names().size());
    List<String> values = headers.getAll("Set-Cookie");
    assertEquals(2, values.size());
    assertTrue(values.contains("t1=t1v1"));
    assertTrue(values.contains("t2=t2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT"));
    lastContent.release();

    assertThat(ch.finish(), is(false));
    assertThat(ch.readInbound(), is(nullValue()));
  }
  @Test
  public void testLastResponseWithHeaderRemoveTrailingSpaces() {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    ch.writeInbound(
        Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\nX-Header: h2=h2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT       \r\n\r\n",
            CharsetUtil.US_ASCII));

    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));
    assertThat(res.headers().get("X-Header"), is("h2=h2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT"));
    assertThat(ch.readInbound(), is(nullValue()));

    ch.writeInbound(Unpooled.wrappedBuffer(new byte[1024]));
    HttpContent content = ch.readInbound();
    assertThat(content.content().readableBytes(), is(1024));
    content.release();

    assertThat(ch.finish(), is(true));

    LastHttpContent lastContent = ch.readInbound();
    assertThat(lastContent.content().isReadable(), is(false));
    lastContent.release();

    assertThat(ch.readInbound(), is(nullValue()));
  }
  @Test
  public void testGarbageHeaders() {
    // A response without headers - from https://github.com/netty/netty/issues/2103
    byte[] data =
        ("<html>\r\n"
                + "<head><title>400 Bad Request</title></head>\r\n"
                + "<body bgcolor=\"white\">\r\n"
                + "<center><h1>400 Bad Request</h1></center>\r\n"
                + "<hr><center>nginx/1.1.19</center>\r\n"
                + "</body>\r\n"
                + "</html>\r\n")
            .getBytes();

    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());

    ch.writeInbound(Unpooled.wrappedBuffer(data));

    // Garbage input should generate the 999 Unknown response.
    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_0));
    assertThat(res.getStatus().code(), is(999));
    assertThat(res.getDecoderResult().isFailure(), is(true));
    assertThat(res.getDecoderResult().isFinished(), is(true));
    assertThat(ch.readInbound(), is(nullValue()));

    // More garbage should not generate anything (i.e. the decoder discards anything beyond this
    // point.)
    ch.writeInbound(Unpooled.wrappedBuffer(data));
    assertThat(ch.readInbound(), is(nullValue()));

    // Closing the connection should not generate anything since the protocol has been violated.
    ch.finish();
    assertThat(ch.readInbound(), is(nullValue()));
  }
  @AdviseWith(adviceClasses = NettyUtilAdvice.class)
  @NewEnv(type = NewEnv.Type.CLASSLOADER)
  @Test
  public void testExecute() throws Exception {
    EmbeddedChannel embeddedChannel = NettyTestUtil.createEmptyEmbeddedChannel();

    ChannelPipeline channelPipeline = embeddedChannel.pipeline();

    channelPipeline.addFirst(NettyRPCChannelHandler.NAME, NettyRPCChannelHandler.INSTANCE);

    NettyChannelAttributes.putFabricWorker(
        embeddedChannel,
        0,
        new LocalFabricWorker<Serializable>(
            new EmbeddedProcessChannel<Serializable>(new DefaultNoticeableFuture<Serializable>())));

    ProcessCallableExecutor processCallableExecutor =
        new NettyFabricWorkerProcessCallableExecutor(embeddedChannel, 0, Long.MAX_VALUE);

    NoticeableFuture<Serializable> noticeableFuture =
        processCallableExecutor.execute(
            new ProcessCallable<Serializable>() {

              @Override
              public Serializable call() {
                return StringPool.BLANK;
              }
            });

    embeddedChannel.writeInbound(embeddedChannel.readOutbound());
    embeddedChannel.writeInbound(embeddedChannel.readOutbound());

    Assert.assertEquals(StringPool.BLANK, noticeableFuture.get());

    final ProcessException processException = new ProcessException("");

    noticeableFuture =
        processCallableExecutor.execute(
            new ProcessCallable<Serializable>() {

              @Override
              public Serializable call() throws ProcessException {
                throw processException;
              }
            });

    embeddedChannel.writeInbound(embeddedChannel.readOutbound());
    embeddedChannel.writeInbound(embeddedChannel.readOutbound());

    try {
      noticeableFuture.get();

      Assert.fail();
    } catch (ExecutionException ee) {
      Assert.assertSame(processException, ee.getCause());
    }
  }
 @Test
 public void testTinyDecode() {
   byte[] b = {4, 1, 1, 1, 1};
   ch.writeInbound(wrappedBuffer(b, 0, 1));
   assertThat(ch.readInbound(), is(nullValue()));
   ch.writeInbound(wrappedBuffer(b, 1, 2));
   assertThat(ch.readInbound(), is(nullValue()));
   ch.writeInbound(wrappedBuffer(b, 3, b.length - 3));
   assertThat(
       releaseLater((ByteBuf) ch.readInbound()),
       is(releaseLater(wrappedBuffer(new byte[] {1, 1, 1, 1}))));
 }
  @Test
  public void testResponseChunkedExceedMaxChunkSize() {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder(4096, 8192, 32));
    ch.writeInbound(
        Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n", CharsetUtil.US_ASCII));

    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));

    byte[] data = new byte[64];
    for (int i = 0; i < data.length; i++) {
      data[i] = (byte) i;
    }

    for (int i = 0; i < 10; i++) {
      assertFalse(
          ch.writeInbound(
              Unpooled.copiedBuffer(
                  Integer.toHexString(data.length) + "\r\n", CharsetUtil.US_ASCII)));
      assertTrue(ch.writeInbound(Unpooled.wrappedBuffer(data)));

      byte[] decodedData = new byte[data.length];
      HttpContent content = ch.readInbound();
      assertEquals(32, content.content().readableBytes());
      content.content().readBytes(decodedData, 0, 32);
      content.release();

      content = ch.readInbound();
      assertEquals(32, content.content().readableBytes());

      content.content().readBytes(decodedData, 32, 32);

      assertArrayEquals(data, decodedData);
      content.release();

      assertFalse(ch.writeInbound(Unpooled.copiedBuffer("\r\n", CharsetUtil.US_ASCII)));
    }

    // Write the last chunk.
    ch.writeInbound(Unpooled.copiedBuffer("0\r\n\r\n", CharsetUtil.US_ASCII));

    // Ensure the last chunk was decoded.
    LastHttpContent content = ch.readInbound();
    assertFalse(content.content().isReadable());
    content.release();

    ch.finish();
    assertNull(ch.readInbound());
  }
  @Test
  public void testExecute() throws Exception {
    EmbeddedChannel embeddedChannel = NettyTestUtil.createEmptyEmbeddedChannel();

    ChannelPipeline channelPipeline = embeddedChannel.pipeline();

    channelPipeline.addFirst(NettyRPCChannelHandler.NAME, NettyRPCChannelHandler.INSTANCE);

    ProcessCallableExecutor processCallableExecutor =
        new NettyFabricAgentProcessCallableExecutor(embeddedChannel);

    NoticeableFuture<Serializable> noticeableFuture =
        processCallableExecutor.execute(
            new ProcessCallable<Serializable>() {

              @Override
              public Serializable call() {
                return StringPool.BLANK;
              }
            });

    embeddedChannel.writeInbound(embeddedChannel.readOutbound());
    embeddedChannel.writeInbound(embeddedChannel.readOutbound());

    Assert.assertEquals(StringPool.BLANK, noticeableFuture.get());

    final ProcessException processException = new ProcessException("");

    noticeableFuture =
        processCallableExecutor.execute(
            new ProcessCallable<Serializable>() {

              @Override
              public Serializable call() throws ProcessException {
                throw processException;
              }
            });

    embeddedChannel.writeInbound(embeddedChannel.readOutbound());
    embeddedChannel.writeInbound(embeddedChannel.readOutbound());

    try {
      noticeableFuture.get();

      Assert.fail();
    } catch (ExecutionException ee) {
      Assert.assertSame(processException, ee.getCause());
    }
  }
  private static void testSpdySessionHandlerGoAway(SpdyVersion version, boolean server) {
    EmbeddedChannel sessionHandler =
        new EmbeddedChannel(
            new SpdySessionHandler(version, server), new EchoHandler(closeSignal, server));

    while (sessionHandler.readOutbound() != null) {
      continue;
    }

    int localStreamId = server ? 1 : 2;

    SpdySynStreamFrame spdySynStreamFrame =
        new DefaultSpdySynStreamFrame(localStreamId, 0, (byte) 0);
    spdySynStreamFrame.headers().set("Compression", "test");

    SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(localStreamId);
    spdyDataFrame.setLast(true);

    // Send an initial request
    sessionHandler.writeInbound(spdySynStreamFrame);
    assertSynReply(
        sessionHandler.readOutbound(), localStreamId, false, spdySynStreamFrame.headers());
    assertNull(sessionHandler.readOutbound());
    sessionHandler.writeInbound(spdyDataFrame);
    assertDataFrame(sessionHandler.readOutbound(), localStreamId, true);
    assertNull(sessionHandler.readOutbound());

    // Check if session handler sends a GOAWAY frame when closing
    sessionHandler.writeInbound(closeMessage);
    assertGoAway(sessionHandler.readOutbound(), localStreamId);
    assertNull(sessionHandler.readOutbound());
    localStreamId += 2;

    // Check if session handler returns REFUSED_STREAM if it receives
    // SYN_STREAM frames after sending a GOAWAY frame
    spdySynStreamFrame.setStreamId(localStreamId);
    sessionHandler.writeInbound(spdySynStreamFrame);
    assertRstStream(sessionHandler.readOutbound(), localStreamId, SpdyStreamStatus.REFUSED_STREAM);
    assertNull(sessionHandler.readOutbound());

    // Check if session handler ignores Data frames after sending
    // a GOAWAY frame
    spdyDataFrame.setStreamId(localStreamId);
    sessionHandler.writeInbound(spdyDataFrame);
    assertNull(sessionHandler.readOutbound());

    sessionHandler.finish();
  }
  @Test
  public void testPrematureClosureWithChunkedEncoding2() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());

    // Write the partial response.
    ch.writeInbound(
        Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n8\r\n12345678",
            CharsetUtil.US_ASCII));

    // Read the response headers.
    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));

    // Read the partial content.
    HttpContent content = ch.readInbound();
    assertThat(content.content().toString(CharsetUtil.US_ASCII), is("12345678"));
    assertThat(content, is(not(instanceOf(LastHttpContent.class))));
    content.release();

    assertThat(ch.readInbound(), is(nullValue()));

    // Close the connection.
    ch.finish();

    // The decoder should not generate the last chunk because it's closed prematurely.
    assertThat(ch.readInbound(), is(nullValue()));
  }
  @Test
  public void testCompatibleExtensionTogetherSuccess() {
    // initialize
    expect(mainHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("main")))
        .andReturn(mainExtensionMock)
        .anyTimes();
    expect(mainHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("fallback")))
        .andReturn(null)
        .anyTimes();
    replay(mainHandshakerMock);

    expect(fallbackHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("fallback")))
        .andReturn(fallbackExtensionMock)
        .anyTimes();
    expect(fallbackHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("main")))
        .andReturn(null)
        .anyTimes();
    replay(fallbackHandshakerMock);

    expect(mainExtensionMock.rsv()).andReturn(WebSocketExtension.RSV1).anyTimes();
    expect(mainExtensionMock.newReponseData())
        .andReturn(new WebSocketExtensionData("main", Collections.<String, String>emptyMap()))
        .once();
    expect(mainExtensionMock.newExtensionEncoder()).andReturn(new DummyEncoder()).once();
    expect(mainExtensionMock.newExtensionDecoder()).andReturn(new DummyDecoder()).once();
    replay(mainExtensionMock);

    expect(fallbackExtensionMock.rsv()).andReturn(WebSocketExtension.RSV2).anyTimes();
    expect(fallbackExtensionMock.newReponseData())
        .andReturn(new WebSocketExtensionData("fallback", Collections.<String, String>emptyMap()))
        .once();
    expect(fallbackExtensionMock.newExtensionEncoder()).andReturn(new Dummy2Encoder()).once();
    expect(fallbackExtensionMock.newExtensionDecoder()).andReturn(new Dummy2Decoder()).once();
    replay(fallbackExtensionMock);

    // execute
    EmbeddedChannel ch =
        new EmbeddedChannel(
            new WebSocketServerExtensionHandler(mainHandshakerMock, fallbackHandshakerMock));

    HttpRequest req = newUpgradeRequest("main, fallback");
    ch.writeInbound(req);

    HttpResponse res = newUpgradeResponse(null);
    ch.writeOutbound(res);

    HttpResponse res2 = ch.readOutbound();
    List<WebSocketExtensionData> resExts =
        WebSocketExtensionUtil.extractExtensions(
            res2.headers().getAndConvert(HttpHeaderNames.SEC_WEBSOCKET_EXTENSIONS));

    // test
    assertEquals(2, resExts.size());
    assertEquals("main", resExts.get(0).name());
    assertEquals("fallback", resExts.get(1).name());
    assertNotNull(ch.pipeline().get(DummyDecoder.class));
    assertNotNull(ch.pipeline().get(DummyEncoder.class));
    assertNotNull(ch.pipeline().get(Dummy2Decoder.class));
    assertNotNull(ch.pipeline().get(Dummy2Encoder.class));
  }
  @Test
  public void testNoneExtensionMatchingSuccess() {
    // initialize
    expect(mainHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("unknown")))
        .andReturn(null)
        .anyTimes();
    expect(mainHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("unknown2")))
        .andReturn(null)
        .anyTimes();
    replay(mainHandshakerMock);

    expect(fallbackHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("unknown")))
        .andReturn(null)
        .anyTimes();
    expect(fallbackHandshakerMock.handshakeExtension(webSocketExtensionDataEqual("unknown2")))
        .andReturn(null)
        .anyTimes();
    replay(fallbackHandshakerMock);

    // execute
    EmbeddedChannel ch =
        new EmbeddedChannel(
            new WebSocketServerExtensionHandler(mainHandshakerMock, fallbackHandshakerMock));

    HttpRequest req = newUpgradeRequest("unknown, unknown2");
    ch.writeInbound(req);

    HttpResponse res = newUpgradeResponse(null);
    ch.writeOutbound(res);

    HttpResponse res2 = ch.readOutbound();

    // test
    assertFalse(res2.headers().contains(HttpHeaderNames.SEC_WEBSOCKET_EXTENSIONS));
  }
  @Test
  public void testLastResponseWithTrailingHeader() {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    ch.writeInbound(
        Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\n"
                + "Transfer-Encoding: chunked\r\n"
                + "\r\n"
                + "0\r\n"
                + "Set-Cookie: t1=t1v1\r\n"
                + "Set-Cookie: t2=t2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT\r\n"
                + "\r\n",
            CharsetUtil.US_ASCII));

    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));

    LastHttpContent lastContent = ch.readInbound();
    assertThat(lastContent.content().isReadable(), is(false));
    HttpHeaders headers = lastContent.trailingHeaders();
    assertEquals(1, headers.names().size());
    List<String> values = headers.getAll("Set-Cookie");
    assertEquals(2, values.size());
    assertTrue(values.contains("t1=t1v1"));
    assertTrue(values.contains("t2=t2v2; Expires=Wed, 09-Jun-2021 10:18:14 GMT"));
    lastContent.release();

    assertThat(ch.finish(), is(false));
    assertThat(ch.readInbound(), is(nullValue()));
  }
  @Test
  public void testValidInitRequest() throws Exception {

    // Given
    EmbeddedChannel channel = new EmbeddedChannel(new InitRequestHandler());

    InitRequest initRequest =
        new InitRequest(
            42,
            InitMessage.DEFAULT_VERSION,
            new HashMap<String, String>() {
              {
                put(InitMessage.HOST_PORT_KEY, "0.0.0.0:0");
                put(InitMessage.PROCESS_NAME_KEY, "test-process");
              }
            });

    channel.writeInbound(initRequest);
    channel.writeOutbound(channel.readInbound());

    // Then
    InitResponse initResponse = channel.readOutbound();

    // Assert
    assertNotNull(initResponse);
    assertEquals(initRequest.getId(), initResponse.getId());
    assertEquals(initRequest.getVersion(), initResponse.getVersion());
    assertEquals(initRequest.getHostPort(), initResponse.getHostPort());
  }
  @Test
  public void testRemoveItselfWriteBuffer() {
    final ByteBuf buf = Unpooled.buffer().writeBytes(new byte[] {'a', 'b', 'c'});
    EmbeddedChannel channel =
        new EmbeddedChannel(
            new ReplayingDecoder() {
              private boolean removed;

              @Override
              protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
                  throws Exception {
                assertFalse(removed);
                in.readByte();
                ctx.pipeline().remove(this);

                // This should not let it keep call decode
                buf.writeByte('d');
                removed = true;
              }
            });

    channel.writeInbound(buf.copy());
    ByteBuf b = channel.readInbound();
    assertEquals(b, Unpooled.wrappedBuffer(new byte[] {'b', 'c'}));
    b.release();
    buf.release();
  }
  @Test
  public void testWebSocketResponse() {
    byte[] data =
        ("HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
                + "Upgrade: WebSocket\r\n"
                + "Connection: Upgrade\r\n"
                + "Sec-WebSocket-Origin: http://localhost:8080\r\n"
                + "Sec-WebSocket-Location: ws://localhost/some/path\r\n"
                + "\r\n"
                + "1234567812345678")
            .getBytes();
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    ch.writeInbound(Unpooled.wrappedBuffer(data));

    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.SWITCHING_PROTOCOLS));
    HttpContent content = ch.readInbound();
    assertThat(content.content().readableBytes(), is(16));
    content.release();

    assertThat(ch.finish(), is(false));

    assertThat(ch.readInbound(), is(nullValue()));
  }
  @Test
  public void testConnect() {
    StringBuilder builder = new StringBuilder();
    try {
      builder
          .append("환영합니다. ")
          .append(InetAddress.getLocalHost().getHostName())
          .append("에 접속하셨습니다!\r\n")
          .append("현재 시간은 ")
          .append(new Date().toString())
          .append(" 입니다.\r\n");
    } catch (UnknownHostException e) {
      fail();
      e.printStackTrace();
    }

    EmbeddedChannel embeddedChannel = new EmbeddedChannel(new TelnetServerHandlerV3());

    String expected = (String) embeddedChannel.readOutbound();
    assertNotNull(expected);

    assertEquals(builder.toString(), (String) expected);

    String request = "hello";
    expected = "입력하신 명령이 '" + request + "' 입니까?\r\n";

    embeddedChannel.writeInbound(request);

    String response = (String) embeddedChannel.readOutbound();
    assertEquals(expected, response);

    embeddedChannel.finish();
  }
  @Test
  public void testIncorrectProtocolVersion() throws Exception {
    // Given
    EmbeddedChannel channel = new EmbeddedChannel(new InitRequestHandler());

    InitRequest initRequest =
        new InitRequest(
            42,
            1,
            new HashMap<String, String>() {
              {
                put(InitMessage.HOST_PORT_KEY, "0.0.0.0:0");
                put(InitMessage.PROCESS_NAME_KEY, "test-process");
              }
            });

    channel.writeInbound(initRequest);
    ErrorMessage error = channel.readOutbound();
    assertNotNull(error);
    assertThat(error.getType(), is(ErrorType.FatalProtocolError));
    assertThat(error.getMessage(), containsString("version"));

    this.expectedClosedChannelException.expect(ClosedChannelException.class);
    channel.writeOutbound();
  }
  @Test
  public void testRemoveItselfWithReplayError() {
    EmbeddedChannel channel =
        new EmbeddedChannel(
            new ReplayingDecoder() {
              private boolean removed;

              @Override
              protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
                  throws Exception {
                assertFalse(removed);
                ctx.pipeline().remove(this);

                in.readBytes(1000);

                removed = true;
              }
            });

    ByteBuf buf = Unpooled.wrappedBuffer(new byte[] {'a', 'b', 'c'});
    channel.writeInbound(buf.copy());
    ByteBuf b = channel.readInbound();

    assertEquals("Expect to have still all bytes in the buffer", b, buf);
    b.release();
    buf.release();
  }
Exemple #21
0
  private void testCompressNone(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper)
      throws Exception {
    EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));

    // Closing an encoder channel without writing anything should generate both header and footer.
    assertTrue(chEncoder.finish());

    EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
    for (; ; ) {
      ByteBuf deflatedData = chEncoder.readOutbound();
      if (deflatedData == null) {
        break;
      }
      chDecoderZlib.writeInbound(deflatedData);
    }

    // Decoder should not generate anything at all.
    for (; ; ) {
      ByteBuf buf = chDecoderZlib.readInbound();
      if (buf == null) {
        break;
      }

      buf.release();
      fail("should decode nothing");
    }

    assertFalse(chDecoderZlib.finish());
  }
  @Test
  public void testClosureWithoutContentLength2() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());

    // Write the partial response.
    ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.1 200 OK\r\n\r\n12345678", CharsetUtil.US_ASCII));

    // Read the response headers.
    HttpResponse res = ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));

    // Read the partial content.
    HttpContent content = ch.readInbound();
    assertThat(content.content().toString(CharsetUtil.US_ASCII), is("12345678"));
    assertThat(content, is(not(instanceOf(LastHttpContent.class))));
    content.release();

    assertThat(ch.readInbound(), is(nullValue()));

    // Close the connection.
    assertTrue(ch.finish());

    // The decoder should still produce the last content.
    LastHttpContent lastContent = ch.readInbound();
    assertThat(lastContent.content().isReadable(), is(false));
    lastContent.release();

    // But nothing more.
    assertThat(ch.readInbound(), is(nullValue()));
  }
  /**
   * This test makes sure that even when the decoder is confronted with various chunk sizes in the
   * middle of decoding, it can recover and decode all the time eventually.
   */
  @Test
  public void shouldHandleNonUniformNetworkBatches() {
    ByteBuf incoming = Unpooled.copiedBuffer(SET_REQUEST_WITH_CONTENT);
    while (incoming.isReadable()) {
      channel.writeInbound(incoming.readBytes(5));
    }

    BinaryMemcacheRequest request = (BinaryMemcacheRequest) channel.readInbound();

    assertThat(request, notNullValue());
    assertThat(request.getHeader(), notNullValue());
    assertThat(request.getKey(), notNullValue());
    assertThat(request.getExtras(), nullValue());

    request.release();

    MemcacheContent content1 = (MemcacheContent) channel.readInbound();
    MemcacheContent content2 = (MemcacheContent) channel.readInbound();

    assertThat(content1, instanceOf(MemcacheContent.class));
    assertThat(content2, instanceOf(LastMemcacheContent.class));

    assertThat(content1.content().readableBytes(), is(3));
    assertThat(content2.content().readableBytes(), is(5));

    content1.release();
    content2.release();
  }
  @Test
  public void testInboundChainNoChanges() throws Exception {
    List<Interceptor> interceptors = new ArrayList<>();

    MockInterceptor interceptor1 = new MockInterceptor();
    MockInterceptor interceptor2 = new MockInterceptor();

    interceptors.add(interceptor1);
    interceptors.add(interceptor2);

    EmbeddedChannel channel =
        new EmbeddedChannel(
            new ChannelDuplexHandler() {
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                InterceptorChain chain =
                    new InterceptorChain(ctx, interceptors, (ResourceRequest) msg);
                chain.fireInbound();
              }
            });

    ResourceRequest request =
        new DefaultResourceRequest.Builder(RequestType.READ, new ResourcePath("/foo/bar")).build();
    channel.writeInbound(request);

    ResourceRequest endRequest = (ResourceRequest) channel.readInbound();

    assertThat(endRequest).isNotNull();
    assertThat(interceptor1.requests()).hasSize(1);
    assertThat(interceptor1.requests()).contains(request);
    assertThat(interceptor2.requests()).hasSize(1);
    assertThat(interceptor2.requests()).contains(request);
  }
  @Test
  public void testDummyOutgoingAck() {
    ch.writeInbound(Unpooled.wrappedBuffer(new byte[] {(byte) 0x81, (byte) 0xFF, 0x00}));

    UsnIncomingMessage msg = (UsnIncomingMessage) ch.readInbound();
    assertEquals(msg.getMessageType(), DUMMY_OUTGOING_ACK);
  }
  @Test
  public void testDummyIncoming() {
    ch.writeInbound(Unpooled.wrappedBuffer(new byte[] {0x02, (byte) 0xFF, 0x01, 23}));

    UsnIncomingMessage msg = (UsnIncomingMessage) ch.readInbound();
    assertEquals(msg.getMessageType(), DUMMY_INCOMING);
  }
 @Test
 public void testRegularDecode() {
   byte[] b = new byte[2048];
   for (int i = 2; i < 2048; i++) {
     b[i] = 1;
   }
   b[0] = -2;
   b[1] = 15;
   ch.writeInbound(wrappedBuffer(b, 0, 127));
   assertThat(ch.readInbound(), is(nullValue()));
   ch.writeInbound(wrappedBuffer(b, 127, 600));
   assertThat(ch.readInbound(), is(nullValue()));
   ch.writeInbound(wrappedBuffer(b, 727, b.length - 727));
   assertThat(
       releaseLater((ByteBuf) ch.readInbound()),
       is(releaseLater(wrappedBuffer(b, 2, b.length - 2))));
 }
  @Test
  public void testReplacement() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new BloatedLineDecoder());

    // "AB" should be forwarded to LineDecoder by BloatedLineDecoder.
    ch.writeInbound(Unpooled.wrappedBuffer(new byte[] {'A', 'B'}));
    assertNull(ch.readInbound());

    // "C\n" should be appended to "AB" so that LineDecoder decodes it correctly.
    ch.writeInbound(Unpooled.wrappedBuffer(new byte[] {'C', '\n'}));
    assertEquals(
        releaseLater(Unpooled.wrappedBuffer(new byte[] {'A', 'B', 'C'})),
        releaseLater(ch.readInbound()));

    ch.finish();
    assertNull(ch.readInbound());
  }
  @Test
  public void testInitHandlerRemovesItself() throws Exception {

    // Given
    EmbeddedChannel channel = new EmbeddedChannel(new InitRequestHandler());

    assertEquals(3, channel.pipeline().names().size());

    InitRequest initRequest =
        new InitRequest(
            42,
            InitMessage.DEFAULT_VERSION,
            new HashMap<String, String>() {
              {
                put(InitMessage.HOST_PORT_KEY, "0.0.0.0:0");
                put(InitMessage.PROCESS_NAME_KEY, "test-process");
              }
            });

    channel.writeInbound(initRequest);
    channel.writeOutbound(channel.readInbound());

    // Then
    InitResponse initResponse = channel.readOutbound();

    // Assert
    assertNotNull(initResponse);
    assertEquals(initRequest.getId(), initResponse.getId());
    assertEquals(initRequest.getVersion(), initResponse.getVersion());
    assertEquals(initRequest.getHostPort(), initResponse.getHostPort());

    // Assert Pipeline is empty
    assertEquals(2, channel.pipeline().names().size());

    // Make sure Messages are still passed through
    channel.writeInbound(initRequest);
    channel.writeOutbound(channel.readInbound());
    InitRequest sameInitRequest = channel.readOutbound();
    assertEquals(initRequest.getId(), sameInitRequest.getId());
    assertEquals(initRequest.getVersion(), sameInitRequest.getVersion());
    assertEquals(initRequest.getHostPort(), sameInitRequest.getHostPort());
  }
  @Test
  public void testInboundChainShortCircuit() throws Exception {

    List<Interceptor> interceptors = new ArrayList<>();

    ResourceRequest request =
        new DefaultResourceRequest.Builder(RequestType.READ, new ResourcePath("/foo/bar")).build();
    ResourceResponse response =
        new DefaultResourceErrorResponse(request, ResourceErrorResponse.ErrorType.NOT_AUTHORIZED);

    MockInterceptor interceptor1 = new MockInterceptor();
    MockInterceptor interceptor2 =
        new MockInterceptor() {
          @Override
          public void onInbound(InboundInterceptorContext context) throws Exception {
            requests.add(context.request());
            context.replyWith(response);
          }
        };
    MockInterceptor interceptor3 = new MockInterceptor();

    interceptors.add(interceptor1);
    interceptors.add(interceptor2);
    interceptors.add(interceptor3);

    EmbeddedChannel channel =
        new EmbeddedChannel(
            new ChannelDuplexHandler() {
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                InterceptorChain chain =
                    new InterceptorChain(ctx, interceptors, (ResourceRequest) msg);
                chain.fireInbound();
              }
            });

    channel.writeInbound(request);
    ResourceRequest endRequest = (ResourceRequest) channel.readInbound();
    Object endResponse = channel.readOutbound();

    assertThat(endRequest).isNull();

    assertThat(interceptor1.requests()).hasSize(1);
    assertThat(interceptor1.requests()).contains(request);
    assertThat(interceptor2.requests()).hasSize(1);
    assertThat(interceptor2.requests()).contains(request);
    assertThat(interceptor3.requests()).isEmpty();

    assertThat(interceptor3.responses()).isEmpty();
    assertThat(interceptor2.responses()).isEmpty();
    assertThat(interceptor1.responses()).hasSize(1);
    assertThat(interceptor1.responses()).contains(response);
  }