org.tio.core.exception.AioDecodeException Java Examples

The following examples show how to use org.tio.core.exception.AioDecodeException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractAioHandler.java    From md_blockchain with Apache License 2.0 5 votes vote down vote up
/**
 * 解码:把接收到的ByteBuffer,解码成应用可以识别的业务消息包
 * 消息头:type + bodyLength
 * 消息体:byte[]
 */
@Override
public BlockPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException {
    int readableLength = buffer.limit() - buffer.position();
    if (readableLength < BlockPacket.HEADER_LENGTH) {
        return null;
    }

    //消息类型
    byte type = buffer.get();

    int bodyLength = buffer.getInt();

    if (bodyLength < 0) {
        throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext
	.getClientNode());
    }

    int neededLength = BlockPacket.HEADER_LENGTH + bodyLength;
    int test = readableLength - neededLength;
    // 不够消息体长度(剩下的buffer组不了消息体)
    if (test < 0) {
        return null;
    }
    BlockPacket imPacket = new BlockPacket();
    imPacket.setType(type);
    if (bodyLength > 0) {
        byte[] dst = new byte[bodyLength];
        buffer.get(dst);
        imPacket.setBody(dst);
    }
    return imPacket;
}
 
Example #2
Source File: BaseAioHandler.java    From blockchain with Apache License 2.0 5 votes vote down vote up
/**
 * 解码:把接收到的ByteBuffer,解码成应用可以识别的业务消息包
 * 总的消息结构:消息头 + 消息类别 + 消息体
 * 消息头结构:    4个字节,存储消息体的长度
 * 消息类别: 1 个字节, 存储类别,S => 字符串, B => 区块, T => 交易
 * 消息体结构:   对象的json串的byte[]
 */
public MessagePacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException {

	int readableLength = buffer.limit() - buffer.position();
	//收到的数据组不了业务包,则返回null以告诉框架数据不够
	if (readableLength < MessagePacket.HEADER_LENGTH) {
		return null;
	}
	//读取消息类别
	byte messageType = buffer.get();
	//读取消息体的长度
	int bodyLength = buffer.getInt();

	//数据不正确,则抛出AioDecodeException异常
	if (bodyLength < 0) {
		throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
	}
	//计算本次需要的数据长度
	int neededLength = MessagePacket.HEADER_LENGTH + bodyLength;
	//收到的数据是否足够组包
	int isDataEnough = readableLength - neededLength;
	// 不够消息体长度(剩下的buffe组不了消息体)
	if (isDataEnough < 0) {
		return null;
	} else //组包成功
	{
		MessagePacket imPacket = new MessagePacket();
		imPacket.setType(messageType);
		if (bodyLength > 0) {
			byte[] dst = new byte[bodyLength];
			buffer.get(dst);
			imPacket.setBody(dst);
		}
		return imPacket;
	}
}
 
Example #3
Source File: HttpResponseDecoder.java    From t-io with Apache License 2.0 5 votes vote down vote up
/**
 * 先粗暴地简单解析一下
 * @param httpResponse
 * @param bodyBytes
 * @param channelContext
 * @throws AioDecodeException
 * @author tanyaowu
 */
private static void parseBody(ClientHttpResponse httpResponse, byte[] bodyBytes, ChannelContext channelContext) throws AioDecodeException {
	if (bodyBytes != null) {
		try {
			httpResponse.setBodyString(new String(bodyBytes, "utf-8"));
		} catch (UnsupportedEncodingException e) {
			log.error(e.toString(), e);
		}
	}
}
 
Example #4
Source File: HttpServerAioHandler.java    From t-io with Apache License 2.0 5 votes vote down vote up
@Override
public HttpRequest decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
	HttpRequest request = HttpRequestDecoder.decode(buffer, limit, position, readableLength, channelContext, httpConfig);
	if (request != null) {
		channelContext.setAttribute(REQUEST_KEY, request);
	}
	return request;
}
 
Example #5
Source File: FlashPolicyServerAioHandler.java    From t-io with Apache License 2.0 5 votes vote down vote up
/**
 * <policy-file-request/>
 * @param buffer
 * @param channelContext
 * @return
 * @throws AioDecodeException
 * @author tanyaowu
 */
