Compare commits

...

10 Commits
3.2 ... 3.0

19 changed files with 196 additions and 94 deletions

2
NOTICE
View File

@ -1,5 +1,5 @@
Apache Dubbo Apache Dubbo
Copyright 2018-2022 The Apache Software Foundation Copyright 2018-2023 The Apache Software Foundation
This product includes software developed at This product includes software developed at
The Apache Software Foundation (http://www.apache.org/). The Apache Software Foundation (http://www.apache.org/).

View File

@ -16,12 +16,6 @@
*/ */
package org.apache.dubbo.common.beanutil; package org.apache.dubbo.common.beanutil;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.LogHelper;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.SerializeClassChecker;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -32,6 +26,12 @@ import java.util.HashMap;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.LogHelper;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.SerializeClassChecker;
public final class JavaBeanSerializeUtil { public final class JavaBeanSerializeUtil {
private static final Logger logger = LoggerFactory.getLogger(JavaBeanSerializeUtil.class); private static final Logger logger = LoggerFactory.getLogger(JavaBeanSerializeUtil.class);
@ -466,7 +466,9 @@ public final class JavaBeanSerializeUtil {
name = name.substring(1, name.length() - 1); name = name.substring(1, name.length() - 1);
} }
SerializeClassChecker.getInstance().validateClass(name); SerializeClassChecker.getInstance().validateClass(name);
return Class.forName(name, false, loader); Class<?> aClass = Class.forName(name, false, loader);
SerializeClassChecker.getInstance().validateClass(aClass);
return aClass;
} }
private static boolean isArray(String type) { private static boolean isArray(String type) {

View File

@ -17,13 +17,13 @@
package org.apache.dubbo.common.constants; package org.apache.dubbo.common.constants;
import org.apache.dubbo.common.URL;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.dubbo.common.URL;
public interface CommonConstants { public interface CommonConstants {
String DUBBO = "dubbo"; String DUBBO = "dubbo";
@ -412,6 +412,8 @@ public interface CommonConstants {
String CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList"; String CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList";
String CLASS_DESERIALIZE_CHECK_SERIALIZABLE = "dubbo.application.check-serializable";
String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = "dubbo.security.serialize.generic.native-java-enable"; String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = "dubbo.security.serialize.generic.native-java-enable";
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist"; String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";

View File

@ -16,11 +16,6 @@
*/ */
package org.apache.dubbo.common.utils; package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -55,6 +50,11 @@ import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import static org.apache.dubbo.common.utils.ClassUtils.isAssignableFrom; import static org.apache.dubbo.common.utils.ClassUtils.isAssignableFrom;
/** /**
@ -410,6 +410,7 @@ public class PojoUtils {
CLASS_NOT_FOUND_CACHE.put((String) className, NOT_FOUND_VALUE); CLASS_NOT_FOUND_CACHE.put((String) className, NOT_FOUND_VALUE);
} }
} }
SerializeClassChecker.getInstance().validateClass(type);
} }
// special logic for enum // special logic for enum

View File

@ -16,16 +16,19 @@
*/ */
package org.apache.dubbo.common.utils; package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST; import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST;
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST; import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST;
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL; import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL;
@ -44,6 +47,8 @@ public class SerializeClassChecker {
private final LFUCache<String, Object> CLASS_ALLOW_LFU_CACHE = new LFUCache<>(); private final LFUCache<String, Object> CLASS_ALLOW_LFU_CACHE = new LFUCache<>();
private final LFUCache<String, Object> CLASS_BLOCK_LFU_CACHE = new LFUCache<>(); private final LFUCache<String, Object> CLASS_BLOCK_LFU_CACHE = new LFUCache<>();
private final boolean checkSerializable;
private final AtomicLong counter = new AtomicLong(0); private final AtomicLong counter = new AtomicLong(0);
private SerializeClassChecker() { private SerializeClassChecker() {
@ -83,6 +88,7 @@ public class SerializeClassChecker {
CLASS_DESERIALIZE_BLOCKED_SET.addAll(Arrays.asList(classStrings)); CLASS_DESERIALIZE_BLOCKED_SET.addAll(Arrays.asList(classStrings));
} }
checkSerializable = Boolean.parseBoolean(ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE, "true"));
} }
public static SerializeClassChecker getInstance() { public static SerializeClassChecker getInstance() {
@ -137,6 +143,12 @@ public class SerializeClassChecker {
CLASS_ALLOW_LFU_CACHE.put(name, CACHE); CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
} }
public void validateClass(Class<?> aClass) {
if (checkSerializable && !Serializable.class.isAssignableFrom(aClass)) {
error(aClass.getName());
}
}
private void error(String name) { private void error(String name) {
String notice = "Trigger the safety barrier! " + String notice = "Trigger the safety barrier! " +
"Catch not allowed serialize class. " + "Catch not allowed serialize class. " +

View File

@ -18,33 +18,38 @@
# #
aj.org.objectweb.asm. aj.org.objectweb.asm.
br.com.anteros. br.com.anteros.
bsh.
ch.qos.logback. ch.qos.logback.
clojure.core$constantly clojure.
clojure.main$eval_opt com.alibaba.citrus.springext.support.parser.
com.alibaba.citrus.springext.support.parser.abstractnamedproxybeandefinitionparser$proxytargetfactory com.alibaba.citrus.springext.util.SpringExtUtil.
com.alibaba.citrus.springext.util.springextutil.abstractproxy com.alibaba.druid.pool.
com.alibaba.druid.pool.druiddatasource
com.alibaba.druid.stat.jdbcdatasourcestat com.alibaba.druid.stat.jdbcdatasourcestat
com.alibaba.fastjson.annotation com.alibaba.fastjson.annotation
com.alipay.custrelation.service.model.redress.pair com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
com.alipay.custrelation.service.model.redress.
com.alipay.oceanbase.obproxy.druid.pool.
com.caucho. com.caucho.
com.ibatis. com.ibatis.
com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
com.ibm.xltxe.rnm1.xtq.bcel.util.
com.mchange com.mchange
com.mysql.cj.jdbc.admin. com.mysql.cj.jdbc.admin.
com.mysql.cj.jdbc.mysqlconnectionpooldatasource com.mysql.cj.jdbc.mysqlconnectionpooldatasource
com.mysql.cj.jdbc.mysqldatasource com.mysql.cj.jdbc.mysqldatasource
com.mysql.cj.jdbc.mysqlxadatasource com.mysql.cj.jdbc.mysqlxadatasource
com.mysql.cj.log. com.mysql.cj.log.
com.mysql.jdbc.util.
com.p6spy.engine. com.p6spy.engine.
com.rometools.rome.feed.impl.equalsbean com.rometools.rome.feed.
com.rometools.rome.feed.impl.tostringbean
com.sun. com.sun.
com.taobao.eagleeye.wrapper com.taobao.eagleeye.wrapper
com.taobao.vipserver.commons.collections.functors.
com.zaxxer.hikari. com.zaxxer.hikari.
flex.messaging.util.concurrent. flex.messaging.util.concurrent.
java.awt.i groovy.lang.
java.awt.p java.awt.
java.beans.expression java.beans.
java.io.closeable java.io.closeable
java.io.serializable java.io.serializable
java.lang.autocloseable java.lang.autocloseable
@ -52,41 +57,46 @@ java.lang.class
java.lang.cloneable java.lang.cloneable
java.lang.iterable java.lang.iterable
java.lang.object java.lang.object
java.lang.ProcessBuilder
java.lang.readable java.lang.readable
java.lang.runnable java.lang.runnable
java.lang.Runtime
java.lang.thread java.lang.thread
java.lang.unixprocess java.lang.unixprocess
java.net.inetaddress java.net.inetaddress
java.net.socket java.net.socket
java.net.url java.net.url
java.rmi java.rmi
java.security.signedobject java.security.
java.util.collection java.util.collection
java.util.eventlistener java.util.eventlistener
java.util.jar. java.util.jar.
java.util.logging. java.util.logging.
java.util.prefs. java.util.prefs.
java.util.ServiceLoader
java.util.serviceloader$lazyiterator java.util.serviceloader$lazyiterator
java.util.StringTokenizer
javassist. javassist.
javax.activation. javax.activation.
javax.imageio.imageio$containsfilter javax.imageio.
javax.imageio.spi.serviceregistry
javax.management. javax.management.
javax.media.jai.remote.
javax.naming. javax.naming.
javax.net. javax.net.
javax.print. javax.print.
javax.script. javax.script.
javax.sound. javax.sound.
javax.swing.j javax.swing.
javax.tools. javax.tools.
javax.xml javax.xml
jdk.internal. jdk.internal.
jodd.db.connection. jodd.db.connection.
junit. junit.
net.bytebuddy.dynamic.loading.bytearrayclassloader net.bytebuddy.dynamic.loading.
net.sf.cglib. net.sf.cglib.
net.sf.ehcache.hibernate. net.sf.ehcache.hibernate.
net.sf.ehcache.transaction.manager. net.sf.ehcache.transaction.manager.
ognl.
oracle.jdbc. oracle.jdbc.
oracle.jms.aq oracle.jms.aq
oracle.net oracle.net
@ -100,10 +110,12 @@ org.apache.aries.transaction.
org.apache.axis2.jaxws.spi.handler. org.apache.axis2.jaxws.spi.handler.
org.apache.axis2.transport.jms. org.apache.axis2.transport.jms.
org.apache.bcel org.apache.bcel
org.apache.carbondata.core.scan.expression.
org.apache.carbondata.core.scan.expression.expressionresult org.apache.carbondata.core.scan.expression.expressionresult
org.apache.catalina. org.apache.catalina.
org.apache.cocoon. org.apache.cocoon.
org.apache.commons.beanutils org.apache.commons.beanutils
org.apache.commons.codec.
org.apache.commons.collections.comparators. org.apache.commons.collections.comparators.
org.apache.commons.collections.functors org.apache.commons.collections.functors
org.apache.commons.collections.functors. org.apache.commons.collections.functors.
@ -112,6 +124,7 @@ org.apache.commons.collections4.comparators
org.apache.commons.collections4.functors org.apache.commons.collections4.functors
org.apache.commons.collections4.transformer org.apache.commons.collections4.transformer
org.apache.commons.configuration org.apache.commons.configuration
org.apache.commons.configuration2.
org.apache.commons.dbcp org.apache.commons.dbcp
org.apache.commons.fileupload org.apache.commons.fileupload
org.apache.commons.jelly. org.apache.commons.jelly.
@ -130,32 +143,43 @@ org.apache.ibatis.ognl.
org.apache.ibatis.parsing. org.apache.ibatis.parsing.
org.apache.ibatis.reflection. org.apache.ibatis.reflection.
org.apache.ibatis.scripting. org.apache.ibatis.scripting.
org.apache.ignite.cache.
org.apache.ignite.cache.jta. org.apache.ignite.cache.jta.
org.apache.log.output.db.
org.apache.log4j. org.apache.log4j.
org.apache.logging. org.apache.logging.
org.apache.myfaces.context.servlet org.apache.myfaces.context.servlet
org.apache.myfaces.view.facelets.el.
org.apache.openjpa.ee. org.apache.openjpa.ee.
org.apache.shiro.jndi. org.apache.shiro.
org.apache.shiro.realm.
org.apache.tomcat org.apache.tomcat
org.apache.velocity.
org.apache.wicket.util org.apache.wicket.util
org.apache.xalan org.apache.xalan
org.apache.xbean. org.apache.xbean.
org.apache.xpath.xpathcontext org.apache.xpath.
org.apache.zookeeper.
org.aspectj.
org.codehaus.groovy.runtime org.codehaus.groovy.runtime
org.codehaus.jackson. org.codehaus.jackson.
org.datanucleus.store.rdbms.datasource.dbcp.datasources.
org.dom4j.
org.eclipse.jetty. org.eclipse.jetty.
org.geotools.filter.constantexpression org.geotools.filter.
org.h2.jdbcx. org.h2.jdbcx.
org.h2.server. org.h2.server.
org.h2.value.
org.hibernate org.hibernate
org.javasimon. org.javasimon.
org.jaxen. org.jaxen.
org.jboss org.jboss
org.jdom. org.jdom.
org.jdom2.transform. org.jdom2.transform.
org.junit.
org.logicalcobwebs. org.logicalcobwebs.
org.mockito.
org.mortbay.jetty. org.mortbay.jetty.
org.mortbay.log.
org.mozilla.javascript org.mozilla.javascript
org.objectweb.asm. org.objectweb.asm.
org.osjava.sj. org.osjava.sj.
@ -163,5 +187,11 @@ org.python.core
org.quartz. org.quartz.
org.slf4j. org.slf4j.
org.springframework. org.springframework.
org.yaml.snakeyaml.tokens.directivetoken org.thymeleaf.
sun.rmi.server.unicastref org.yaml.snakeyaml.tokens.
pstore.shaded.org.apache.commons.collections.
sun.print.
sun.rmi.server.
sun.rmi.transport.
weblogic.ejb20.internal.
weblogic.jms.common.

View File

@ -1,12 +1,13 @@
package org.apache.dubbo.common.beanutil; package org.apache.dubbo.common.beanutil;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import org.apache.dubbo.rpc.model.person.FullAddress; import org.apache.dubbo.rpc.model.person.FullAddress;
import org.apache.dubbo.rpc.model.person.PersonStatus; import org.apache.dubbo.rpc.model.person.PersonStatus;
import org.apache.dubbo.rpc.model.person.Phone; import org.apache.dubbo.rpc.model.person.Phone;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@ -23,7 +24,7 @@ import java.util.Map;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
public class Bean { public class Bean implements Serializable {
private Class<?> type; private Class<?> type;

View File

@ -16,9 +16,10 @@
*/ */
package org.apache.dubbo.common.model; package org.apache.dubbo.common.model;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
public class Person { public class Person implements Serializable {
byte oneByte = 123; byte oneByte = 123;
private String name = "name1"; private String name = "name1";
private int age = 11; private int age = 11;

View File

@ -17,12 +17,13 @@
package org.apache.dubbo.common.model; package org.apache.dubbo.common.model;
import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
/** /**
* this class has no nullary constructor and some field is primitive * this class has no nullary constructor and some field is primitive
*/ */
public class User { public class User implements Serializable {
private int age; private int age;
private String name; private String name;

View File

@ -16,19 +16,7 @@
*/ */
package org.apache.dubbo.common.utils; package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.model.Person; import java.io.Serializable;
import org.apache.dubbo.common.model.SerializablePerson;
import org.apache.dubbo.common.model.User;
import org.apache.dubbo.common.model.person.BigPerson;
import org.apache.dubbo.common.model.person.FullAddress;
import org.apache.dubbo.common.model.person.PersonInfo;
import org.apache.dubbo.common.model.person.PersonStatus;
import org.apache.dubbo.common.model.person.Phone;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -43,6 +31,19 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.apache.dubbo.common.model.Person;
import org.apache.dubbo.common.model.SerializablePerson;
import org.apache.dubbo.common.model.User;
import org.apache.dubbo.common.model.person.BigPerson;
import org.apache.dubbo.common.model.person.FullAddress;
import org.apache.dubbo.common.model.person.PersonInfo;
import org.apache.dubbo.common.model.person.PersonStatus;
import org.apache.dubbo.common.model.person.Phone;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.alibaba.fastjson.JSONObject;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@ -764,7 +765,7 @@ public class PojoUtilsTest {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
} }
public static class BasicTestData { public static class BasicTestData implements Serializable {
public boolean a; public boolean a;
public char b; public char b;
@ -836,7 +837,7 @@ public class PojoUtilsTest {
} }
public static class Parent { public static class Parent implements Serializable {
public String gender; public String gender;
public String email; public String email;
String name; String name;
@ -881,7 +882,7 @@ public class PojoUtilsTest {
} }
} }
public static class Child { public static class Child implements Serializable {
public String gender; public String gender;
public int age; public int age;
String toy; String toy;
@ -921,7 +922,7 @@ public class PojoUtilsTest {
} }
} }
public static class TestData { public static class TestData implements Serializable {
private Map<String, Child> children = new HashMap<String, Child>(); private Map<String, Child> children = new HashMap<String, Child>();
private List<Child> list = new ArrayList<Child>(); private List<Child> list = new ArrayList<Child>();
@ -950,7 +951,7 @@ public class PojoUtilsTest {
} }
} }
public static class InnerPojo<T> { public static class InnerPojo<T> implements Serializable {
private List<T> list; private List<T> list;
public List<T> getList() { public List<T> getList() {
@ -962,7 +963,7 @@ public class PojoUtilsTest {
} }
} }
public static class ListResult<T> { public static class ListResult<T> implements Serializable {
List<T> result; List<T> result;
public List<T> getResult() { public List<T> getResult() {

View File

@ -16,19 +16,19 @@
*/ */
package org.apache.dubbo.common.utils; package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.constants.CommonConstants;
import javassist.compiler.Javac;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import java.net.Socket; import java.net.Socket;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.apache.dubbo.common.constants.CommonConstants;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javassist.compiler.Javac;
public class SerializeClassCheckerTest { public class SerializeClassCheckerTest {
@BeforeEach @BeforeEach
@ -62,6 +62,26 @@ public class SerializeClassCheckerTest {
}); });
} }
@Test
public void testSerializable1() {
SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance();
Assertions.assertThrows(IllegalArgumentException.class, ()-> serializeClassChecker.validateClass(List.class));
}
@Test
public void testSerializable2() {
System.setProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE, "false");
SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance();
try {
serializeClassChecker.validateClass(List.class);
} catch (Throwable t) {
Assertions.fail(t);
}
System.clearProperty(CommonConstants.CLASS_DESERIALIZE_CHECK_SERIALIZABLE);
}
@Test @Test
public void testAddAllow() { public void testAddAllow() {
System.setProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, Socket.class.getName() + "," + Javac.class.getName()); System.setProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, Socket.class.getName() + "," + Javac.class.getName());

View File

@ -175,7 +175,7 @@
<portlet_version>2.0</portlet_version> <portlet_version>2.0</portlet_version>
<maven_flatten_version>1.1.0</maven_flatten_version> <maven_flatten_version>1.1.0</maven_flatten_version>
<commons_compress_version>1.21</commons_compress_version> <commons_compress_version>1.21</commons_compress_version>
<revision>3.0.13-SNAPSHOT</revision> <revision>3.0.16-SNAPSHOT</revision>
</properties> </properties>
<dependencyManagement> <dependencyManagement>

View File

@ -32,7 +32,7 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<properties> <properties>
<revision>3.0.13-SNAPSHOT</revision> <revision>3.0.16-SNAPSHOT</revision>
<maven_flatten_version>1.1.0</maven_flatten_version> <maven_flatten_version>1.1.0</maven_flatten_version>
<curator_version>5.1.0</curator_version> <curator_version>5.1.0</curator_version>
<zookeeper_version>3.7.0</zookeeper_version> <zookeeper_version>3.7.0</zookeeper_version>

View File

@ -32,7 +32,7 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<properties> <properties>
<revision>3.0.13-SNAPSHOT</revision> <revision>3.0.16-SNAPSHOT</revision>
<maven_flatten_version>1.1.0</maven_flatten_version> <maven_flatten_version>1.1.0</maven_flatten_version>
<curator_version>4.2.0</curator_version> <curator_version>4.2.0</curator_version>
<zookeeper_version>3.4.14</zookeeper_version> <zookeeper_version>3.4.14</zookeeper_version>

View File

@ -42,6 +42,8 @@ import org.apache.dubbo.remoting.transport.ExceedPayloadLimitException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/** /**
* ExchangeCodec. * ExchangeCodec.
@ -167,7 +169,7 @@ public class ExchangeCodec extends TelnetCodec {
data = decodeEventData(channel, CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto), eventPayload); data = decodeEventData(channel, CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto), eventPayload);
} }
} else { } else {
data = decodeResponseData(channel, CodecSupport.deserialize(channel.getUrl(), is, proto), getRequestData(id)); data = decodeResponseData(channel, CodecSupport.deserialize(channel.getUrl(), is, proto), getRequestData(channel, res, id));
} }
res.setResult(data); res.setResult(data);
} else { } else {
@ -209,16 +211,21 @@ public class ExchangeCodec extends TelnetCodec {
} }
} }
protected Object getRequestData(long id) { protected Object getRequestData(Channel channel, Response response, long id) {
DefaultFuture future = DefaultFuture.getFuture(id); DefaultFuture future = DefaultFuture.getFuture(id);
if (future == null) { if (future != null) {
return null; Request req = future.getRequest();
if (req != null) {
return req.getData();
}
} }
Request req = future.getRequest();
if (req == null) { logger.warn("The timeout response finally returned at "
return null; + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
} + ", response status is " + response.getStatus() + ", response id is " + response.getId()
return req.getData(); + (channel == null ? "" : ", channel: " + channel.getLocalAddress()
+ " -> " + channel.getRemoteAddress()) + ", please check provider side for detailed result.");
throw new IllegalArgumentException("Failed to find any request match the response, response id: " + id);
} }
protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException { protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException {
@ -427,7 +434,7 @@ public class ExchangeCodec extends TelnetCodec {
try { try {
if (eventBytes != null) { if (eventBytes != null) {
int dataLen = eventBytes.length; int dataLen = eventBytes.length;
int threshold = ConfigurationUtils.getSystemConfiguration(channel.getUrl().getScopeModel()).getInt("deserialization.event.size", 50); int threshold = ConfigurationUtils.getSystemConfiguration(channel.getUrl().getScopeModel()).getInt("deserialization.event.size", 15);
if (dataLen > threshold) { if (dataLen > threshold) {
throw new IllegalArgumentException("Event data too long, actual size " + threshold + ", threshold " + threshold + " rejected for security consideration."); throw new IllegalArgumentException("Event data too long, actual size " + threshold + ", threshold " + threshold + " rejected for security consideration.");
} }

View File

@ -30,11 +30,13 @@ import org.apache.dubbo.remoting.buffer.ChannelBuffers;
import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Request;
import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.exchange.Response;
import org.apache.dubbo.remoting.exchange.codec.ExchangeCodec; import org.apache.dubbo.remoting.exchange.codec.ExchangeCodec;
import org.apache.dubbo.remoting.exchange.support.DefaultFuture;
import org.apache.dubbo.remoting.telnet.codec.TelnetCodec; import org.apache.dubbo.remoting.telnet.codec.TelnetCodec;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -137,6 +139,8 @@ public class ExchangeCodecTest extends TelnetCodecTest {
@Test @Test
public void test_Decode_Error_Length() throws IOException { public void test_Decode_Error_Length() throws IOException {
DefaultFuture future = DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(0), 100000, null);
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Person person = new Person(); Person person = new Person();
byte[] request = getRequestBytes(person, header); byte[] request = getRequestBytes(person, header);
@ -148,6 +152,8 @@ public class ExchangeCodecTest extends TelnetCodecTest {
Assertions.assertEquals(person, obj.getResult()); Assertions.assertEquals(person, obj.getResult());
//only decode necessary bytes //only decode necessary bytes
Assertions.assertEquals(request.length, buffer.readerIndex()); Assertions.assertEquals(request.length, buffer.readerIndex());
future.cancel();
} }
@Test @Test
@ -226,6 +232,7 @@ public class ExchangeCodecTest extends TelnetCodecTest {
@Test @Test
public void test_Decode_Return_Response_Person() throws IOException { public void test_Decode_Return_Response_Person() throws IOException {
DefaultFuture future = DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(0), 100000, null);
//00000010-response/oneway/hearbeat=false/hessian |20-stats=ok|id=0|length=0 //00000010-response/oneway/hearbeat=false/hessian |20-stats=ok|id=0|length=0
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 2, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 2, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Person person = new Person(); Person person = new Person();
@ -235,6 +242,8 @@ public class ExchangeCodecTest extends TelnetCodecTest {
Assertions.assertEquals(20, obj.getStatus()); Assertions.assertEquals(20, obj.getStatus());
Assertions.assertEquals(person, obj.getResult()); Assertions.assertEquals(person, obj.getResult());
System.out.println(obj); System.out.println(obj);
future.cancel();
} }
@Test //The status input has a problem, and the read information is wrong when the serialization is serialized. @Test //The status input has a problem, and the read information is wrong when the serialization is serialized.
@ -324,6 +333,7 @@ public class ExchangeCodecTest extends TelnetCodecTest {
@Test @Test
public void test_Header_Response_NoSerializationFlag() throws IOException { public void test_Header_Response_NoSerializationFlag() throws IOException {
DefaultFuture future = DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(0), 100000, null);
//00000010-response/oneway/hearbeat=false/noset |20-stats=ok|id=0|length=0 //00000010-response/oneway/hearbeat=false/noset |20-stats=ok|id=0|length=0
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte) 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte) 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Person person = new Person(); Person person = new Person();
@ -333,10 +343,13 @@ public class ExchangeCodecTest extends TelnetCodecTest {
Assertions.assertEquals(20, obj.getStatus()); Assertions.assertEquals(20, obj.getStatus());
Assertions.assertEquals(person, obj.getResult()); Assertions.assertEquals(person, obj.getResult());
System.out.println(obj); System.out.println(obj);
future.cancel();
} }
@Test @Test
public void test_Header_Response_Heartbeat() throws IOException { public void test_Header_Response_Heartbeat() throws IOException {
DefaultFuture future = DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(0), 100000, null);
//00000010-response/oneway/hearbeat=true |20-stats=ok|id=0|length=0 //00000010-response/oneway/hearbeat=true |20-stats=ok|id=0|length=0
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, 0x02, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Person person = new Person(); Person person = new Person();
@ -346,6 +359,8 @@ public class ExchangeCodecTest extends TelnetCodecTest {
Assertions.assertEquals(20, obj.getStatus()); Assertions.assertEquals(20, obj.getStatus());
Assertions.assertEquals(person, obj.getResult()); Assertions.assertEquals(person, obj.getResult());
System.out.println(obj); System.out.println(obj);
future.cancel();
} }
@Test @Test
@ -371,6 +386,7 @@ public class ExchangeCodecTest extends TelnetCodecTest {
@Test @Test
public void test_Encode_Response() throws IOException { public void test_Encode_Response() throws IOException {
DefaultFuture future = DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(1001), 100000, null);
ChannelBuffer encodeBuffer = ChannelBuffers.dynamicBuffer(1024); ChannelBuffer encodeBuffer = ChannelBuffers.dynamicBuffer(1024);
Channel channel = getClientSideChannel(url); Channel channel = getClientSideChannel(url);
Response response = new Response(); Response response = new Response();
@ -396,6 +412,7 @@ public class ExchangeCodecTest extends TelnetCodecTest {
// encode response verson ?? // encode response verson ??
// Assertions.assertEquals(response.getProtocolVersion(), obj.getVersion()); // Assertions.assertEquals(response.getProtocolVersion(), obj.getVersion());
future.cancel();
} }
@Test @Test

View File

@ -101,12 +101,12 @@ public class DubboCodec extends ExchangeCodec {
DecodeableRpcResult result; DecodeableRpcResult result;
if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) { if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {
result = new DecodeableRpcResult(channel, res, is, result = new DecodeableRpcResult(channel, res, is,
(Invocation) getRequestData(id), proto); (Invocation) getRequestData(channel, res, id), proto);
result.decode(); result.decode();
} else { } else {
result = new DecodeableRpcResult(channel, res, result = new DecodeableRpcResult(channel, res,
new UnsafeByteArrayInputStream(readMessageData(is)), new UnsafeByteArrayInputStream(readMessageData(is)),
(Invocation) getRequestData(id), proto); (Invocation) getRequestData(channel, res, id), proto);
} }
data = result; data = result;
} }

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.remoting.buffer.ChannelBuffer;
import org.apache.dubbo.remoting.buffer.ChannelBuffers; import org.apache.dubbo.remoting.buffer.ChannelBuffers;
import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Request;
import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.exchange.Response;
import org.apache.dubbo.remoting.exchange.support.DefaultFuture;
import org.apache.dubbo.remoting.exchange.support.MultiMessage; import org.apache.dubbo.remoting.exchange.support.MultiMessage;
import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.AppResponse;
import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.RpcInvocation;
@ -32,7 +33,9 @@ import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import static org.apache.dubbo.rpc.Constants.INPUT_KEY; import static org.apache.dubbo.rpc.Constants.INPUT_KEY;
import static org.apache.dubbo.rpc.Constants.OUTPUT_KEY; import static org.apache.dubbo.rpc.Constants.OUTPUT_KEY;
@ -45,23 +48,25 @@ public class DubboCountCodecTest {
ChannelBuffer buffer = ChannelBuffers.buffer(1024); ChannelBuffer buffer = ChannelBuffers.buffer(1024);
Channel channel = new MockChannel(); Channel channel = new MockChannel();
Assertions.assertEquals(Codec2.DecodeResult.NEED_MORE_INPUT, dubboCountCodec.decode(channel, buffer)); Assertions.assertEquals(Codec2.DecodeResult.NEED_MORE_INPUT, dubboCountCodec.decode(channel, buffer));
List<DefaultFuture> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
Request request = new Request(1); Request request = new Request(i);
futures.add(DefaultFuture.newFuture(channel, request, 1000, null));
RpcInvocation rpcInvocation = new RpcInvocation(null, "echo", DemoService.class.getName(), "", new Class<?>[]{String.class}, new String[]{"yug"}); RpcInvocation rpcInvocation = new RpcInvocation(null, "echo", DemoService.class.getName(), "", new Class<?>[]{String.class}, new String[]{"yug"});
request.setData(rpcInvocation); request.setData(rpcInvocation);
dubboCountCodec.encode(channel, buffer, request); dubboCountCodec.encode(channel, buffer, request);
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
Response response = new Response(1); Response response = new Response(i);
AppResponse appResponse = new AppResponse(i); AppResponse appResponse = new AppResponse(i);
response.setResult(appResponse); response.setResult(appResponse);
dubboCountCodec.encode(channel, buffer, response); dubboCountCodec.encode(channel, buffer, response);
} }
MultiMessage multiMessage = (MultiMessage) dubboCountCodec.decode(channel, buffer); MultiMessage multiMessage = (MultiMessage) dubboCountCodec.decode(channel, buffer);
Assertions.assertEquals(multiMessage.size(), 20); Assertions.assertEquals(20, multiMessage.size());
int requestCount = 0; int requestCount = 0;
int responseCount = 0; int responseCount = 0;
Iterator iterator = multiMessage.iterator(); Iterator iterator = multiMessage.iterator();
@ -79,6 +84,8 @@ public class DubboCountCodecTest {
} }
Assertions.assertEquals(requestCount, 10); Assertions.assertEquals(requestCount, 10);
Assertions.assertEquals(responseCount, 10); Assertions.assertEquals(responseCount, 10);
futures.forEach(DefaultFuture::cancel);
} }
} }

View File

@ -129,7 +129,7 @@
<checkstyle_unix.skip>true</checkstyle_unix.skip> <checkstyle_unix.skip>true</checkstyle_unix.skip>
<rat.skip>true</rat.skip> <rat.skip>true</rat.skip>
<jacoco.skip>true</jacoco.skip> <jacoco.skip>true</jacoco.skip>
<revision>3.0.13-SNAPSHOT</revision> <revision>3.0.16-SNAPSHOT</revision>
</properties> </properties>
<modules> <modules>