This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/master by this push:
new b32e604 fix #7201 The client-side and server-side payload parameters
are inconsistent, and the server-side response data packet length exceeds the
client-side payload. (#7287)
b32e604 is described below
commit b32e604da57b972c82df580746cc6b54473df2ae
Author: xiaoheng1 <[email protected]>
AuthorDate: Fri Apr 2 10:52:27 2021 +0800
fix #7201 The client-side and server-side payload parameters are
inconsistent, and the server-side response data packet length exceeds the
client-side payload. (#7287)
---
.../remoting/exchange/codec/ExchangeCodec.java | 31 +++++++++++++++++++++-
.../dubbo/remoting/transport/AbstractCodec.java | 21 ++++++++++++---
.../rpc/protocol/dubbo/DubboProtocolTest.java | 18 +++++++++++++
.../rpc/protocol/dubbo/support/DemoService.java | 2 ++
.../protocol/dubbo/support/DemoServiceImpl.java | 8 ++++++
5 files changed, 75 insertions(+), 5 deletions(-)
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 5031470..877f2ca 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
@@ -110,6 +110,14 @@ public class ExchangeCodec extends TelnetCodec {
// get data length.
int len = Bytes.bytes2int(header, 12);
+
+ // When receiving response, how to exceed the length, then directly
construct a response to the client.
+ // see more detail from https://github.com/apache/dubbo/issues/7021.
+ Object obj = finishRespWhenOverPayload(channel, len, header);
+ if (null != obj) {
+ return obj;
+ }
+
checkPayload(channel, len);
int tt = len + HEADER_LENGTH;
@@ -474,5 +482,26 @@ public class ExchangeCodec extends TelnetCodec {
encodeResponseData(out, data);
}
-
+ 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) {
+ Response res = new Response(reqId);
+ if ((flag & FLAG_EVENT) != 0) {
+ res.setEvent(true);
+ }
+ // get status.
+ byte status = header[3];
+ res.setStatus(Response.CLIENT_ERROR);
+ String errorMsg = "Data length too large: " + size + ", max
payload: " + payload + ", channel: " + channel;
+ logger.error(errorMsg);
+ res.setErrorMessage(errorMsg);
+ return res;
+ }
+ }
+ return null;
+ }
}
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java
index e84c28e..fd18ed6 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java
@@ -44,16 +44,29 @@ public abstract class AbstractCodec implements Codec2 {
private static final String SERVER_SIDE = "server";
protected static void checkPayload(Channel channel, long size) throws
IOException {
+ int payload = getPayload(channel);
+ boolean overPayload = isOverPayload(payload, size);
+ if (overPayload) {
+ ExceedPayloadLimitException e = new ExceedPayloadLimitException(
+ "Data length too large: " + size + ", max payload: " +
payload + ", channel: " + channel);
+ logger.error(e);
+ throw e;
+ }
+ }
+
+ protected static int getPayload(Channel channel) {
int payload = Constants.DEFAULT_PAYLOAD;
if (channel != null && channel.getUrl() != null) {
payload = channel.getUrl().getParameter(Constants.PAYLOAD_KEY,
Constants.DEFAULT_PAYLOAD);
}
+ return payload;
+ }
+
+ protected static boolean isOverPayload(int payload, long size) {
if (payload > 0 && size > payload) {
- ExceedPayloadLimitException e = new ExceedPayloadLimitException(
- "Data length too large: " + size + ", max payload: " +
payload + ", channel: " + channel);
- logger.error(e);
- throw e;
+ return true;
}
+ return false;
}
protected Serialization getSerialization(Channel channel, Request req) {
diff --git
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
index b1eeff9..3377eeb 100644
---
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
+++
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
@@ -231,4 +231,22 @@ public class DubboProtocolTest {
service = proxy.getProxy(protocol.refer(DemoService.class, url));
assertEquals(service.getRemoteApplicationName(), "consumer");
}
+
+ @Test
+ public void testPayloadOverException() throws Exception {
+ DemoService service = new DemoServiceImpl();
+ int port = NetUtils.getAvailablePort();
+ protocol.export(proxy.getInvoker(service, DemoService.class,
+ URL.valueOf("dubbo://127.0.0.1:" + port + "/" +
DemoService.class.getName()).addParameter("payload", 10 * 1024)));
+ service = proxy.getProxy(protocol.refer(DemoService.class,
+ URL.valueOf("dubbo://127.0.0.1:" + port + "/" +
DemoService.class.getName()).addParameter("timeout",
+ 6000L).addParameter("payload", 160)));
+ try {
+ service.download(300);
+ Assertions.fail();
+ } catch (Exception expected) {
+ Assertions.assertTrue(expected.getMessage().contains("Data length
too large"));
+ }
+
+ }
}
diff --git
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java
index 40ca4fb..fea53d6 100644
---
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java
+++
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java
@@ -66,4 +66,6 @@ public interface DemoService {
String getPerson(Man man);
String getRemoteApplicationName();
+
+ byte[] download(int size);
}
\ No newline at end of file
diff --git
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
index 0d56e3e..ec1d8c6 100644
---
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
+++
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.protocol.dubbo.support;
import org.apache.dubbo.rpc.RpcContext;
+import java.util.Arrays;
import java.util.Map;
import java.util.Set;
@@ -126,4 +127,11 @@ public class DemoServiceImpl implements DemoService {
public String getRemoteApplicationName() {
return RpcContext.getContext().getRemoteApplicationName();
}
+
+ @Override
+ public byte[] download(int size) {
+ byte[] bytes = new byte[size];
+ Arrays.fill(bytes, (byte) 0);
+ return bytes;
+ }
}
\ No newline at end of file