@Override
public FlashPolicyPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
	//收到的数据组不了业务包,则返回null以告诉框架数据不够
	if (readableLength < FlashPolicyPacket.MIN_LENGHT) {
		return null;
	}

	String line = null;

	try {
		line = ByteBufferUtils.readString(buffer, Const.CHARSET, '\0', FlashPolicyPacket.MAX_LING_LENGHT);
	} catch (LengthOverflowException e) {
		throw new AioDecodeException(e);
	}

	if (line == null) {
		return null;
	} else {
		log.info("收到消息:{}", line);
		if (REQUEST_STR.equalsIgnoreCase(line)) {
			return FlashPolicyPacket.REQUEST;
		} else {
			throw new AioDecodeException("");
		}
	}
}
 
Example #6
Source File: TioRpcServerEndpoint.java    From nutzcloud with Apache License 2.0 5 votes vote down vote up
@Override
public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
    if (readableLength < HEADER_LENGHT)
        return null;
    // 读取消息体的长度
    int bodyLength = buffer.getInt();

    // 数据不正确,则抛出AioDecodeException异常
    if (bodyLength < 2) {
        throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
    }

    // 计算本次需要的数据长度
    int neededLength = HEADER_LENGHT + bodyLength;
    // 收到的数据是否足够组包
    int isDataEnough = readableLength - neededLength;
    // 不够消息体长度(剩下的buffe组不了消息体)
    if (isDataEnough < 0) {
        return null;
    } else // 组包成功
    {
        LiteRpcPacket rpcPacket = new LiteRpcPacket();
        // 版本信息占一个字节
        byte version = buffer.get();
        if (version != 1) {}
        // 操作类型占一个字节
        rpcPacket.opType = buffer.get();
        if (rpcPacket.opType == OP_PING) {
            // 心跳包没有剩余信息,清除多余的body,返回null
            if (bodyLength > 2)
                buffer.clear();
            return null;
        }
        byte[] dst = new byte[bodyLength - 2];
        buffer.get(dst);
        // log.debug(Lang.fixedHexString(dst));
        rpcPacket.setBody(dst);
        return rpcPacket;
    }
}
 
Example #7
Source File: HttpResponseDecoder.java    From t-io with Apache License 2.0 4 votes vote down vote up
/**
   * @param buffer
   * @param limit
   * @param position
   * @param readableLength
   * @param channelContext
   * @return
   * @throws AioDecodeException
   * @author tanyaowu
   */
  public static HttpResponse decode(
      ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext)
      throws AioDecodeException {
    Map<String, String> headers = new HashMap<>();
    int contentLength = 0;
    byte[] bodyBytes = null;
    StringBuilder headerSb = null; // new StringBuilder(512);
    ResponseLine firstLine = null;
    boolean appendRequestHeaderString = true;

    if (appendRequestHeaderString) {
      headerSb = new StringBuilder(512);
    }

    // request line connect
    firstLine = parseResponseLine(buffer, channelContext);
    if (firstLine == null) {
      return null;
    }
    // request line end

    // request header connect
    boolean headerCompleted = parseHeaderLine(buffer, headers, 0);
    if (!headerCompleted) {
      return null;
    }
    String contentLengthStr = headers.get(HttpConst.ResponseHeaderKey.Content_Length);

    if (StrUtil.isBlank(contentLengthStr)) {
      contentLength = 0;
    } else {
      contentLength = Integer.parseInt(contentLengthStr);
    }

    int headerLength = (buffer.position() - position);
    int allNeedLength = headerLength + contentLength; // 这个packet所需要的字节长度(含头部和体部)

    if (readableLength < allNeedLength) {
      channelContext.setPacketNeededLength(allNeedLength);
      return null;
    }
    // request header end

    // ----------------------------------------------- request body connect

    HttpResponse httpResponse = new HttpResponse();
    //    httpResponse.setChannelContext(channelContext);
    //		httpResponse.setHttpConfig((HttpConfig)
    // channelContext.tioConfig.getAttribute(TioConfigKey.HTTP_SERVER_CONFIG));

    if (appendRequestHeaderString) {
      httpResponse.setHeaderString(headerSb.toString());
    } else {
      httpResponse.setHeaderString("");
    }

    //    httpResponse.setResponseLine(firstLine);
    httpResponse.setStatus(HttpResponseStatus.getHttpStatus(firstLine.status));
    httpResponse.addHeaders(
        headers.entrySet().stream()
            .collect(
                Collectors.toMap(
                    entry -> HeaderName.from(entry.getKey()),
                    entry -> HeaderValue.from(entry.getValue()))));
//    httpResponse.setContentLength(contentLength);
    String connection = headers.get(HttpConst.ResponseHeaderKey.Connection);
    if (connection != null) {
//      httpResponse.setConnection(connection.toLowerCase());
    }

    if (contentLength == 0) {
      //			if (StrUtil.isNotBlank(firstLine.getQuery())) {
      //				decodeParams(httpResponse.getParams(), firstLine.getQuery(), httpResponse.getCharset(),
      // channelContext);
      //			}
    } else {
      bodyBytes = new byte[contentLength];
      buffer.get(bodyBytes);
      httpResponse.setBody(bodyBytes);
      // 解析消息体
      parseBody(httpResponse, bodyBytes, channelContext);
    }
    // ----------------------------------------------- request body end

    return httpResponse;
  }
 
