Exemplo n.º 1
0
  protected void sendMessage(byte[] aMessage, MessageOpCode aOpCode) {
    if (!isClosing()) {
      int messageLength = aMessage.length;
      if (messageLength <= getMaxPayloadSize()) {
        // create and send fragment
        WebSocketFragment fragment = new WebSocketFragment(aOpCode, true, sendWithMask(), aMessage);
        sendMessage(fragment);
      } else {
        List<WebSocketFragment> fragments = new ArrayList<WebSocketFragment>();
        int fragmentCount = messageLength / getMaxPayloadSize();
        if (messageLength % getMaxPayloadSize() > 0) {
          fragmentCount++;
        }

        // build fragments
        for (int i = 0; i < fragmentCount; i++) {
          WebSocketFragment fragment = null;
          int fragmentLength = getMaxPayloadSize();
          if (i == 0) {
            fragment =
                new WebSocketFragment(
                    aOpCode,
                    false,
                    sendWithMask(),
                    WebSocketUtil.copySubArray(aMessage, i * getMaxPayloadSize(), fragmentLength));
          } else if (i == fragmentCount - 1) {
            fragmentLength = messageLength % getMaxPayloadSize();
            if (fragmentLength == 0) {
              fragmentLength = getMaxPayloadSize();
            }
            fragment =
                new WebSocketFragment(
                    MessageOpCode.CONTINUATION,
                    true,
                    sendWithMask(),
                    WebSocketUtil.copySubArray(aMessage, i * getMaxPayloadSize(), fragmentLength));
          } else {
            fragment =
                new WebSocketFragment(
                    MessageOpCode.CONTINUATION,
                    false,
                    sendWithMask(),
                    WebSocketUtil.copySubArray(aMessage, i * getMaxPayloadSize(), fragmentLength));
          }
          fragments.add(fragment);
        }
        // send fragments
        for (WebSocketFragment fragment : fragments) {
          sendMessage(fragment);
        }
      }
    }
  }
Exemplo n.º 2
0
  protected void handleMessageData(byte[] aData) {
    // grab last fragment, use if not complete
    WebSocketFragment fragment = pendingFragments.peek();
    if (fragment == null || fragment.isValid()) {
      // assign web socket fragment since the last one was complete
      fragment = new WebSocketFragment(aData);

      pendingFragments.offer(fragment);
    } else if (fragment != null) {
      fragment.appendFragment(aData);
      if (fragment.canBeParsed()) {
        fragment.parseContent();
      }
    }

    // if we have a complete fragment, handle it
    if (fragment.isValid()) {
      // handle complete fragment
      handleCompleteFragment(fragment);

      // if we have extra data, handle it
      if (aData.length > fragment.getMessageLength()) {
        handleMessageData(
            WebSocketUtil.copySubArray(
                aData, fragment.getMessageLength(), aData.length - fragment.getMessageLength()));
      }
    }
  }
Exemplo n.º 3
0
  protected void handleClose(WebSocketFragment aFragment) {
    // parse close message
    boolean hasInvalidUtf8 = false;

    try {
      byte[] data = aFragment.getPayloadData();
      if (data != null) {
        if (data.length >= 2) {
          closeStatus = WebSocketUtil.convertBytesToShort(data, 0);
          if (data.length > 2) {
            closeMessage =
                convertFromBytesToString(WebSocketUtil.copySubArray(data, 2, data.length - 2));
          }
        }
      }
    } catch (CharacterCodingException e) {
      logger.error("An error occurred while decoding from UTF8 to get text in close message.", e);
      sendErrorToObserver(e);
      hasInvalidUtf8 = true;
    }

    // actually close
    if (isClosing()) {
      closeSocket();
    } else {
      setClosing(true);
      if (hasInvalidUtf8) {
        close(WebSocketCloseStatusInvalidUtf8, null);
      } else {
        close(0, null);
      }
    }
  }
Exemplo n.º 4
0
 public void parseContent() {
   if (getFragment() != null && getFragment().length >= getPayloadStart() + getPayloadLength()) {
     // set payload
     if (hasMask()) {
       setPayloadData(
           WebSocketFragment.unmask(
               getMask(), getFragment(), getPayloadStart(), getPayloadLength()));
     } else {
       setPayloadData(
           WebSocketUtil.copySubArray(getFragment(), getPayloadStart(), getPayloadLength()));
     }
   }
 }
Exemplo n.º 5
0
  public boolean parseHeader(byte[] aData, int aOffset) {
    // get header data bits
    int bufferLength = 14;

    byte[] data = aData;

    // do we have an existing fragment to work with
    if (getFragment() != null) {
      if (getFragment().length >= bufferLength) {
        data = getFragment();
      } else {
        byte[] both;
        if ((aData != null ? aData.length : 0) - aOffset >= bufferLength - getFragment().length) {
          both =
              WebSocketUtil.appendPartialArray(
                  getFragment(), aData, aOffset, bufferLength - getFragment().length);
        } else {
          both = WebSocketUtil.appendArray(getFragment(), aData);
        }
        data = both;
      }
    }

    if (data != null && data.length - aOffset < bufferLength) {
      bufferLength = data.length - aOffset;
    }
    if (bufferLength < 0 || data == null) {
      return false;
    }
    byte[] buffer = WebSocketUtil.copySubArray(data, 0, bufferLength);

    // determine opcode
    if (bufferLength > 0) {
      int index = 0;
      setFinal((buffer[index] & 0x80) != 0);
      setRSV1((buffer[index] & 0x40) != 0);
      setRSV2((buffer[index] & 0x20) != 0);
      setRSV3((buffer[index] & 0x20) != 0);
      setOpCode(buffer[index++] & 0x0F);

      // handle data depending on opcode
      switch (getOpCode()) {
        case TEXT:
          setPayloadType(PayloadType.TEXT);
          break;
        case BINARY:
          setPayloadType(PayloadType.BINARY);
          break;
      }

      // handle content, if any
      if (bufferLength > 1) {
        // do we have a mask
        boolean hasMask = (buffer[index] & 0x80) != 0;

        // get payload length
        Long dataLength = new Integer(buffer[index++] & 0x7F).longValue();
        if (dataLength == 126) {
          // exit if we are missing bytes
          if (bufferLength < 4) {
            return false;
          }

          dataLength = new Integer(WebSocketUtil.convertBytesToShort(buffer, index)).longValue();
          index += 2;
        } else if (dataLength == 127) {
          // exit if we are missing bytes
          if (bufferLength < 10) {
            return false;
          }

          dataLength = WebSocketUtil.convertBytesToLong(buffer, index);
          index += 8;
        }

        // if applicable, set mask value
        if (hasMask) {
          // exit if we are missing bytes
          if (bufferLength < index + 4) {
            return false;
          }

          // grab mask
          setMask(WebSocketUtil.convertBytesToInt(buffer, index));
          index += 4;
        }

        payloadStart = index;
        if (dataLength > Integer.MAX_VALUE) {
          throw new IllegalArgumentException(
              "Implementation does not support payload lengths in excess of "
                  + Integer.MAX_VALUE
                  + ": "
                  + dataLength);
        }
        payloadLength = dataLength.intValue();
        return true;
      }
    }

    return false;
  }