summaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-11-20 10:44:45 +0200
committerLeif Åstrand <leif@vaadin.com>2012-11-20 10:47:09 +0200
commitd0d84ec68f2b786a39bff36d091c9b256c9e42c3 (patch)
treecbf5d52bd5ee7e66651817d178e025ca85980cf0 /server/src
parent512b541b3edb1dbc919dd1fa757965a766c603ad (diff)
downloadvaadin-framework-d0d84ec68f2b786a39bff36d091c9b256c9e42c3.tar.gz
vaadin-framework-d0d84ec68f2b786a39bff36d091c9b256c9e42c3.zip
Only process RPC invocation if there's a handler for it (#10134)
* RpcManagers lookup by String instead of Class to avoid loading the class sent by the client * Some generics tightened to only accept ServerRpc instances * Remove RpcTarget as it is only supported for ClientConnector Change-Id: I264d58f373db7ea3258cbc28dfc0fa1ec952723d
Diffstat (limited to 'server/src')
-rw-r--r--server/src/com/vaadin/server/AbstractClientConnector.java24
-rw-r--r--server/src/com/vaadin/server/AbstractCommunicationManager.java50
-rw-r--r--server/src/com/vaadin/server/AbstractJavaScriptExtension.java4
-rw-r--r--server/src/com/vaadin/server/ClientConnector.java12
-rw-r--r--server/src/com/vaadin/server/DragAndDropService.java2
-rw-r--r--server/src/com/vaadin/server/RpcTarget.java38
-rw-r--r--server/src/com/vaadin/server/ServerRpcManager.java9
-rw-r--r--server/src/com/vaadin/server/ServerRpcMethodInvocation.java29
-rw-r--r--server/src/com/vaadin/ui/AbstractJavaScriptComponent.java4
9 files changed, 75 insertions, 97 deletions
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java
index 2e0b72b08a..3762e90d05 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/com/vaadin/server/AbstractClientConnector.java
@@ -55,10 +55,10 @@ import com.vaadin.ui.UI;
public abstract class AbstractClientConnector implements ClientConnector,
MethodEventSource {
/**
- * A map from client to server RPC interface class to the RPC call manager
- * that handles incoming RPC calls for that interface.
+ * A map from client to server RPC interface class name to the RPC call
+ * manager that handles incoming RPC calls for that interface.
*/
- private Map<Class<?>, RpcManager> rpcManagerMap = new HashMap<Class<?>, RpcManager>();
+ private Map<String, RpcManager> rpcManagerMap = new HashMap<String, RpcManager>();
/**
* A map from server to client RPC interface class to the RPC proxy that
@@ -122,8 +122,9 @@ public abstract class AbstractClientConnector implements ClientConnector,
* RPC interface class for which the implementation should be
* registered
*/
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
- rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager<T>(
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
+ rpcManagerMap.put(rpcInterfaceType.getName(), new ServerRpcManager<T>(
implementation, rpcInterfaceType));
}
@@ -333,18 +334,9 @@ public abstract class AbstractClientConnector implements ClientConnector,
requestRepaint();
}
- /**
- * @see RpcTarget#getRpcManager(Class)
- *
- * @param rpcInterface
- * RPC interface for which a call was made
- * @return RPC Manager handling calls for the interface
- *
- * @since 7.0
- */
@Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
- return rpcManagerMap.get(rpcInterface);
+ public RpcManager getRpcManager(String rpcInterfaceName) {
+ return rpcManagerMap.get(rpcInterfaceName);
}
@Override
diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java
index 834d7d8a17..0655ad6e74 100644
--- a/server/src/com/vaadin/server/AbstractCommunicationManager.java
+++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java
@@ -75,6 +75,7 @@ import com.vaadin.shared.JavaScriptConnectorState;
import com.vaadin.shared.Version;
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.communication.UidlValue;
import com.vaadin.shared.ui.ui.UIConstants;
@@ -1662,17 +1663,6 @@ public abstract class AbstractCommunicationManager implements Serializable {
final ClientConnector connector = getConnector(uI,
invocation.getConnectorId());
- if (connector == null) {
- getLogger().log(
- Level.WARNING,
- "RPC call to " + invocation.getInterfaceName()
- + "." + invocation.getMethodName()
- + " received for connector "
- + invocation.getConnectorId()
- + " but no such connector could be found");
- continue;
- }
-
if (!enabledConnectors.contains(connector)) {
if (invocation instanceof LegacyChangeVariablesInvocation) {
@@ -1790,8 +1780,9 @@ public abstract class AbstractCommunicationManager implements Serializable {
MethodInvocation invocation = parseInvocation(invocationJson,
previousInvocation, connectorTracker);
if (invocation != null) {
- // Can be null iff the invocation was a legacy invocation and it
- // was merged with the previous one
+ // Can be null if the invocation was a legacy invocation and it
+ // was merged with the previous one or if the invocation was
+ // rejected because of an error.
invocations.add(invocation);
previousInvocation = invocation;
}
@@ -1806,6 +1797,15 @@ public abstract class AbstractCommunicationManager implements Serializable {
String interfaceName = invocationJson.getString(1);
String methodName = invocationJson.getString(2);
+ if (connectorTracker.getConnector(connectorId) == null) {
+ getLogger().log(
+ Level.WARNING,
+ "RPC call to " + interfaceName + "." + methodName
+ + " received for connector " + connectorId
+ + " but no such connector could be found");
+ return null;
+ }
+
JSONArray parametersJson = invocationJson.getJSONArray(3);
if (LegacyChangeVariablesInvocation.isLegacyVariableChange(
@@ -1855,8 +1855,30 @@ public abstract class AbstractCommunicationManager implements Serializable {
String connectorId, String interfaceName, String methodName,
JSONArray parametersJson, ConnectorTracker connectorTracker)
throws JSONException {
+ ClientConnector connector = connectorTracker.getConnector(connectorId);
+
+ RpcManager rpcManager = connector.getRpcManager(interfaceName);
+ if (!(rpcManager instanceof ServerRpcManager)) {
+ /*
+ * Security: Don't even decode the json parameters if no RpcManager
+ * corresponding to the received method invocation has been
+ * registered.
+ */
+ getLogger().warning(
+ "Ignoring RPC call to " + interfaceName + "." + methodName
+ + " in connector " + connector.getClass().getName()
+ + "(" + connectorId
+ + ") as no RPC implementation is regsitered");
+ return null;
+ }
+
+ // Use interface from RpcManager instead of loading the class based on
+ // the string name to avoid problems with OSGi
+ Class<? extends ServerRpc> rpcInterface = ((ServerRpcManager<?>) rpcManager)
+ .getRpcInterface();
+
ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation(
- connectorId, interfaceName, methodName, parametersJson.length());
+ connectorId, rpcInterface, methodName, parametersJson.length());
Object[] parameters = new Object[parametersJson.length()];
Type[] declaredRpcMethodParameterTypes = invocation.getMethod()
diff --git a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
index 1f67631203..af814e6c19 100644
--- a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
+++ b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java
@@ -17,6 +17,7 @@
package com.vaadin.server;
import com.vaadin.shared.JavaScriptExtensionState;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.ui.JavaScriptFunction;
/**
@@ -125,7 +126,8 @@ public abstract class AbstractJavaScriptExtension extends AbstractExtension {
this);
@Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
super.registerRpc(implementation, rpcInterfaceType);
callbackHelper.registerRpc(rpcInterfaceType);
}
diff --git a/server/src/com/vaadin/server/ClientConnector.java b/server/src/com/vaadin/server/ClientConnector.java
index b38f2a9037..b46ef58fcd 100644
--- a/server/src/com/vaadin/server/ClientConnector.java
+++ b/server/src/com/vaadin/server/ClientConnector.java
@@ -36,7 +36,7 @@ import com.vaadin.ui.UI;
* @since 7.0.0
*
*/
-public interface ClientConnector extends Connector, RpcTarget {
+public interface ClientConnector extends Connector {
/**
* Returns the list of pending server to client RPC calls and clears the
* list.
@@ -239,4 +239,14 @@ public interface ClientConnector extends Connector, RpcTarget {
*/
public boolean handleConnectorRequest(VaadinRequest request,
VaadinResponse response, String path) throws IOException;
+
+ /**
+ * Returns the RPC manager instance to use when receiving calls for an RPC
+ * interface.
+ *
+ * @param rpcInterfaceName
+ * name of the interface for which the call was made
+ * @return RpcManager or null if none found for the interface
+ */
+ public RpcManager getRpcManager(String rpcInterfaceName);
}
diff --git a/server/src/com/vaadin/server/DragAndDropService.java b/server/src/com/vaadin/server/DragAndDropService.java
index 69ab997b18..a864f8fb16 100644
--- a/server/src/com/vaadin/server/DragAndDropService.java
+++ b/server/src/com/vaadin/server/DragAndDropService.java
@@ -252,7 +252,7 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
}
@Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
+ public RpcManager getRpcManager(String interfaceName) {
// TODO Use rpc for drag'n'drop
return null;
}
diff --git a/server/src/com/vaadin/server/RpcTarget.java b/server/src/com/vaadin/server/RpcTarget.java
deleted file mode 100644
index c491707995..0000000000
--- a/server/src/com/vaadin/server/RpcTarget.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.server;
-
-import java.io.Serializable;
-
-/**
- * Marker interface for server side classes that can receive RPC calls.
- *
- * This plays a role similar to that of {@link VariableOwner}.
- *
- * @since 7.0
- */
-public interface RpcTarget extends Serializable {
- /**
- * Returns the RPC manager instance to use when receiving calls for an RPC
- * interface.
- *
- * @param rpcInterface
- * interface for which the call was made
- * @return RpcManager or null if none found for the interface
- */
- public RpcManager getRpcManager(Class<?> rpcInterface);
-}
diff --git a/server/src/com/vaadin/server/ServerRpcManager.java b/server/src/com/vaadin/server/ServerRpcManager.java
index 8ef165e084..c063761c7f 100644
--- a/server/src/com/vaadin/server/ServerRpcManager.java
+++ b/server/src/com/vaadin/server/ServerRpcManager.java
@@ -24,6 +24,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.vaadin.shared.Connector;
+import com.vaadin.shared.communication.ServerRpc;
/**
* Server side RPC manager that handles RPC calls coming from the client.
@@ -34,7 +35,7 @@ import com.vaadin.shared.Connector;
*
* @since 7.0
*/
-public class ServerRpcManager<T> implements RpcManager {
+public class ServerRpcManager<T extends ServerRpc> implements RpcManager {
private final T implementation;
private final Class<T> rpcInterface;
@@ -80,10 +81,10 @@ public class ServerRpcManager<T> implements RpcManager {
* method invocation to perform
* @throws RpcInvocationException
*/
- public static void applyInvocation(RpcTarget target,
+ public static void applyInvocation(ClientConnector target,
ServerRpcMethodInvocation invocation) throws RpcInvocationException {
- RpcManager manager = target.getRpcManager(invocation
- .getInterfaceClass());
+ RpcManager manager = target
+ .getRpcManager(invocation.getInterfaceName());
if (manager != null) {
manager.applyInvocation(invocation);
} else {
diff --git a/server/src/com/vaadin/server/ServerRpcMethodInvocation.java b/server/src/com/vaadin/server/ServerRpcMethodInvocation.java
index 761db687bb..3af58fa351 100644
--- a/server/src/com/vaadin/server/ServerRpcMethodInvocation.java
+++ b/server/src/com/vaadin/server/ServerRpcMethodInvocation.java
@@ -29,33 +29,20 @@ public class ServerRpcMethodInvocation extends MethodInvocation {
private final Method method;
- private Class<? extends ServerRpc> interfaceClass;
+ private final Class<? extends ServerRpc> interfaceClass;
- public ServerRpcMethodInvocation(String connectorId, String interfaceName,
- String methodName, int parameterCount) {
- super(connectorId, interfaceName, methodName);
+ public ServerRpcMethodInvocation(String connectorId,
+ Class<? extends ServerRpc> interfaceClass, String methodName,
+ int parameterCount) {
+ super(connectorId, interfaceClass.getName(), methodName);
+
+ assert ServerRpc.class.isAssignableFrom(interfaceClass);
+ this.interfaceClass = interfaceClass;
- interfaceClass = findClass();
method = findInvocationMethod(interfaceClass, methodName,
parameterCount);
}
- private Class<? extends ServerRpc> findClass() {
- try {
- Class<?> rpcInterface = Class.forName(getInterfaceName());
- if (!ServerRpc.class.isAssignableFrom(rpcInterface)) {
- throw new IllegalArgumentException("The interface "
- + getInterfaceName() + "is not a server RPC interface.");
- }
- return (Class<? extends ServerRpc>) rpcInterface;
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("The server RPC interface "
- + getInterfaceName() + " could not be found", e);
- } finally {
-
- }
- }
-
public Class<? extends ServerRpc> getInterfaceClass() {
return interfaceClass;
}
diff --git a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
index 47420334d7..91547dc79f 100644
--- a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
+++ b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java
@@ -16,6 +16,7 @@
package com.vaadin.ui;
import com.vaadin.server.JavaScriptCallbackHelper;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.ui.JavaScriptComponentState;
/**
@@ -128,7 +129,8 @@ public abstract class AbstractJavaScriptComponent extends AbstractComponent {
this);
@Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
super.registerRpc(implementation, rpcInterfaceType);
callbackHelper.registerRpc(rpcInterfaceType);
}