// Decode a 200-byte binary frame
  private void sizeLimitDecodeBinaryFrame(int maxSize) throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, maxSize);

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(204))
            .put((byte) 0x82)
            .put((byte) 126)
            .put((byte) 0x00)
            .put((byte) 0xC8)
            .fill(200)
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsBinaryMessage(allocator.wrap(allocator.allocate(200)).fill(200).flip()), out);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
  // Decode a 12-byte text frame and a 15 byte text frame written in one go (one network packet)
  private void sizeLimitDecodeDoubleTextFrame(int maxSize) throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, maxSize);

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(12 + 2 + 15 + 2))
            .put((byte) 0x81)
            .put((byte) 12)
            .putString("123456789012", UTF_8.newEncoder())
            .put((byte) 0x81)
            .put((byte) 15)
            .putString("123456789012345", UTF_8.newEncoder())
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsTextMessage(allocator.wrap(ByteBuffer.wrap("123456789012".getBytes(UTF_8)))), out);

    WsMessage out2 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsTextMessage(allocator.wrap(ByteBuffer.wrap("123456789012345".getBytes(UTF_8)))),
        out2);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
  @Test
  public void decodeTextFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 0);

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(14))
            .put((byte) 0x81)
            .put((byte) 0x0C)
            .putString("Hello, world", UTF_8.newEncoder())
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsTextMessage(allocator.wrap(ByteBuffer.wrap("Hello, world".getBytes(UTF_8)))), out);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
  @Test
  public void decodeZeroLengthMaskedPongFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 0);

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(6))
            .put((byte) 0x8A)
            .put((byte) 0x80)
            .fill(4) // mask
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsPongMessage(allocator.wrap(allocator.allocate(0)).flip()), out);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
Example #5
0
        @Override
        protected void doSessionClosed(HttpSession createSession) throws Exception {
          final WsebSession wsebSession = WSE_SESSION_KEY.get(createSession);
          assert (wsebSession != null);

          IoBufferEx buf = CREATE_RESPONSE_KEY.remove(createSession);
          if (buf == null || createSession.getStatus() != HttpStatus.SUCCESS_CREATED) {
            throw new IllegalStateException("Create handshake failed: invalid response");
          }

          buf.flip();

          String responseText = buf.getString(UTF_8.newDecoder());
          String[] locations = responseText.split("\n");

          if (locations.length < 2) {
            throw new IllegalStateException("Create handshake failed: invalid response");
          }

          URI writeURI = URI.create(locations[0]);
          URI readURI = URI.create(locations[1]);

          ResourceAddress writeAddress = resourceAddressFactory.newResourceAddress(writeURI);
          ResourceAddress readAddress = resourceAddressFactory.newResourceAddress(readURI);

          if (!wsebSession.isClosing()) {
            wsebSession.setWriteAddress(writeAddress);
            wsebSession.setReadAddress(readAddress);

            sessionMap.put(writeAddress, wsebSession);
            sessionMap.put(readAddress, wsebSession);

            // attach downstream for read
            final BridgeConnector bridgeConnector =
                bridgeServiceFactory.newBridgeConnector(readAddress);
            bridgeConnector.connect(
                readAddress,
                selectReadHandler(readAddress),
                new IoSessionInitializer<ConnectFuture>() {
                  @Override
                  public void initializeSession(IoSession ioSession, ConnectFuture connectFuture) {
                    HttpSession httpSession = (HttpSession) ioSession;
                    httpSession.setWriteHeader(
                        HttpHeaders.HEADER_X_SEQUENCE_NO,
                        Long.toString(wsebSession.nextReaderSequenceNo()));
                  }
                });

            // activate upstream for write
            // TODO: Replace usage of suspendWrite/resumeWrite with a WSEB-specific "send queue"
            // upon which
            // TODO: locking of writes can be achieved.
            wsebSession.resumeWrite();
            // We are always aligned now. if (session.isIoAligned()) {
            wsebSession.getProcessor().flush(wsebSession);
          }
        }
  @Test
  public void decodeTextContinuationFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 200);

    int firstPayload = 125;
    String first = createString('a', firstPayload);

    int secondPayload = 2;
    String second = createString('b', secondPayload);

    int thirdPayload = 4;
    String thrid = createString('c', thirdPayload);

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(firstPayload + secondPayload + thirdPayload + 6))
            // text frame
            .put((byte) 0x01)
            .put((byte) firstPayload)
            .putString(first, UTF_8.newEncoder())
            // continuation frame with FIN
            .put((byte) 0x80)
            .put((byte) secondPayload)
            .putString(second, UTF_8.newEncoder())
            // text frame with FIN
            .put((byte) 0x81)
            .put((byte) thirdPayload)
            .putString(thrid, UTF_8.newEncoder())
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out1 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsTextMessage(allocator.wrap(ByteBuffer.wrap(first.getBytes(UTF_8))), false), out1);

    WsMessage out2 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsContinuationMessage(allocator.wrap(ByteBuffer.wrap(second.getBytes(UTF_8)))), out2);

    WsMessage out3 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsTextMessage(allocator.wrap(ByteBuffer.wrap(thrid.getBytes(UTF_8)))), out3);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
  /** {@inheritDoc} */
  @Override
  public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    IoBufferEx inEx = (IoBufferEx) in;
    if (buffer == null) {
      if (in.remaining() >= length) {
        int limit = in.limit();
        in.limit(in.position() + length);
        IoBufferEx product = inEx.slice();
        in.position(in.position() + length);
        in.limit(limit);
        return finishDecode((IoBuffer) product, out);
      }

      buffer = allocator.wrap(allocator.allocate(length));
      buffer.put(inEx);
      return this;
    }

    if (in.remaining() >= length - buffer.position()) {
      int limit = in.limit();
      in.limit(in.position() + length - buffer.position());
      buffer.put(inEx);
      in.limit(limit);
      buffer.flip();
      IoBufferEx product = buffer;
      buffer = null;
      return finishDecode((IoBuffer) product, out);
    }

    buffer.put(inEx);
    return this;
  }
  @Test
  public void decodeBinaryContinuationFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 200);

    int firstPayload = 125;
    byte[] first = createString('a', firstPayload).getBytes("UTF-8");

    int secondPayload = 2;
    byte[] second = createString('b', secondPayload).getBytes("UTF-8");

    int thirdPayload = 4;
    byte[] thrid = createString('c', thirdPayload).getBytes("UTF-8");

    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(firstPayload + secondPayload + thirdPayload + 6))
            // binary frame
            .put((byte) 0x02)
            .put((byte) firstPayload)
            .put(first)
            // continuation frame with FIN
            .put((byte) 0x80)
            .put((byte) secondPayload)
            .put(second)
            // binary frame with FIN
            .put((byte) 0x82)
            .put((byte) thirdPayload)
            .put(thrid)
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out1 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsBinaryMessage(allocator.wrap(ByteBuffer.wrap(first)), false), out1);

    WsMessage out2 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsContinuationMessage(allocator.wrap(ByteBuffer.wrap(second))), out2);

    WsMessage out3 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsBinaryMessage(allocator.wrap(ByteBuffer.wrap(thrid))), out3);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }
