예제 #1
0
 public WsFrameBase(WsSession wsSession, Transformation transformation) {
   inputBuffer = new byte[Constants.DEFAULT_BUFFER_SIZE];
   messageBufferBinary = ByteBuffer.allocate(wsSession.getMaxBinaryMessageBufferSize());
   messageBufferText = CharBuffer.allocate(wsSession.getMaxTextMessageBufferSize());
   this.wsSession = wsSession;
   Transformation finalTransformation;
   if (isMasked()) {
     finalTransformation = new UnmaskTransformation();
   } else {
     finalTransformation = new NoopTransformation();
   }
   if (transformation == null) {
     this.transformation = finalTransformation;
   } else {
     transformation.setNext(finalTransformation);
     this.transformation = transformation;
   }
 }
예제 #2
0
  /**
   * @return <code>true</code> if sufficient data was present to process all of the initial header
   */
  private boolean processInitialHeader() throws IOException {
    // Need at least two bytes of data to do this
    if (writePos - readPos < 2) {
      return false;
    }
    int b = inputBuffer[readPos++];
    fin = (b & 0x80) > 0;
    rsv = (b & 0x70) >>> 4;
    opCode = (byte) (b & 0x0F);
    if (!transformation.validateRsv(rsv, opCode)) {
      throw new WsIOException(
          new CloseReason(
              CloseCodes.PROTOCOL_ERROR,
              sm.getString("wsFrame.wrongRsv", Integer.valueOf(rsv), Integer.valueOf(opCode))));
    }

    if (Util.isControl(opCode)) {
      if (!fin) {
        throw new WsIOException(
            new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.controlFragmented")));
      }
      if (opCode != Constants.OPCODE_PING
          && opCode != Constants.OPCODE_PONG
          && opCode != Constants.OPCODE_CLOSE) {
        throw new WsIOException(
            new CloseReason(
                CloseCodes.PROTOCOL_ERROR,
                sm.getString("wsFrame.invalidOpCode", Integer.valueOf(opCode))));
      }
    } else {
      if (continuationExpected) {
        if (!Util.isContinuation(opCode)) {
          throw new WsIOException(
              new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.noContinuation")));
        }
      } else {
        try {
          if (opCode == Constants.OPCODE_BINARY) {
            // New binary message
            textMessage = false;
            int size = wsSession.getMaxBinaryMessageBufferSize();
            if (size != messageBufferBinary.capacity()) {
              messageBufferBinary = ByteBuffer.allocate(size);
            }
            binaryMsgHandler = wsSession.getBinaryMessageHandler();
            textMsgHandler = null;
          } else if (opCode == Constants.OPCODE_TEXT) {
            // New text message
            textMessage = true;
            int size = wsSession.getMaxTextMessageBufferSize();
            if (size != messageBufferText.capacity()) {
              messageBufferText = CharBuffer.allocate(size);
            }
            binaryMsgHandler = null;
            textMsgHandler = wsSession.getTextMessageHandler();
          } else {
            throw new WsIOException(
                new CloseReason(
                    CloseCodes.PROTOCOL_ERROR,
                    sm.getString("wsFrame.invalidOpCode", Integer.valueOf(opCode))));
          }
        } catch (IllegalStateException ise) {
          // Thrown if the session is already closed
          throw new WsIOException(
              new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.sessionClosed")));
        }
      }
      continuationExpected = !fin;
    }
    b = inputBuffer[readPos++];
    // Client data must be masked
    if ((b & 0x80) == 0 && isMasked()) {
      throw new WsIOException(
          new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.notMasked")));
    }
    payloadLength = b & 0x7F;
    state = State.PARTIAL_HEADER;
    return true;
  }