diff options
author | Joakim Erdfelt | 2015-12-17 18:42:27 +0000 |
---|---|---|
committer | Joakim Erdfelt | 2015-12-17 18:42:27 +0000 |
commit | 3bec195d080a32f8410816b605136da9fc9ff391 (patch) | |
tree | 4d5cc92d5ab9236ad54af52b274a2d5f6e9a71b1 /jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty | |
parent | 7c5bec1b48db95854965c13c203a0e23373c88d6 (diff) | |
download | org.eclipse.jetty.project-3bec195d080a32f8410816b605136da9fc9ff391.tar.gz org.eclipse.jetty.project-3bec195d080a32f8410816b605136da9fc9ff391.tar.xz org.eclipse.jetty.project-3bec195d080a32f8410816b605136da9fc9ff391.zip |
484440 - Swap WebSocket PathMappings for new jetty-http PathMappings
+ Deprecated jetty-server ServletPathSpec and RegexPathSpec
+ Moved all other code to using new jetty-http versions
Diffstat (limited to 'jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty')
5 files changed, 9 insertions, 356 deletions
diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java index 60016f4d1d..6954cb01d2 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrCreator.java @@ -29,6 +29,8 @@ import javax.websocket.Extension.Parameter; import javax.websocket.server.ServerEndpointConfig; import javax.websocket.server.ServerEndpointConfig.Configurator; +import org.eclipse.jetty.http.pathmap.PathSpec; +import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -37,8 +39,6 @@ import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; import org.eclipse.jetty.websocket.jsr356.JsrExtension; import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance; -import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; -import org.eclipse.jetty.websocket.server.pathmap.PathSpec; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -148,10 +148,10 @@ public class JsrCreator implements WebSocketCreator // Do not decorate here (let the Connection and Session start first) // This will allow CDI to see Session for injection into Endpoint classes. PathSpec pathSpec = hsreq.getRequestPathSpec(); - if (pathSpec instanceof WebSocketPathSpec) + if (pathSpec instanceof UriTemplatePathSpec) { // We have a PathParam path spec - WebSocketPathSpec wspathSpec = (WebSocketPathSpec)pathSpec; + UriTemplatePathSpec wspathSpec = (UriTemplatePathSpec)pathSpec; String requestPath = req.getRequestPath(); // Wrap the config with the path spec information config = new PathParamServerEndpointConfig(containerScope,config,wspathSpec,requestPath); diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrHandshakeRequest.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrHandshakeRequest.java index 6db246d801..023b676531 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrHandshakeRequest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/JsrHandshakeRequest.java @@ -25,7 +25,7 @@ import java.util.Map; import javax.websocket.server.HandshakeRequest; -import org.eclipse.jetty.websocket.server.pathmap.PathSpec; +import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; public class JsrHandshakeRequest implements HandshakeRequest diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java index d709a0039a..a4bcb3b8e1 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/PathParamServerEndpointConfig.java @@ -23,8 +23,8 @@ import java.util.Map; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; -import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; /** * Wrapper for a {@link ServerEndpointConfig} where there PathParm information from the incoming request. @@ -33,7 +33,7 @@ public class PathParamServerEndpointConfig extends BasicServerEndpointConfig imp { private final Map<String, String> pathParamMap; - public PathParamServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig config, WebSocketPathSpec pathSpec, String requestPath) + public PathParamServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig config, UriTemplatePathSpec pathSpec, String requestPath) { super(containerScope, config); diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index 7fdba0426d..dba7a88567 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -27,6 +27,7 @@ import javax.websocket.Endpoint; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.events.EventDriverFactory; @@ -35,7 +36,6 @@ import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance; import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata; -import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec; import org.eclipse.jetty.websocket.server.MappedWebSocketCreator; import org.eclipse.jetty.websocket.server.WebSocketServerFactory; @@ -99,7 +99,7 @@ public class ServerContainer extends ClientContainer implements javax.websocket. private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException { JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory()); - mappedCreator.addMapping(new WebSocketPathSpec(metadata.getPath()),creator); + mappedCreator.addMapping(new UriTemplatePathSpec(metadata.getPath()),creator); } @Override diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/pathmap/WebSocketPathSpec.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/pathmap/WebSocketPathSpec.java deleted file mode 100644 index 014466a60e..0000000000 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/pathmap/WebSocketPathSpec.java +++ /dev/null @@ -1,347 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.jsr356.server.pathmap; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; - -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.server.pathmap.PathSpecGroup; -import org.eclipse.jetty.websocket.server.pathmap.RegexPathSpec; - -/** - * PathSpec for WebSocket @{@link ServerEndpoint} declarations with support for URI templates and @{@link PathParam} annotations - * - * @see javax.websocket spec (JSR-356) Section 3.1.1 URI Mapping - * @see <a href="https://tools.ietf.org/html/rfc6570">URI Templates (Level 1)</a> - */ -public class WebSocketPathSpec extends RegexPathSpec -{ - private static final Logger LOG = Log.getLogger(WebSocketPathSpec.class); - - private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{(.*)\\}"); - /** Reserved Symbols in URI Template variable */ - private static final String VARIABLE_RESERVED = ":/?#[]@" + // gen-delims - "!$&'()*+,;="; // sub-delims - /** Allowed Symboles in a URI Template variable */ - private static final String VARIABLE_SYMBOLS="-._"; - private static final Set<String> FORBIDDEN_SEGMENTS; - - static - { - FORBIDDEN_SEGMENTS = new HashSet<>(); - FORBIDDEN_SEGMENTS.add("/./"); - FORBIDDEN_SEGMENTS.add("/../"); - FORBIDDEN_SEGMENTS.add("//"); - } - - private String variables[]; - - public WebSocketPathSpec(String pathParamSpec) - { - super(); - Objects.requireNonNull(pathParamSpec,"Path Param Spec cannot be null"); - - if ("".equals(pathParamSpec) || "/".equals(pathParamSpec)) - { - super.pathSpec = "/"; - super.pattern = Pattern.compile("^/$"); - super.pathDepth = 1; - this.specLength = 1; - this.variables = new String[0]; - this.group = PathSpecGroup.EXACT; - return; - } - - if (pathParamSpec.charAt(0) != '/') - { - // path specs must start with '/' - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: path spec \""); - err.append(pathParamSpec); - err.append("\" must start with '/'"); - throw new IllegalArgumentException(err.toString()); - } - - for (String forbidden : FORBIDDEN_SEGMENTS) - { - if (pathParamSpec.contains(forbidden)) - { - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: segment "); - err.append(forbidden); - err.append(" is forbidden in path spec: "); - err.append(pathParamSpec); - throw new IllegalArgumentException(err.toString()); - } - } - - this.pathSpec = pathParamSpec; - - StringBuilder regex = new StringBuilder(); - regex.append('^'); - - List<String> varNames = new ArrayList<>(); - // split up into path segments (ignoring the first slash that will always be empty) - String segments[] = pathParamSpec.substring(1).split("/"); - char segmentSignature[] = new char[segments.length]; - this.pathDepth = segments.length; - for (int i = 0; i < segments.length; i++) - { - String segment = segments[i]; - Matcher mat = VARIABLE_PATTERN.matcher(segment); - - if (mat.matches()) - { - // entire path segment is a variable. - String variable = mat.group(1); - if (varNames.contains(variable)) - { - // duplicate variable names - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: variable "); - err.append(variable); - err.append(" is duplicated in path spec: "); - err.append(pathParamSpec); - throw new IllegalArgumentException(err.toString()); - } - - assertIsValidVariableLiteral(variable); - - segmentSignature[i] = 'v'; // variable - // valid variable name - varNames.add(variable); - // build regex - regex.append("/([^/]+)"); - } - else if (mat.find(0)) - { - // variable exists as partial segment - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: variable "); - err.append(mat.group()); - err.append(" must exist as entire path segment: "); - err.append(pathParamSpec); - throw new IllegalArgumentException(err.toString()); - } - else if ((segment.indexOf('{') >= 0) || (segment.indexOf('}') >= 0)) - { - // variable is split with a path separator - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: invalid path segment /"); - err.append(segment); - err.append("/ variable declaration incomplete: "); - err.append(pathParamSpec); - throw new IllegalArgumentException(err.toString()); - } - else if (segment.indexOf('*') >= 0) - { - // glob segment - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: path segment /"); - err.append(segment); - err.append("/ contains a wildcard symbol (not supported by javax.websocket): "); - err.append(pathParamSpec); - throw new IllegalArgumentException(err.toString()); - } - else - { - // valid path segment - segmentSignature[i] = 'e'; // exact - // build regex - regex.append('/'); - // escape regex special characters - for (char c : segment.toCharArray()) - { - if ((c == '.') || (c == '[') || (c == ']') || (c == '\\')) - { - regex.append('\\'); - } - regex.append(c); - } - } - } - - // Handle trailing slash (which is not picked up during split) - if(pathParamSpec.charAt(pathParamSpec.length()-1) == '/') - { - regex.append('/'); - } - - regex.append('$'); - - this.pattern = Pattern.compile(regex.toString()); - - int varcount = varNames.size(); - this.variables = varNames.toArray(new String[varcount]); - - // Convert signature to group - String sig = String.valueOf(segmentSignature); - - if (Pattern.matches("^e*$",sig)) - { - this.group = PathSpecGroup.EXACT; - } - else if (Pattern.matches("^e*v+",sig)) - { - this.group = PathSpecGroup.PREFIX_GLOB; - } - else if (Pattern.matches("^v+e+",sig)) - { - this.group = PathSpecGroup.SUFFIX_GLOB; - } - else - { - this.group = PathSpecGroup.MIDDLE_GLOB; - } - } - - /** - * Validate variable literal name, per RFC6570, Section 2.1 Literals - * @param variable - * @param pathParamSpec - */ - private void assertIsValidVariableLiteral(String variable) - { - int len = variable.length(); - - int i = 0; - int codepoint; - boolean valid = (len > 0); // must not be zero length - - while (valid && i < len) - { - codepoint = variable.codePointAt(i); - i += Character.charCount(codepoint); - - // basic letters, digits, or symbols - if (isValidBasicLiteralCodepoint(codepoint)) - { - continue; - } - - // The ucschar and iprivate pieces - if (Character.isSupplementaryCodePoint(codepoint)) - { - continue; - } - - // pct-encoded - if (codepoint == '%') - { - if (i + 2 > len) - { - // invalid percent encoding, missing extra 2 chars - valid = false; - continue; - } - codepoint = TypeUtil.convertHexDigit(variable.codePointAt(i++)) << 4; - codepoint |= TypeUtil.convertHexDigit(variable.codePointAt(i++)); - - // validate basic literal - if (isValidBasicLiteralCodepoint(codepoint)) - { - continue; - } - } - - valid = false; - } - - if (!valid) - { - // invalid variable name - StringBuilder err = new StringBuilder(); - err.append("Syntax Error: variable {"); - err.append(variable); - err.append("} an invalid variable name: "); - err.append(pathSpec); - throw new IllegalArgumentException(err.toString()); - } - } - - private boolean isValidBasicLiteralCodepoint(int codepoint) - { - // basic letters or digits - if((codepoint >= 'a' && codepoint <= 'z') || - (codepoint >= 'A' && codepoint <= 'Z') || - (codepoint >= '0' && codepoint <= '9')) - { - return true; - } - - // basic allowed symbols - if(VARIABLE_SYMBOLS.indexOf(codepoint) >= 0) - { - return true; // valid simple value - } - - // basic reserved symbols - if(VARIABLE_RESERVED.indexOf(codepoint) >= 0) - { - LOG.warn("Detected URI Template reserved symbol [{}] in path spec \"{}\"",(char)codepoint,pathSpec); - return false; // valid simple value - } - - return false; - } - - public Map<String, String> getPathParams(String path) - { - Matcher matcher = getMatcher(path); - if (matcher.matches()) - { - if (group == PathSpecGroup.EXACT) - { - return Collections.emptyMap(); - } - Map<String, String> ret = new HashMap<>(); - int groupCount = matcher.groupCount(); - for (int i = 1; i <= groupCount; i++) - { - ret.put(this.variables[i - 1],matcher.group(i)); - } - return ret; - } - return null; - } - - public int getVariableCount() - { - return variables.length; - } - - public String[] getVariables() - { - return this.variables; - } -} |