Example #9
0
        @Override
        protected void doMessageReceived(HttpSession createSession, Object message)
            throws Exception {
          // Handle fragmentation of response body
          IoBufferEx in = (IoBufferEx) message;

          IoBufferEx buf = CREATE_RESPONSE_KEY.get(createSession);
          if (buf == null) {
            IoBufferAllocatorEx<?> allocator = createSession.getBufferAllocator();
            buf = allocator.wrap(allocator.allocate(in.remaining())).setAutoExpander(allocator);
            CREATE_RESPONSE_KEY.set(createSession, buf);
          }

          buf.put(in);
        }
  @Test
  public void decodeFragmentedBinaryFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 0);

    IoBufferEx[] array =
        new IoBufferEx[] {
          allocator
              .wrap(allocator.allocate(104))
              .put((byte) 0x82)
              .put((byte) 126)
              .put((byte) 0x00)
              .put((byte) 0xC8)
              .fill(100)
              .flip(),
          allocator
              .wrap(allocator.allocate(102))
              .fill(100)
              .put((byte) 0x82)
              .put((byte) 0x00)
              .flip(),
        };

    for (IoBufferEx in : array) {
      decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());
    }

    WsMessage fragmented = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsBinaryMessage(allocator.wrap(allocator.allocate(200)).fill(200).flip()), fragmented);

    WsMessage empty = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsBinaryMessage(allocator.wrap(allocator.allocate(0))), empty);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());

    for (IoBufferEx in : array) {
      assertFalse(in.hasRemaining());
    }
  }
  @Test
  public void decodeFragmentedTextFrame() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 0);

    IoBufferEx[] array =
        new IoBufferEx[] {
          allocator
              .wrap(allocator.allocate(103))
              .put((byte) 0x81)
              .put((byte) 0x0C)
              .putString("Hello", UTF_8.newEncoder())
              .flip(),
          allocator
              .wrap(allocator.allocate(102))
              .putString(", world", UTF_8.newEncoder())
              .put((byte) 0x81)
              .put((byte) 0x00)
              .flip(),
        };

    for (IoBufferEx in : array) {
      decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());
    }

    WsMessage fragmented = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsTextMessage(allocator.wrap(ByteBuffer.wrap("Hello, world".getBytes(UTF_8)))),
        fragmented);

    WsMessage empty = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsTextMessage(allocator.wrap(allocator.allocate(0))), empty);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());

    for (IoBufferEx in : array) {
      assertFalse(in.hasRemaining());
    }
  }
 /** {@inheritDoc} */
 @Override
 public DecodingState finishDecode(ProtocolDecoderOutput out) throws Exception {
   IoBufferEx readData;
   if (buffer == null) {
     readData = allocator.wrap(allocator.allocate(0));
   } else {
     buffer.flip();
     readData = buffer;
     buffer = null;
   }
   return finishDecode((IoBuffer) readData, out);
 }
  // Make sure we fail early for case of large text messages: we should fail as soon as we process
  // a network packet that exceeds the limit (2nd packet in this case)
  @Test(expected = ProtocolDecoderException.class)
  public void sizeLimitDecodeTextFrameFailEarly2() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 20);

    int dataSize = 30;
    StringBuilder data = new StringBuilder(dataSize);
    for (int i = 0; i < (dataSize); i++) {
      data.append((i % 10));
    }
    IoBufferEx in =
        allocator
            .wrap(allocator.allocate(dataSize + 2))
            .put((byte) 0x81)
            .put((byte) 30)
            .putString(data.toString(), UTF_8.newEncoder())
            .flip();
    decoder.decode(session, (IoBuffer) in.getSlice(10), session.getDecoderOutput());
    // Now if we send the next 12 bytes that should exceed the limit (first byte is control byte,
    // doesn't count)
    decoder.decode(session, (IoBuffer) in.getSlice(12), session.getDecoderOutput());
  }
  @Test
  public void pingInBinaryContinuationSequence() throws Exception {
    ProtocolCodecSessionEx session = new ProtocolCodecSessionEx();
    IoBufferAllocatorEx<?> allocator = session.getBufferAllocator();
    ProtocolDecoder decoder = new WsFrameDecoder(allocator, 400);

    int firstPayload = 125;
    byte[] first = createString('a', firstPayload).getBytes("UTF-8");

    int secondPayload = 125;
    byte[] second = createString('b', secondPayload).getBytes("UTF-8");

    int thirdPayload = 4;
    byte[] third = createString('c', thirdPayload).getBytes("UTF-8");

    int fourthPayload = 6;
    String fourth = createString('d', fourthPayload);

    IoBufferEx in =
        allocator
            .wrap(
                allocator.allocate(
                    firstPayload + secondPayload + 2 + thirdPayload + fourthPayload + 8))
            // text frame
            .put((byte) 0x01)
            .put((byte) firstPayload)
            .put(first)
            // continuation frame
            .put((byte) 0x00)
            .put((byte) secondPayload)
            .put(second)
            // ping frame
            .put((byte) 0x89)
            .put((byte) 0x00)
            // continuation frame with FIN
            .put((byte) 0x80)
            .put((byte) thirdPayload)
            .put(third)
            // binary frame
            .put((byte) 0x82)
            .put((byte) fourthPayload)
            .putString(fourth, UTF_8.newEncoder())
            .flip();

    decoder.decode(session, (IoBuffer) in, session.getDecoderOutput());

    WsMessage out1 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsTextMessage(allocator.wrap(ByteBuffer.wrap(first)), false), out1);

    WsMessage out2 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsContinuationMessage(allocator.wrap(ByteBuffer.wrap(second)), false), out2);

    WsMessage out = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsPingMessage(allocator.wrap(allocator.allocate(0))), out);

    WsMessage out3 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(new WsContinuationMessage(allocator.wrap(ByteBuffer.wrap(third))), out3);

    WsMessage out4 = (WsMessage) session.getDecoderOutputQueue().poll();
    assertEquals(
        new WsBinaryMessage(allocator.wrap(ByteBuffer.wrap(fourth.getBytes(UTF_8)))), out4);

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    decoder.finishDecode(session, session.getDecoderOutput());

    assertTrue(session.getDecoderOutputQueue().isEmpty());
    assertFalse(in.hasRemaining());
  }