Skip to content

Commit

Permalink
fix apache#7201 The client-side and server-side payload parameters ar…
Browse files Browse the repository at this point in the history
…e inconsistent, and the server-side response data packet length exceeds the client-side payload. (apache#7287)
  • Loading branch information
xiaoheng1 authored Apr 2, 2021
1 parent cc421ba commit b32e604
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ protected Object decode(Channel channel, ChannelBuffer buffer, int readable, byt

// 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;
Expand Down Expand Up @@ -474,5 +482,26 @@ protected void encodeResponseData(Channel channel, ObjectOutput out, Object data
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,22 @@ public void testRemoteApplicationName() throws Exception {
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"));
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ public interface DemoService {
String getPerson(Man man);

String getRemoteApplicationName();

byte[] download(int size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.dubbo.rpc.RpcContext;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;

Expand Down Expand Up @@ -126,4 +127,11 @@ public String getPerson(Man man) {
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;
}
}

0 comments on commit b32e604

Please sign in to comment.