String extraParams = UIConstants.UI_ID_PARAMETER + "="
+ connection.getConfiguration().getUIId();
- String csrfToken = connection.getMessageHandler().getCsrfToken();
- if (!csrfToken.equals(ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) {
- extraParams += "&" + ApplicationConstants.CSRF_TOKEN_PARAMETER + "="
- + csrfToken;
+ String pushId = connection.getMessageHandler().getPushId();
+ if (pushId != null) {
+ extraParams += "&" + ApplicationConstants.PUSH_ID_PARAMETER + "="
+ + pushId;
}
// uri is needed to identify the right connection when closing
// will hold the CSRF token once received
private String csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ // holds the push identifier once received
+ private String pushId = null;
+
/** Timer for automatic redirect to SessionExpiredURL */
private Timer redirectTimer;
csrfToken = json
.getString(ApplicationConstants.UIDL_SECURITY_TOKEN_ID);
}
+
+ // Get push id if present
+ if (json.containsKey(ApplicationConstants.UIDL_PUSH_ID)) {
+ pushId = json.getString(ApplicationConstants.UIDL_PUSH_ID);
+ }
+
getLogger().info(" * Handling resources from server");
if (json.containsKey("resources")) {
}
}
handleUIDLDuration
- .logDuration(" * Handling resources from server completed", 10);
+ .logDuration(" * Handling resources from server completed", 10);
getLogger().info(" * Handling type inheritance map from server");
if (json.containsKey("dd")) {
// response contains data for drag and drop service
VDragAndDropManager.get()
- .handleServerResponse(json.getValueMap("dd"));
+ .handleServerResponse(json.getValueMap("dd"));
}
unregisterRemovedConnectors(
if (child instanceof ComponentConnector
&& ((ComponentConnector) child)
- .delegateCaptionHandling()) {
+ .delegateCaptionHandling()) {
ServerConnector parent = child.getParent();
if (parent instanceof HasComponentsConnector) {
Profiler.enter(
"HasComponentsConnector.updateCaption");
((HasComponentsConnector) parent)
- .updateCaption((ComponentConnector) child);
+ .updateCaption((ComponentConnector) child);
Profiler.leave(
"HasComponentsConnector.updateCaption");
}
throw new RuntimeException(
"Missing data needed to invoke @DelegateToWidget for "
+ component.getClass().getSimpleName(),
- e);
+ e);
}
}
}
getLogger().info("* Unregistered " + detachedArray.length()
- + " connectors");
+ + " connectors");
Profiler.leave("unregisterRemovedConnectors");
}
}
getLogger()
- .info(" * Passing UIDL to Vaadin 6 style connectors");
+ .info(" * Passing UIDL to Vaadin 6 style connectors");
// update paintables
for (int i = 0; i < length; i++) {
try {
} else if (legacyConnector == null) {
getLogger().severe(
"Received update for " + uidl.getTag()
- + ", but there is no such paintable ("
- + connectorId + ") rendered.");
+ + ", but there is no such paintable ("
+ + connectorId + ") rendered.");
} else {
getLogger()
- .severe("Server sent Vaadin 6 style updates for "
- + Util.getConnectorString(
- legacyConnector)
- + " but this is not a Vaadin 6 Paintable");
+ .severe("Server sent Vaadin 6 style updates for "
+ + Util.getConnectorString(
+ legacyConnector)
+ + " but this is not a Vaadin 6 Paintable");
}
} catch (final Throwable e) {
if (connector instanceof HasJavaScriptConnectorHelper) {
((HasJavaScriptConnectorHelper) connector)
- .getJavascriptConnectorHelper()
- .setNativeState(jso);
+ .getJavascriptConnectorHelper()
+ .setNativeState(jso);
}
SharedState state = connector.getState();
newChildren.add(childConnector);
if (childConnector instanceof ComponentConnector) {
newComponents
- .add((ComponentConnector) childConnector);
+ .add((ComponentConnector) childConnector);
} else if (!(childConnector instanceof AbstractExtensionConnector)) {
throw new IllegalStateException(Util
.getConnectorString(childConnector)
Profiler.enter(
prefix + "recursivelyDetach clear children and parent");
connector
- .setChildren(Collections.<ServerConnector> emptyList());
+ .setChildren(Collections.<ServerConnector> emptyList());
connector.setParent(null);
Profiler.leave(
prefix + "recursivelyDetach clear children and parent");
Profiler.enter("handleRpcInvocations");
getLogger()
- .info(" * Performing server to client RPC calls");
+ .info(" * Performing server to client RPC calls");
JsonArray rpcCalls = Util
.jso2json(json.getJavaScriptObject("rpc"));
return csrfToken;
}
+ /**
+ * Gets the push connection identifier for this session. Used when
+ * establishing a push connection with the client.
+ *
+ * @return the push connection identifier string
+ * @since 7.7.11
+ */
+ public String getPushId() {
+ return pushId;
+ }
+
/**
* Checks whether state changes are currently being processed. Certain
* operations are not allowed when the internal state of the application
private void refreshLock() {
assert lock == null || lock == service.getSessionLock(
session) : "Cannot change the lock from one instance to another";
- assert hasLock(service, session);
- lock = service.getSessionLock(session);
+ assert hasLock(service, session);
+ lock = service.getSessionLock(session);
}
public void setCommunicationManager(
private final String csrfToken = UUID.randomUUID().toString();
+ private final String pushId = UUID.randomUUID().toString();
+
/**
* Generate an id for the given Connector. Connectors must not call this
* method more than once, the first time they need an id.
getLogger().log(Level.SEVERE,
"Exception while cleaning connector map for ui "
+ ui.getUIId(),
- e);
+ e);
} catch (AssertionError e) {
getLogger().log(Level.SEVERE,
"Exception while cleaning connector map for ui "
+ ui.getUIId(),
- e);
+ e);
}
}
}
}
if (value != null && !type.isInstance(value)) {
throw new IllegalArgumentException("value of type " + type.getName()
- + " expected but got " + value.getClass().getName());
+ + " expected but got " + value.getClass().getName());
}
setAttribute(type.getName(), value);
}
protected void setState(State state) {
assert hasLock();
assert this.state.isValidChange(state) : "Invalid session state change "
- + this.state + "->" + state;
+ + this.state + "->" + state;
this.state = state;
}
return csrfToken;
}
+ /**
+ * Gets the push connection identifier for this session. Used when
+ * establishing a push connection with the client.
+ *
+ * @return the push connection identifier string
+ * @since 7.7.11
+ */
+ public String getPushId() {
+ assert hasLock();
+ return pushId;
+ }
+
/**
* Override default deserialization logic to account for transient
* {@link #pendingAccessQueue}.
}
String requestToken = resource.getRequest()
- .getParameter(ApplicationConstants.CSRF_TOKEN_PARAMETER);
- if (!VaadinService.isCsrfTokenValid(session, requestToken)) {
+ .getParameter(ApplicationConstants.PUSH_ID_PARAMETER);
+ if (!isPushIdValid(session, requestToken)) {
getLogger().log(Level.WARNING,
- "Invalid CSRF token in new connection received from {0}",
+ "Invalid identifier in new connection received from {0}",
resource.getRequest().getRemoteHost());
// Refresh on client side, create connection just for
// sending a message
return Logger.getLogger(PushHandler.class.getName());
}
+ /**
+ * Checks whether a given push id matches the session's push id.
+ *
+ * @param session
+ * the vaadin session for which the check should be done
+ * @param requestPushId
+ * the push id provided in the request
+ * @return {@code true} if the id is valid, {@code false} otherwise
+ */
+ private static boolean isPushIdValid(VaadinSession session,
+ String requestPushId) {
+
+ String sessionPushId = session.getPushId();
+ if (requestPushId == null || !requestPushId.equals(sessionPushId)) {
+ return false;
+ }
+ return true;
+ }
+
/**
* Called when a new push connection is requested to be opened by the client
*
session.addUI(ui);
if (initException != null) {
ui.getSession().getCommunicationManager()
- .handleConnectorRelatedException(ui, initException);
+ .handleConnectorRelatedException(ui, initException);
}
// Warn if the window can't be preserved
if (embedId == null
if (session.getConfiguration().isXsrfProtectionEnabled()) {
writer.write(getSecurityKeyUIDL(session));
}
+ writer.write(getPushIdUIDL(session));
new UidlWriter().write(uI, writer, false);
writer.write("}");
String seckey = session.getCsrfToken();
return "\"" + ApplicationConstants.UIDL_SECURITY_TOKEN_ID + "\":\""
- + seckey + "\",";
+ + seckey + "\",";
+ }
+
+ /**
+ * Gets the push connection identifier as UIDL.
+ *
+ * @param session
+ * the vaadin session to which the security key belongs
+ * @return the push identifier UIDL
+ * @since 7.7.11
+ */
+ private static String getPushIdUIDL(VaadinSession session) {
+ return "\"" + ApplicationConstants.UIDL_PUSH_ID + "\":\""
+ + session.getPushId() + "\",";
}
private static final Logger getLogger() {
public static final String UIDL_SECURITY_TOKEN_ID = "Vaadin-Security-Key";
+ public static final String UIDL_PUSH_ID = "Vaadin-Push-ID";
+
@Deprecated
public static final String UPDATE_VARIABLE_INTERFACE = "v";
@Deprecated
*/
public static final String CSRF_TOKEN_PARAMETER = "v-csrfToken";
+ /**
+ * Name of the parameter used to transmit the push connection identifier.
+ *
+ * @since 7.7.11
+ */
+ public static final String PUSH_ID_PARAMETER = "v-pushId";
+
/**
* The name of the parameter used to transmit RPC invocations
*