Example #8
Source File: WsClientDecoder.java    From t-io with Apache License 2.0 4 votes vote down vote up
public static WsResponse decode(ByteBuffer buf, ChannelContext channelContext)
    throws AioDecodeException {
  // 第一阶段解析
  int initPosition = buf.position();
  int readableLength = buf.limit() - initPosition;

  int headLength = WsPacket.MINIMUM_HEADER_LENGTH;

  if (readableLength < headLength) {
    return null;
  }

  byte first = buf.get();
  //		int b = first & 0xFF; //转换成32位
  boolean fin = (first & 0x80) > 0; // 得到第8位 10000000>0
  @SuppressWarnings("unused")
  int rsv = (first & 0x70) >>> 4; // 得到5、6、7 为01110000 然后右移四位为00000111
  byte opCodeByte = (byte) (first & 0x0F); // 后四位为opCode 00001111
  Opcode opcode = Opcode.valueOf(opCodeByte);
  if (opcode == Opcode.CLOSE) {
    //			Tio.remove(channelContext, "收到opcode:" + opcode);
    //			return null;
  }

  byte second = buf.get(); // 向后读取一个字节
  boolean hasMask =
      (second & 0xFF) >> 7
          == 1; // 用于标识PayloadData是否经过掩码处理。如果是1,Masking-key域的数据即是掩码密钥,用于解码PayloadData。客户端发出的数据帧需要进行掩码处理,所以此位是1。

  // Client data must be masked
  if (!hasMask) { // 第9为为mask,必须为1
    // throw new AioDecodeException("websocket client data must be masked");
  } else {
    headLength += 4;
  }
  int payloadLength = second & 0x7F; // 读取后7位  Payload legth,如果<126则payloadLength

  byte[] mask = null;
  if (payloadLength == 126) { // 为126读2个字节,后两个字节为payloadLength
    headLength += 2;
    if (readableLength < headLength) {
      return null;
    }
    payloadLength = ByteBufferUtils.readUB2WithBigEdian(buf);
    log.info("{} payloadLengthFlag: 126,payloadLength {}", channelContext, payloadLength);

  } else if (payloadLength == 127) { // 127读8个字节,后8个字节为payloadLength
    headLength += 8;
    if (readableLength < headLength) {
      return null;
    }

    payloadLength = (int) buf.getLong();
    log.info("{} payloadLengthFlag: 127,payloadLength {}", channelContext, payloadLength);
  }

  if (payloadLength < 0 ) {
    throw new AioDecodeException("body length(" + payloadLength + ") is not right");
  }

  if (readableLength < headLength + payloadLength) {
    return null;
  }

  if (hasMask) {
    mask = ByteBufferUtils.readBytes(buf, 4);
  }

  // 第二阶段解析
  WsResponse websocketPacket = new WsResponse();
  websocketPacket.setWsEof(fin);
  websocketPacket.setWsHasMask(hasMask);
  websocketPacket.setWsMask(mask);
  websocketPacket.setWsOpcode(opcode);
  websocketPacket.setWsBodyLength(payloadLength);

  if (payloadLength == 0) {
    return websocketPacket;
  }

  byte[] array = ByteBufferUtils.readBytes(buf, payloadLength);
  if (hasMask) {
    for (int i = 0; i < array.length; i++) {
      array[i] = (byte) (array[i] ^ mask[i % 4]);
    }
  }

  websocketPacket.setBody(array);
  return websocketPacket;
}
 
Example #9
Source File: HttpClientAioHandler.java    From t-io with Apache License 2.0 4 votes vote down vote up
@Override
public ClientHttpResponse decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
	ClientHttpResponse response = HttpResponseDecoder.decode(buffer, limit, position, readableLength, channelContext);
	channelContext.setAttribute(RESPONSE_KEY, response);
	return response;
}
 
Example #10
Source File: HttpResponseDecoder.java    From t-io with Apache License 2.0 4 votes vote down vote up
/**
 * 
 * @param buffer
 * @param limit
 * @param position
 * @param readableLength
 * @param channelContext
 * @return
 * @throws AioDecodeException
 * @author tanyaowu
 */
public static ClientHttpResponse decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
	//		int initPosition = position;
	//		int receivedCount = 0;
	//		Step step = Step.firstline;
	//		StringBuilder currLine = new StringBuilder();
	Map<String, String> headers = new HashMap<>();
	int contentLength = 0;
	byte[] bodyBytes = null;
	StringBuilder headerSb = null;//new StringBuilder(512);
	ResponseLine firstLine = null;
	boolean appendRequestHeaderString = true;

	if (appendRequestHeaderString) {
		headerSb = new StringBuilder(512);
	}

	// request line start
	firstLine = parseResponseLine(buffer, channelContext);
	if (firstLine == null) {
		return null;
	}
	// request line end

	// request header start
	boolean headerCompleted = parseHeaderLine(buffer, headers, 0);
	if (!headerCompleted) {
		return null;
	}
	String contentLengthStr = headers.get(HttpConst.ResponseHeaderKey.Content_Length);

	if (StrUtil.isBlank(contentLengthStr)) {
		contentLength = 0;
	} else {
		contentLength = Integer.parseInt(contentLengthStr);
	}

	int headerLength = (buffer.position() - position);
	int allNeedLength = headerLength + contentLength; //这个packet所需要的字节长度(含头部和体部)

	if (readableLength < allNeedLength) {
		channelContext.setPacketNeededLength(allNeedLength);
		return null;
	}
	// request header end

	// ----------------------------------------------- request body start

	ClientHttpResponse httpResponse = new ClientHttpResponse();
	httpResponse.setChannelContext(channelContext);
	//		httpResponse.setHttpConfig((HttpConfig) channelContext.tioConfig.getAttribute(TioConfigKey.HTTP_SERVER_CONFIG));

	if (appendRequestHeaderString) {
		httpResponse.setHeaderString(headerSb.toString());
	} else {
		httpResponse.setHeaderString("");
	}

	httpResponse.setResponseLine(firstLine);
	httpResponse.setHeaders(headers);
	httpResponse.setContentLength(contentLength);
	String connection = headers.get(HttpConst.ResponseHeaderKey.Connection);
	if (connection != null) {
		httpResponse.setConnection(connection.toLowerCase());
	}

	if (contentLength == 0) {
		//			if (StrUtil.isNotBlank(firstLine.getQuery())) {
		//				decodeParams(httpResponse.getParams(), firstLine.getQuery(), httpResponse.getCharset(), channelContext);
		//			}
	} else {
		bodyBytes = new byte[contentLength];
		buffer.get(bodyBytes);
		httpResponse.setBody(bodyBytes);
		//解析消息体
		parseBody(httpResponse, bodyBytes, channelContext);
	}
	// ----------------------------------------------- request body end

	return httpResponse;

}
 
