Provider side payload checking (#11885)
* Provider side payload checking * Optimize judgment conditions and reduce useless calculations * bugfix
This commit is contained in:
parent
fe22d8723a
commit
e54494024a
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue