You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConnectorResourceHandler.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.server;
  17. import java.io.IOException;
  18. import java.util.Map;
  19. import java.util.logging.Level;
  20. import java.util.logging.Logger;
  21. import java.util.regex.Matcher;
  22. import java.util.regex.Pattern;
  23. import javax.servlet.http.HttpServletResponse;
  24. import com.vaadin.shared.ApplicationConstants;
  25. import com.vaadin.ui.UI;
  26. import com.vaadin.util.CurrentInstance;
  27. public class ConnectorResourceHandler implements RequestHandler {
  28. // APP/connector/[uiid]/[cid]/[filename.xyz]
  29. private static final String CONNECTOR_RESOURCE_PREFIX = "/"
  30. + ApplicationConstants.APP_PATH + "/"
  31. + ConnectorResource.CONNECTOR_PATH + "/";
  32. private static final Pattern CONNECTOR_RESOURCE_PATTERN = Pattern
  33. .compile("^" + CONNECTOR_RESOURCE_PREFIX + "(\\d+)/(\\d+)/(.*)");
  34. private static Logger getLogger() {
  35. return Logger.getLogger(ConnectorResourceHandler.class.getName());
  36. }
  37. @Override
  38. public boolean handleRequest(VaadinSession session, VaadinRequest request,
  39. VaadinResponse response) throws IOException {
  40. String requestPath = request.getPathInfo();
  41. if (requestPath == null
  42. || !requestPath.startsWith(CONNECTOR_RESOURCE_PREFIX)) {
  43. return false;
  44. }
  45. Matcher matcher = CONNECTOR_RESOURCE_PATTERN.matcher(requestPath);
  46. if (!matcher.matches()) {
  47. // This is a connector resource request based on the prefix but the
  48. // pattern did not match
  49. warnAboutInvalidURLEncoding(requestPath);
  50. response.sendError(HttpServletResponse.SC_NOT_FOUND,
  51. "Connector resource not found");
  52. return true;
  53. }
  54. String uiId = matcher.group(1);
  55. String cid = matcher.group(2);
  56. String key = matcher.group(3);
  57. session.lock();
  58. UI ui;
  59. ClientConnector connector;
  60. try {
  61. ui = session.getUIById(Integer.parseInt(uiId));
  62. if (ui == null) {
  63. return error(request, response,
  64. "Ignoring connector request for no-existent root "
  65. + uiId);
  66. }
  67. connector = ui.getConnectorTracker().getConnector(cid);
  68. if (connector == null) {
  69. return error(request, response,
  70. "Ignoring connector request for no-existent connector "
  71. + cid + " in root " + uiId);
  72. }
  73. } finally {
  74. session.unlock();
  75. }
  76. Map<Class<?>, CurrentInstance> oldInstances = CurrentInstance
  77. .setCurrent(ui);
  78. try {
  79. if (!connector.handleConnectorRequest(request, response, key)) {
  80. return error(request, response,
  81. connector.getClass().getSimpleName() + " ("
  82. + connector.getConnectorId()
  83. + ") did not handle connector request for "
  84. + key);
  85. }
  86. } catch (Exception e) {
  87. session.lock();
  88. try {
  89. session.getCommunicationManager()
  90. .handleConnectorRelatedException(connector, e);
  91. } finally {
  92. session.unlock();
  93. }
  94. } finally {
  95. CurrentInstance.restoreInstances(oldInstances);
  96. }
  97. return true;
  98. }
  99. private boolean loggedDecodingWarning = false;
  100. private void warnAboutInvalidURLEncoding(String requestPath) {
  101. if (requestPath.contains("\n") || requestPath.indexOf(0x85) != -1) {
  102. // What, path info should not contain a new line or UTF-8 Next Line
  103. // (NEL) character, but it does in
  104. // Tomcat 7 with default configuration in some cases (URL is encoded
  105. // by the browser as UTF-8 and decoded as ISO-8859-1 by Tomcat)
  106. if (!loggedDecodingWarning) {
  107. loggedDecodingWarning = true;
  108. getLogger().warning(
  109. "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: "
  110. + requestPath + ")");
  111. }
  112. }
  113. }
  114. private static boolean error(VaadinRequest request, VaadinResponse response,
  115. String logMessage) throws IOException {
  116. getLogger().log(Level.WARNING, logMessage);
  117. response.sendError(HttpServletResponse.SC_NOT_FOUND,
  118. request.getPathInfo() + " can not be found");
  119. // Request handled (though not in a nice way)
  120. return true;
  121. }
  122. }