List of usage examples for io.netty.buffer ByteBuf isReadable
public abstract boolean isReadable();
From source file:com.linecorp.armeria.client.endpoint.dns.DnsTextEndpointGroup.java
License:Apache License
@Override ImmutableSortedSet<Endpoint> onDnsRecords(List<DnsRecord> records, int ttl) throws Exception { final ImmutableSortedSet.Builder<Endpoint> builder = ImmutableSortedSet.naturalOrder(); for (DnsRecord r : records) { if (!(r instanceof DnsRawRecord) || r.type() != DnsRecordType.TXT) { continue; }/*from ww w.j a v a 2s . co m*/ final ByteBuf content = ((ByteBufHolder) r).content(); if (!content.isReadable()) { // Missing length octet warnInvalidRecord(DnsRecordType.TXT, content); continue; } content.markReaderIndex(); final int txtLen = content.readUnsignedByte(); if (txtLen == 0) { // Empty content continue; } if (content.readableBytes() != txtLen) { // Mismatching number of octets content.resetReaderIndex(); warnInvalidRecord(DnsRecordType.TXT, content); continue; } final byte[] txt = new byte[txtLen]; content.readBytes(txt); final Endpoint endpoint; try { endpoint = mapping.apply(txt); } catch (Exception e) { content.resetReaderIndex(); warnInvalidRecord(DnsRecordType.TXT, content); continue; } if (endpoint != null) { if (endpoint.isGroup()) { logger().warn("{} Ignoring group endpoint: {}", logPrefix(), endpoint); } else { builder.add(endpoint); } } } final ImmutableSortedSet<Endpoint> endpoints = builder.build(); if (logger().isDebugEnabled()) { logger().debug("{} Resolved: {} (TTL: {})", logPrefix(), endpoints.stream().map(Object::toString).collect(Collectors.joining(", ")), ttl); } return endpoints; }
From source file:com.linecorp.armeria.client.thrift.ThriftClientCodec.java
License:Apache License
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override//from www .j av a 2 s . c o m public <T> T decodeResponse(ServiceInvocationContext ctx, ByteBuf content, Object originalResponse) throws Exception { if (content == null) { return null; } if (!content.isReadable()) { ThriftMethod thriftMethod = getThriftMethod(ctx); if (thriftMethod != null && thriftMethod.isOneWay()) { return null; } throw new TApplicationException(TApplicationException.MISSING_RESULT, ctx.toString()); } TByteBufInputTransport inputTransport = new TByteBufInputTransport(content); TProtocol inputProtocol = protocolFactory.getProtocol(inputTransport); TMessage msg = inputProtocol.readMessageBegin(); if (msg.type == TMessageType.EXCEPTION) { TApplicationException ex = TApplicationException.read(inputProtocol); inputProtocol.readMessageEnd(); throw ex; } ThriftMethod method = methodMap.get(msg.name); if (method == null) { throw new TApplicationException(TApplicationException.WRONG_METHOD_NAME, msg.name); } TBase<? extends TBase, TFieldIdEnum> result = method.createResult(); result.read(inputProtocol); inputProtocol.readMessageEnd(); for (TFieldIdEnum fieldIdEnum : method.getExceptionFields()) { if (result.isSet(fieldIdEnum)) { throw (TException) result.getFieldValue(fieldIdEnum); } } TFieldIdEnum successField = method.successField(); if (successField == null) { //void method return null; } if (result.isSet(successField)) { return (T) result.getFieldValue(successField); } throw new TApplicationException(TApplicationException.MISSING_RESULT, result.getClass().getName() + '.' + successField.getFieldName()); }
From source file:com.linecorp.armeria.common.HttpData.java
License:Apache License
/** * Converts the specified Netty {@link ByteBuf} into an {@link HttpData}. Unlike {@link #of(byte[])}, this * method makes a copy of the {@link ByteBuf}. * * @return a new {@link HttpData}. {@link #EMPTY_DATA} if the readable bytes of {@code buf} is 0. *///from w ww .j a v a 2s .c o m static HttpData of(ByteBuf buf) { requireNonNull(buf, "buf"); if (!buf.isReadable()) { return EMPTY_DATA; } return of(ByteBufUtil.getBytes(buf)); }
From source file:com.linecorp.armeria.server.http.tomcat.TomcatServiceInvocationHandler.java
License:Apache License
private Request convertRequest(ServiceInvocationContext ctx) { final FullHttpRequest req = ctx.originalRequest(); final String mappedPath = ctx.mappedPath(); final Request coyoteReq = new Request(); // Set the remote host/address. final InetSocketAddress remoteAddr = (InetSocketAddress) ctx.remoteAddress(); coyoteReq.remoteAddr().setString(remoteAddr.getAddress().getHostAddress()); coyoteReq.remoteHost().setString(remoteAddr.getHostString()); coyoteReq.setRemotePort(remoteAddr.getPort()); // Set the local host/address. final InetSocketAddress localAddr = (InetSocketAddress) ctx.localAddress(); coyoteReq.localAddr().setString(localAddr.getAddress().getHostAddress()); coyoteReq.localName().setString(hostname()); coyoteReq.setLocalPort(localAddr.getPort()); // Set the method. final HttpMethod method = req.method(); coyoteReq.method().setString(method.name()); // Set the request URI. final byte[] uriBytes = mappedPath.getBytes(StandardCharsets.US_ASCII); coyoteReq.requestURI().setBytes(uriBytes, 0, uriBytes.length); // Set the query string if any. final int queryIndex = req.uri().indexOf('?'); if (queryIndex >= 0) { coyoteReq.queryString().setString(req.uri().substring(queryIndex + 1)); }//from w ww. j av a 2s.c o m // Set the headers. final MimeHeaders cHeaders = coyoteReq.getMimeHeaders(); convertHeaders(req.headers(), cHeaders); convertHeaders(req.trailingHeaders(), cHeaders); // Set the content. final ByteBuf content = req.content(); if (content.isReadable()) { coyoteReq.setInputBuffer(new InputBufferImpl(content)); } return coyoteReq; }
From source file:com.mobius.software.android.iotbroker.mqtt.parser.MQParser.java
License:Open Source License
public static MQMessage decode(ByteBuf buf) throws MalformedMessageException, UnsupportedEncodingException { MQMessage header = null;/*from w w w . ja va 2 s . c o m*/ byte fixedHeader = buf.readByte(); LengthDetails length = decodeLength(buf); MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf); switch (type) { case CONNECT: byte[] nameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(nameValue, 0, nameValue.length); String name = new String(nameValue, "UTF-8"); if (!name.equals("MQTT")) throw new MalformedMessageException("CONNECT, protocol-name set to " + name); int protocolLevel = buf.readUnsignedByte(); byte contentFlags = buf.readByte(); boolean userNameFlag = (((contentFlags >> 7) & 1) == 1) ? true : false; boolean userPassFlag = (((contentFlags >> 6) & 1) == 1) ? true : false; boolean willRetain = (((contentFlags >> 5) & 1) == 1) ? true : false; QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3); if (willQos == null) throw new MalformedMessageException("CONNECT, will QoS set to " + willQos); boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false; if (willQos.getValue() > 0 && !willFlag) throw new MalformedMessageException("CONNECT, will QoS set to " + willQos + ", willFlag not set"); if (willRetain && !willFlag) throw new MalformedMessageException("CONNECT, will retain set, willFlag not set"); boolean cleanSession = (((contentFlags >> 1) & 1) == 1) ? true : false; boolean reservedFlag = ((contentFlags & 1) == 1) ? true : false; if (reservedFlag) throw new MalformedMessageException("CONNECT, reserved flag set to true"); int keepalive = buf.readUnsignedShort(); byte[] clientIdValue = new byte[buf.readUnsignedShort()]; buf.readBytes(clientIdValue, 0, clientIdValue.length); String clientID = new String(clientIdValue, "UTF-8"); if (!StringVerifier.verify(clientID)) throw new MalformedMessageException( "ClientID contains restricted characters: U+0000, U+D000-U+DFFF"); Text willTopic = null; byte[] willMessage = null; String username = null; String password = null; Will will = null; if (willFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] willTopicValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willTopicValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willTopicValue, 0, willTopicValue.length); String willTopicName = new String(willTopicValue, "UTF-8"); if (!StringVerifier.verify(willTopicName)) throw new MalformedMessageException( "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); willTopic = new Text(willTopicName); if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); willMessage = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willMessage.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willMessage, 0, willMessage.length); if (willTopic.length() == 0) throw new MalformedMessageException("invalid will encoding"); will = new Will(new Topic(willTopic, willQos), willMessage, willRetain); if (!will.isValid()) throw new MalformedMessageException("invalid will encoding"); } if (userNameFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userNameValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userNameValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userNameValue, 0, userNameValue.length); username = new String(userNameValue, "UTF-8"); if (!StringVerifier.verify(username)) throw new MalformedMessageException( "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (userPassFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userPassValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userPassValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userPassValue, 0, userPassValue.length); password = new String(userPassValue, "UTF-8"); if (!StringVerifier.verify(password)) throw new MalformedMessageException( "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (buf.readableBytes() > 0) throw new MalformedMessageException("Invalid encoding will/username/password"); Connect connect = new Connect(username, password, clientID, cleanSession, keepalive, will); if (protocolLevel != 4) connect.setProtocolLevel(protocolLevel); header = connect; break; case CONNACK: byte sessionPresentValue = buf.readByte(); if (sessionPresentValue != 0 && sessionPresentValue != 1) throw new MalformedMessageException( String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff)); boolean isPresent = sessionPresentValue == 1 ? true : false; short connackByte = buf.readUnsignedByte(); ConnackCode connackCode = ConnackCode.valueOf(connackByte); if (connackCode == null) throw new MalformedMessageException("Invalid connack code: " + connackByte); header = new Connack(isPresent, connackCode); break; case PUBLISH: int dataLength = length.getLength(); fixedHeader &= 0xf; boolean dup = (((fixedHeader >> 3) & 1) == 1) ? true : false; QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1); if (qos == null) throw new MalformedMessageException("invalid QoS value"); if (dup && qos == QoS.AT_MOST_ONCE) throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present"); boolean retain = ((fixedHeader & 1) == 1) ? true : false; byte[] topicNameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(topicNameValue, 0, topicNameValue.length); String topicName = new String(topicNameValue, "UTF-8"); if (!StringVerifier.verify(topicName)) throw new MalformedMessageException( "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); dataLength -= topicName.length() + 2; Integer packetID = null; if (qos != QoS.AT_MOST_ONCE) { packetID = buf.readUnsignedShort(); if (packetID < 0 || packetID > 65535) throw new MalformedMessageException("Invalid PUBLISH packetID encoding"); dataLength -= 2; } byte[] data = new byte[dataLength]; if (dataLength > 0) buf.readBytes(data, 0, data.length); header = new Publish(packetID, new Topic(new Text(topicName), qos), data, retain, dup); break; case PUBACK: header = new Puback(buf.readUnsignedShort()); break; case PUBREC: header = new Pubrec(buf.readUnsignedShort()); break; case PUBREL: header = new Pubrel(buf.readUnsignedShort()); break; case PUBCOMP: header = new Pubcomp(buf.readUnsignedShort()); break; case SUBSCRIBE: Integer subID = buf.readUnsignedShort(); List<Topic> subscriptions = new ArrayList<Topic>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); QoS requestedQos = QoS.valueOf(buf.readByte()); if (requestedQos == null) throw new MalformedMessageException( "Subscribe qos must be in range from 0 to 2: " + requestedQos); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Topic subscription = new Topic(new Text(topic), requestedQos); subscriptions.add(subscription); } if (subscriptions.isEmpty()) throw new MalformedMessageException("Subscribe with 0 topics"); header = new Subscribe(subID, subscriptions.toArray(new Topic[subscriptions.size()])); break; case SUBACK: Integer subackID = buf.readUnsignedShort(); List<SubackCode> subackCodes = new ArrayList<SubackCode>(); while (buf.isReadable()) { short subackByte = buf.readUnsignedByte(); SubackCode subackCode = SubackCode.valueOf(subackByte); if (subackCode == null) throw new MalformedMessageException("Invalid suback code: " + subackByte); subackCodes.add(subackCode); } if (subackCodes.isEmpty()) throw new MalformedMessageException("Suback with 0 return-codes"); header = new Suback(subackID, subackCodes); break; case UNSUBSCRIBE: Integer unsubID = buf.readUnsignedShort(); List<Topic> unsubscribeTopics = new ArrayList<Topic>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Topic subscription = new Topic(new Text(topic), QoS.AT_MOST_ONCE); unsubscribeTopics.add(subscription); } if (unsubscribeTopics.isEmpty()) throw new MalformedMessageException("Unsubscribe with 0 topics"); header = new Unsubscribe(unsubID, unsubscribeTopics.toArray(new Topic[unsubscribeTopics.size()])); break; case UNSUBACK: header = new Unsuback(buf.readUnsignedShort()); break; case PINGREQ: header = new Pingreq(); break; case PINGRESP: header = new Pingresp(); break; case DISCONNECT: header = new Disconnect(); break; default: throw new MalformedMessageException("Invalid header type: " + type); } if (buf.isReadable()) throw new MalformedMessageException("unexpected bytes in content"); if (length.getLength() != header.getLength()) throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d", length.getLength(), header.getLength())); return header; }
From source file:com.mobius.software.android.iotbroker.mqtt.parser.MQParser.java
License:Open Source License
private static LengthDetails decodeLength(ByteBuf buf) throws MalformedMessageException { int length = 0, multiplier = 1; int bytesUsed = 0; byte enc = 0; do {//from w w w . ja v a 2 s. c om if (multiplier > 128 * 128 * 128) throw new MalformedMessageException("Encoded length exceeds maximum of 268435455 bytes"); if (!buf.isReadable()) return new LengthDetails(0, 0); enc = buf.readByte(); length += (enc & 0x7f) * multiplier; multiplier *= 128; bytesUsed++; } while ((enc & 0x80) != 0); return new LengthDetails(length, bytesUsed); }
From source file:com.mobius.software.mqtt.parser.avps.LengthDetails.java
License:Open Source License
public static LengthDetails decode(ByteBuf buf) throws MalformedMessageException { int length = 0, multiplier = 1; int bytesUsed = 0; byte enc = 0; do {// ww w. j av a 2 s . c o m if (multiplier > 128 * 128 * 128) throw new MalformedMessageException("Encoded length exceeds maximum of 268435455 bytes"); if (!buf.isReadable()) return new LengthDetails(0, 0); enc = buf.readByte(); length += (enc & 0x7f) * multiplier; multiplier *= 128; bytesUsed++; } while ((enc & 0x80) != 0); return new LengthDetails(length, bytesUsed); }
From source file:com.mobius.software.mqtt.parser.MQParser.java
License:Open Source License
public MQMessage decodeUsingCache(ByteBuf buf) throws MalformedMessageException { byte fixedHeader = buf.readByte(); LengthDetails length = LengthDetails.decode(buf); MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf); MQMessage header = cache.borrowMessage(type); try {/*from w w w.ja va 2 s . c o m*/ switch (type) { case CONNECT: byte[] nameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(nameValue, 0, nameValue.length); String name = new String(nameValue, "UTF-8"); if (!name.equals("MQTT")) throw new MalformedMessageException("CONNECT, protocol-name set to " + name); int protocolLevel = buf.readUnsignedByte(); byte contentFlags = buf.readByte(); boolean userNameFlag = ((contentFlags >> 7) & 1) == 1 ? true : false; boolean userPassFlag = ((contentFlags >> 6) & 1) == 1 ? true : false; boolean willRetain = ((contentFlags >> 5) & 1) == 1 ? true : false; QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3); if (willQos == null) throw new MalformedMessageException("CONNECT, will QoS set to " + willQos); boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false; if (willQos.getValue() > 0 && !willFlag) throw new MalformedMessageException( "CONNECT, will QoS set to " + willQos + ", willFlag not set"); if (willRetain && !willFlag) throw new MalformedMessageException("CONNECT, will retain set, willFlag not set"); boolean cleanSession = ((contentFlags >> 1) & 1) == 1 ? true : false; boolean reservedFlag = (contentFlags & 1) == 1 ? true : false; if (reservedFlag) throw new MalformedMessageException("CONNECT, reserved flag set to true"); int keepalive = buf.readUnsignedShort(); byte[] clientIdValue = new byte[buf.readUnsignedShort()]; buf.readBytes(clientIdValue, 0, clientIdValue.length); String clientID = new String(clientIdValue, "UTF-8"); if (!StringVerifier.verify(clientID)) throw new MalformedMessageException( "ClientID contains restricted characters: U+0000, U+D000-U+DFFF"); Text willTopic = null; byte[] willMessage = null; String username = null; String password = null; Will will = null; if (willFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] willTopicValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willTopicValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willTopicValue, 0, willTopicValue.length); String willTopicName = new String(willTopicValue, "UTF-8"); if (!StringVerifier.verify(willTopicName)) throw new MalformedMessageException( "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); willTopic = new Text(willTopicName); if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); willMessage = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willMessage.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willMessage, 0, willMessage.length); if (willTopic.length() == 0) throw new MalformedMessageException("invalid will encoding"); will = new Will(new Topic(willTopic, willQos), willMessage, willRetain); if (!will.isValid()) throw new MalformedMessageException("invalid will encoding"); } if (userNameFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userNameValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userNameValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userNameValue, 0, userNameValue.length); username = new String(userNameValue, "UTF-8"); if (!StringVerifier.verify(username)) throw new MalformedMessageException( "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (userPassFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userPassValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userPassValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userPassValue, 0, userPassValue.length); password = new String(userPassValue, "UTF-8"); if (!StringVerifier.verify(password)) throw new MalformedMessageException( "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (buf.readableBytes() > 0) throw new MalformedMessageException("Invalid encoding will/username/password"); Connect connect = (Connect) header; connect.reInit(username, password, clientID, cleanSession, keepalive, will); connect.setProtocolLevel(protocolLevel); break; case CONNACK: byte sessionPresentValue = buf.readByte(); if (sessionPresentValue != 0 && sessionPresentValue != 1) throw new MalformedMessageException( String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff)); boolean isPresent = sessionPresentValue == 1 ? true : false; short connackByte = buf.readUnsignedByte(); ConnackCode connackCode = ConnackCode.valueOf(connackByte); if (connackCode == null) throw new MalformedMessageException("Invalid connack code: " + connackByte); Connack connack = (Connack) header; connack.reInit(isPresent, connackCode); break; case PUBLISH: fixedHeader &= 0xf; boolean dup = ((fixedHeader >> 3) & 1) == 1 ? true : false; QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1); if (qos == null) throw new MalformedMessageException("invalid QoS value"); if (dup && qos == QoS.AT_MOST_ONCE) throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present"); boolean retain = ((fixedHeader & 1) == 1) ? true : false; byte[] topicNameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(topicNameValue, 0, topicNameValue.length); String topicName = new String(topicNameValue, "UTF-8"); if (!StringVerifier.verify(topicName)) throw new MalformedMessageException( "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Integer packetID = null; if (qos != QoS.AT_MOST_ONCE) { packetID = buf.readUnsignedShort(); if (packetID < 0 || packetID > 65535) throw new MalformedMessageException("Invalid PUBLISH packetID encoding"); } ByteBuf data = Unpooled.buffer(buf.readableBytes()); data.writeBytes(buf); Publish publish = (Publish) header; publish.reInit(packetID, new Topic(new Text(topicName), qos), data, retain, dup); break; case PUBACK: case PUBREC: case PUBREL: case PUBCOMP: case UNSUBACK: CountableMessage countable = (CountableMessage) header; countable.reInit(buf.readUnsignedShort()); break; case SUBSCRIBE: Integer subID = buf.readUnsignedShort(); List<Topic> subscriptions = new ArrayList<>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); QoS requestedQos = QoS.valueOf(buf.readByte()); if (requestedQos == null) throw new MalformedMessageException( "Subscribe qos must be in range from 0 to 2: " + requestedQos); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Topic subscription = new Topic(new Text(topic), requestedQos); subscriptions.add(subscription); } if (subscriptions.isEmpty()) throw new MalformedMessageException("Subscribe with 0 topics"); Subscribe subscribe = (Subscribe) header; subscribe.reInit(subID, subscriptions.toArray(new Topic[subscriptions.size()])); break; case SUBACK: Integer subackID = buf.readUnsignedShort(); List<SubackCode> subackCodes = new ArrayList<>(); while (buf.isReadable()) { short subackByte = buf.readUnsignedByte(); SubackCode subackCode = SubackCode.valueOf(subackByte); if (subackCode == null) throw new MalformedMessageException("Invalid suback code: " + subackByte); subackCodes.add(subackCode); } if (subackCodes.isEmpty()) throw new MalformedMessageException("Suback with 0 return-codes"); Suback suback = (Suback) header; suback.reInit(subackID, subackCodes); break; case UNSUBSCRIBE: Integer unsubID = buf.readUnsignedShort(); List<Text> unsubscribeTopics = new ArrayList<>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); unsubscribeTopics.add(new Text(topic)); } if (unsubscribeTopics.isEmpty()) throw new MalformedMessageException("Unsubscribe with 0 topics"); Unsubscribe unsubscribe = (Unsubscribe) header; unsubscribe.reInit(unsubID, unsubscribeTopics.toArray(new Text[unsubscribeTopics.size()])); break; case PINGREQ: case PINGRESP: case DISCONNECT: break; default: throw new MalformedMessageException("Invalid header type: " + type); } if (buf.isReadable()) throw new MalformedMessageException("unexpected bytes in content"); if (length.getLength() != header.getLength()) throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d", length.getLength(), header.getLength())); return header; } catch (UnsupportedEncodingException e) { throw new MalformedMessageException("unsupported string encoding:" + e.getMessage()); } }
From source file:com.mobius.software.mqtt.parser.MQParser.java
License:Open Source License
public static MQMessage decode(ByteBuf buf) throws MalformedMessageException { MQMessage header = null;/*from w w w . j a v a2 s .co m*/ byte fixedHeader = buf.readByte(); LengthDetails length = LengthDetails.decode(buf); MessageType type = MessageType.valueOf((fixedHeader >> 4) & 0xf); try { switch (type) { case CONNECT: byte[] nameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(nameValue, 0, nameValue.length); String name = new String(nameValue, "UTF-8"); if (!name.equals("MQTT")) throw new MalformedMessageException("CONNECT, protocol-name set to " + name); int protocolLevel = buf.readUnsignedByte(); byte contentFlags = buf.readByte(); boolean userNameFlag = ((contentFlags >> 7) & 1) == 1 ? true : false; boolean userPassFlag = ((contentFlags >> 6) & 1) == 1 ? true : false; boolean willRetain = ((contentFlags >> 5) & 1) == 1 ? true : false; QoS willQos = QoS.valueOf(((contentFlags & 0x1f) >> 3) & 3); if (willQos == null) throw new MalformedMessageException("CONNECT, will QoS set to " + willQos); boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false; if (willQos.getValue() > 0 && !willFlag) throw new MalformedMessageException( "CONNECT, will QoS set to " + willQos + ", willFlag not set"); if (willRetain && !willFlag) throw new MalformedMessageException("CONNECT, will retain set, willFlag not set"); boolean cleanSession = ((contentFlags >> 1) & 1) == 1 ? true : false; boolean reservedFlag = (contentFlags & 1) == 1 ? true : false; if (reservedFlag) throw new MalformedMessageException("CONNECT, reserved flag set to true"); int keepalive = buf.readUnsignedShort(); byte[] clientIdValue = new byte[buf.readUnsignedShort()]; buf.readBytes(clientIdValue, 0, clientIdValue.length); String clientID = new String(clientIdValue, "UTF-8"); if (!StringVerifier.verify(clientID)) throw new MalformedMessageException( "ClientID contains restricted characters: U+0000, U+D000-U+DFFF"); Text willTopic = null; byte[] willMessage = null; String username = null; String password = null; Will will = null; if (willFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] willTopicValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willTopicValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willTopicValue, 0, willTopicValue.length); String willTopicName = new String(willTopicValue, "UTF-8"); if (!StringVerifier.verify(willTopicName)) throw new MalformedMessageException( "WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); willTopic = new Text(willTopicName); if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); willMessage = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < willMessage.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(willMessage, 0, willMessage.length); if (willTopic.length() == 0) throw new MalformedMessageException("invalid will encoding"); will = new Will(new Topic(willTopic, willQos), willMessage, willRetain); if (!will.isValid()) throw new MalformedMessageException("invalid will encoding"); } if (userNameFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userNameValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userNameValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userNameValue, 0, userNameValue.length); username = new String(userNameValue, "UTF-8"); if (!StringVerifier.verify(username)) throw new MalformedMessageException( "Username contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (userPassFlag) { if (buf.readableBytes() < 2) throw new MalformedMessageException("Invalid encoding will/username/password"); byte[] userPassValue = new byte[buf.readUnsignedShort()]; if (buf.readableBytes() < userPassValue.length) throw new MalformedMessageException("Invalid encoding will/username/password"); buf.readBytes(userPassValue, 0, userPassValue.length); password = new String(userPassValue, "UTF-8"); if (!StringVerifier.verify(password)) throw new MalformedMessageException( "Password contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (buf.readableBytes() > 0) throw new MalformedMessageException("Invalid encoding will/username/password"); Connect connect = new Connect(username, password, clientID, cleanSession, keepalive, will); if (protocolLevel != 4) connect.setProtocolLevel(protocolLevel); header = connect; break; case CONNACK: byte sessionPresentValue = buf.readByte(); if (sessionPresentValue != 0 && sessionPresentValue != 1) throw new MalformedMessageException( String.format("CONNACK, session-present set to %d", sessionPresentValue & 0xff)); boolean isPresent = sessionPresentValue == 1 ? true : false; short connackByte = buf.readUnsignedByte(); ConnackCode connackCode = ConnackCode.valueOf(connackByte); if (connackCode == null) throw new MalformedMessageException("Invalid connack code: " + connackByte); header = new Connack(isPresent, connackCode); break; case PUBLISH: fixedHeader &= 0xf; boolean dup = ((fixedHeader >> 3) & 1) == 1 ? true : false; QoS qos = QoS.valueOf((fixedHeader & 0x07) >> 1); if (qos == null) throw new MalformedMessageException("invalid QoS value"); if (dup && qos == QoS.AT_MOST_ONCE) throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present"); boolean retain = ((fixedHeader & 1) == 1) ? true : false; byte[] topicNameValue = new byte[buf.readUnsignedShort()]; buf.readBytes(topicNameValue, 0, topicNameValue.length); String topicName = new String(topicNameValue, "UTF-8"); if (!StringVerifier.verify(topicName)) throw new MalformedMessageException( "Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Integer packetID = null; if (qos != QoS.AT_MOST_ONCE) { packetID = buf.readUnsignedShort(); if (packetID < 0 || packetID > 65535) throw new MalformedMessageException("Invalid PUBLISH packetID encoding"); } ByteBuf data = Unpooled.buffer(buf.readableBytes()); data.writeBytes(buf); header = new Publish(packetID, new Topic(new Text(topicName), qos), data, retain, dup); break; case PUBACK: header = new Puback(buf.readUnsignedShort()); break; case PUBREC: header = new Pubrec(buf.readUnsignedShort()); break; case PUBREL: header = new Pubrel(buf.readUnsignedShort()); break; case PUBCOMP: header = new Pubcomp(buf.readUnsignedShort()); break; case SUBSCRIBE: Integer subID = buf.readUnsignedShort(); List<Topic> subscriptions = new ArrayList<>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); QoS requestedQos = QoS.valueOf(buf.readByte()); if (requestedQos == null) throw new MalformedMessageException( "Subscribe qos must be in range from 0 to 2: " + requestedQos); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); Topic subscription = new Topic(new Text(topic), requestedQos); subscriptions.add(subscription); } if (subscriptions.isEmpty()) throw new MalformedMessageException("Subscribe with 0 topics"); header = new Subscribe(subID, subscriptions.toArray(new Topic[subscriptions.size()])); break; case SUBACK: Integer subackID = buf.readUnsignedShort(); List<SubackCode> subackCodes = new ArrayList<>(); while (buf.isReadable()) { short subackByte = buf.readUnsignedByte(); SubackCode subackCode = SubackCode.valueOf(subackByte); if (subackCode == null) throw new MalformedMessageException("Invalid suback code: " + subackByte); subackCodes.add(subackCode); } if (subackCodes.isEmpty()) throw new MalformedMessageException("Suback with 0 return-codes"); header = new Suback(subackID, subackCodes); break; case UNSUBSCRIBE: Integer unsubID = buf.readUnsignedShort(); List<Text> unsubscribeTopics = new ArrayList<>(); while (buf.isReadable()) { byte[] value = new byte[buf.readUnsignedShort()]; buf.readBytes(value, 0, value.length); String topic = new String(value, "UTF-8"); if (!StringVerifier.verify(topic)) throw new MalformedMessageException( "Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); unsubscribeTopics.add(new Text(topic)); } if (unsubscribeTopics.isEmpty()) throw new MalformedMessageException("Unsubscribe with 0 topics"); header = new Unsubscribe(unsubID, unsubscribeTopics.toArray(new Text[unsubscribeTopics.size()])); break; case UNSUBACK: header = new Unsuback(buf.readUnsignedShort()); break; case PINGREQ: header = PINGREQ; break; case PINGRESP: header = PINGRESP; break; case DISCONNECT: header = DISCONNECT; break; default: throw new MalformedMessageException("Invalid header type: " + type); } if (buf.isReadable()) throw new MalformedMessageException("unexpected bytes in content"); if (length.getLength() != header.getLength()) throw new MalformedMessageException(String.format("Invalid length. Encoded: %d, actual: %d", length.getLength(), header.getLength())); return header; } catch (UnsupportedEncodingException e) { throw new MalformedMessageException("unsupported string encoding:" + e.getMessage()); } }
From source file:com.mpush.netty.codec.PacketDecoder.java
License:Apache License
private void decodeHeartbeat(ByteBuf in, List<Object> out) { while (in.isReadable()) { if (in.readByte() == Packet.HB_PACKET_BYTE) { out.add(Packet.HB_PACKET);/*from ww w . j a v a 2 s. co m*/ } else { in.readerIndex(in.readerIndex() - 1); break; } } }