Example #11
Source File: HttpMultiBodyDecoder.java    From t-io with Apache License 2.0 4 votes vote down vote up
/**
 * 【
 * Content-Disposition: form-data; name="uploadFile"; filename=""
 * Content-Type: application/octet-stream
 * 】
 *
 * 【
 * Content-Disposition: form-data; name="end"
 * 】
 * @param lines
 * @param header
 * @author tanyaowu
 */
public static void parseHeader(List<String> lines, Header header, ChannelContext channelContext) throws AioDecodeException {
	if (lines == null || lines.size() == 0) {
		throw new AioDecodeException("multipart_form_data 格式不对,没有头部信息");
	}

	try {
		for (String line : lines) {
			String[] keyvalue = line.split(":");
			String key = StrUtil.trim(keyvalue[0]).toLowerCase();//
			String value = StrUtil.trim(keyvalue[1]);
			header.map.put(key, value);
		}

		String contentDisposition = header.map.get(MultiBodyHeaderKey.Content_Disposition);
		String name = HttpParseUtils.getSubAttribute(contentDisposition, "name");//.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Disposition, "value");
		String filename = HttpParseUtils.getSubAttribute(contentDisposition, "filename");//HttpParseUtils.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Disposition, "filename");
		String contentType = header.map.get(MultiBodyHeaderKey.Content_Type);//.HttpParseUtils.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Type, "filename");

		header.setContentDisposition(contentDisposition);
		header.setName(name);
		header.setFilename(filename);
		header.setContentType(contentType);

	} catch (Throwable e) {
		log.error(channelContext.toString(), e);
		throw new AioDecodeException(e.toString());
	}

	//		for (int i = 0; i < lines.size(); i++) {
	//			String line = lines.get(i);
	//			if (i == 0) {
	//				String[] mapStrings = StrUtil.split(line, ";");
	//				String s = mapStrings[0];//
	//
	//				String[] namekeyvalue = StrUtil.split(mapStrings[1], "=");
	//				header.setName(namekeyvalue[1].substring(1, namekeyvalue[1].length() - 1));
	//
	//				if (mapStrings.length == 3) {
	//					String[] finenamekeyvalue = StrUtil.split(mapStrings[2], "=");
	//					String filename = finenamekeyvalue[1].substring(1, finenamekeyvalue[1].length() - 1);
	//					header.setFilename(FilenameUtils.getName(filename));
	//				}
	//			} else if (i == 1) {
	//				String[] map = StrUtil.split(line, ":");
	//				String contentType = map[1].trim();//
	//				header.setContentType(contentType);
	//			}
	//		}
}
 
Example #12
Source File: HttpResponseDecoder.java    From t-io with Apache License 2.0 3 votes vote down vote up
/**
 * 先粗暴地简单解析一下
 *
 * @param httpResponse
 * @param bodyBytes
 * @param channelContext
 * @throws AioDecodeException
 * @author tanyaowu
 */
private static void parseBody(
    HttpResponse httpResponse, byte[] bodyBytes, ChannelContext channelContext)
    throws AioDecodeException {
  if (bodyBytes != null) {
	httpResponse.setBody(bodyBytes);
}
}
 
Example #13
Source File: HttpRequestDecoder.java    From t-io with Apache License 2.0 2 votes vote down vote up
/**
 * 解析URLENCODED格式的消息体
 * 形如: 【Content-Type : application/x-www-form-urlencoded; charset=UTF-8】
 * @author tanyaowu
 * @throws AioDecodeException 
 */
private static void parseUrlencoded(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, String bodyString, ChannelContext channelContext)
        throws AioDecodeException {
	decodeParams(httpRequest.getParams(), bodyString, httpRequest.getCharset(), channelContext);
}
 
Example #14
Source File: AioHandler.java    From t-io with Apache License 2.0 2 votes vote down vote up
/**
 * 根据ByteBuffer解码成业务需要的Packet对象.
 * 如果收到的数据不全,导致解码失败,请返回null,在下次消息来时框架层会自动续上前面的收到的数据
 * @param buffer 参与本次希望解码的ByteBuffer
 * @param limit ByteBuffer的limit
 * @param position ByteBuffer的position,不一定是0哦
 * @param readableLength ByteBuffer参与本次解码的有效数据(= limit - position)
 * @param channelContext
 * @return
 * @throws AioDecodeException
 */
Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException;