com.vaadin.server.ConnectorResourceHandler Maven / Gradle / Ivy
/*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.server;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
public class ConnectorResourceHandler implements RequestHandler {
// APP/connector/[uiid]/[cid]/[filename.xyz]
private static final String CONNECTOR_RESOURCE_PREFIX = "/"
+ ApplicationConstants.APP_PATH + "/"
+ ConnectorResource.CONNECTOR_PATH + "/";
private static final Pattern CONNECTOR_RESOURCE_PATTERN = Pattern
.compile("^" + CONNECTOR_RESOURCE_PREFIX + "(\\d+)/(\\d+)/(.*)");
private static Logger getLogger() {
return Logger.getLogger(ConnectorResourceHandler.class.getName());
}
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request,
VaadinResponse response) throws IOException {
String requestPath = request.getPathInfo();
if (requestPath == null
|| !requestPath.startsWith(CONNECTOR_RESOURCE_PREFIX)) {
return false;
}
Matcher matcher = CONNECTOR_RESOURCE_PATTERN.matcher(requestPath);
if (!matcher.matches()) {
// This is a connector resource request based on the prefix but the
// pattern did not match
warnAboutInvalidURLEncoding(requestPath);
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"Connector resource not found");
return true;
}
String uiId = matcher.group(1);
String cid = matcher.group(2);
String key = matcher.group(3);
session.lock();
UI ui;
ClientConnector connector;
try {
ui = session.getUIById(Integer.parseInt(uiId));
if (ui == null) {
return error(request, response,
"Ignoring connector request for no-existent root "
+ uiId);
}
connector = ui.getConnectorTracker().getConnector(cid);
if (connector == null) {
return error(request, response,
"Ignoring connector request for no-existent connector "
+ cid + " in root " + uiId);
}
} finally {
session.unlock();
}
Map, CurrentInstance> oldInstances = CurrentInstance
.setCurrent(ui);
try {
if (!connector.handleConnectorRequest(request, response, key)) {
return error(request, response,
connector.getClass().getSimpleName() + " ("
+ connector.getConnectorId()
+ ") did not handle connector request for "
+ key);
}
} catch (Exception e) {
session.lock();
try {
session.getCommunicationManager()
.handleConnectorRelatedException(connector, e);
} finally {
session.unlock();
}
} finally {
CurrentInstance.restoreInstances(oldInstances);
}
return true;
}
private boolean loggedDecodingWarning = false;
private void warnAboutInvalidURLEncoding(String requestPath) {
if (requestPath.contains("\n") || requestPath.indexOf(0x85) != -1) {
// What, path info should not contain a new line or UTF-8 Next Line
// (NEL) character, but it does in
// Tomcat 7 with default configuration in some cases (URL is encoded
// by the browser as UTF-8 and decoded as ISO-8859-1 by Tomcat)
if (!loggedDecodingWarning) {
loggedDecodingWarning = true;
getLogger().warning(
"Request path contains a new line character. This typically means that the server is incorrectly configured to use something else than UTF-8 for URL decoding (requestPath: "
+ requestPath + ")");
}
}
}
private static boolean error(VaadinRequest request, VaadinResponse response,
String logMessage) throws IOException {
getLogger().log(Level.WARNING, logMessage);
response.sendError(HttpServletResponse.SC_NOT_FOUND,
request.getPathInfo() + " can not be found");
// Request handled (though not in a nice way)
return true;
}
}