diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java index 87df02c019..23743a389d 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java @@ -497,12 +497,12 @@ public class ExchangeCodec extends TelnetCodec { } private Object finishRespWhenOverPayload(Channel channel, long size, byte[] header) { - int payload = getPayload(channel); - boolean overPayload = isOverPayload(payload, size); - if (overPayload) { - long reqId = Bytes.bytes2long(header, 4); - byte flag = header[2]; - if ((flag & FLAG_REQUEST) == 0) { + byte flag = header[2]; + if ((flag & FLAG_REQUEST) == 0) { + int payload = getPayload(channel); + boolean overPayload = isOverPayload(payload, size); + if (overPayload) { + long reqId = Bytes.bytes2long(header, 4); Response res = new Response(reqId); if ((flag & FLAG_EVENT) != 0) { res.setEvent(true); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java index 76b3f5ce76..06b9a5157c 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java @@ -16,12 +16,12 @@ */ package org.apache.dubbo.rpc.protocol.dubbo; -import org.apache.dubbo.common.utils.CacheableSupplier; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.serialize.Cleanable; import org.apache.dubbo.common.serialize.ObjectInput; import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.common.utils.CacheableSupplier; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.ReflectUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -30,6 +30,7 @@ import org.apache.dubbo.remoting.Codec; import org.apache.dubbo.remoting.Decodeable; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.transport.CodecSupport; +import org.apache.dubbo.remoting.transport.ExceedPayloadLimitException; import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -52,8 +53,10 @@ import static org.apache.dubbo.common.URL.buildKey; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PAYLOAD; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DECODE; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_EXCEED_PAYLOAD_LIMIT; import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY; import static org.apache.dubbo.rpc.Constants.SERIALIZATION_SECURITY_CHECK_KEY; @@ -125,6 +128,9 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec String version = in.readUTF(); setAttachment(VERSION_KEY, version); + // Do provider-level payload checks. + checkPayload(keyWithoutGroup(path, version)); + setMethodName(in.readUTF()); String desc = in.readUTF(); @@ -248,4 +254,24 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec } return args; } + + private void checkPayload(String serviceKey) throws IOException { + ProviderModel providerModel = + frameworkModel.getServiceRepository().lookupExportedServiceWithoutGroup(serviceKey); + if (providerModel != null) { + String payloadStr = (String) providerModel.getServiceMetadata().getAttachments().get(PAYLOAD); + if (payloadStr != null) { + int payload = Integer.parseInt(payloadStr); + if (payload <= 0) { + return; + } + if (request.getPayload() > payload) { + ExceedPayloadLimitException e = new ExceedPayloadLimitException( + "Data length too large: " + request.getPayload() + ", max payload: " + payload + ", channel: " + channel); + log.error(TRANSPORT_EXCEED_PAYLOAD_LIMIT, "", "", e.getMessage(), e); + throw e; + } + } + } + } } diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java index b9520cab54..44bc7cd700 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java @@ -157,7 +157,12 @@ public class DubboCodec extends ExchangeCodec { } req.setEvent(true); } else { - req = new HeartBeatRequest(id); + req = new Request(id); + + // get data length. + int len = Bytes.bytes2int(header, 12); + req.setPayload(len); + DecodeableRpcInvocation inv; if (isDecodeDataInIoThread(channel)) { if (customByteAccessor != null) {