Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
07e915e
commit 04385f2
Showing
8 changed files
with
331 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
core/src/main/java/io/undertow/server/RoutingHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package io.undertow.server; | ||
|
||
import io.undertow.predicate.Predicate; | ||
import io.undertow.server.handlers.ResponseCodeHandler; | ||
import io.undertow.util.CopyOnWriteMap; | ||
import io.undertow.util.HttpString; | ||
import io.undertow.util.PathTemplateMatch; | ||
import io.undertow.util.PathTemplateMatcher; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
/** | ||
* A Handler that handles the common case of routing via path template and method name. | ||
* | ||
* @author Stuart Douglas | ||
*/ | ||
public class RoutingHandler implements HttpHandler { | ||
|
||
private final Map<HttpString, PathTemplateMatcher<RoutingMatch>> matches = new CopyOnWriteMap<HttpString, PathTemplateMatcher<RoutingMatch>>(); | ||
|
||
private volatile HttpHandler fallbackHandler = ResponseCodeHandler.HANDLE_404; | ||
|
||
/** | ||
* If this is true then path matches will be added to the query parameters for easy access by | ||
* later handlers. | ||
*/ | ||
private final boolean rewriteQueryParameters; | ||
|
||
public RoutingHandler(boolean rewriteQueryParameters) { | ||
this.rewriteQueryParameters = rewriteQueryParameters; | ||
} | ||
|
||
public RoutingHandler() { | ||
this.rewriteQueryParameters = true; | ||
} | ||
|
||
@Override | ||
public void handleRequest(HttpServerExchange exchange) throws Exception { | ||
|
||
PathTemplateMatcher<RoutingMatch> matcher = matches.get(exchange.getRequestMethod()); | ||
if (matcher == null) { | ||
fallbackHandler.handleRequest(exchange); | ||
return; | ||
} | ||
PathTemplateMatcher.PathMatchResult<RoutingMatch> match = matcher.match(exchange.getRelativePath()); | ||
if (match == null) { | ||
fallbackHandler.handleRequest(exchange); | ||
return; | ||
} | ||
exchange.putAttachment(PathTemplateMatch.ATTACHMENT_KEY, match); | ||
if (rewriteQueryParameters) { | ||
for (Map.Entry<String, String> entry : match.getParameters().entrySet()) { | ||
exchange.addQueryParam(entry.getKey(), entry.getValue()); | ||
} | ||
} | ||
for (HandlerHolder handler : match.getValue().predicatedHandlers) { | ||
if (handler.predicate.resolve(exchange)) { | ||
handler.handler.handleRequest(exchange); | ||
return; | ||
} | ||
} | ||
if (match.getValue().defaultHandler != null) { | ||
match.getValue().defaultHandler.handleRequest(exchange); | ||
} else { | ||
fallbackHandler.handleRequest(exchange); | ||
} | ||
} | ||
|
||
public synchronized RoutingHandler add(final String method, final String template, HttpHandler handler) { | ||
return add(new HttpString(method), template, handler); | ||
} | ||
|
||
public synchronized RoutingHandler add(HttpString method, String template, HttpHandler handler) { | ||
PathTemplateMatcher<RoutingMatch> matcher = matches.get(method); | ||
if (matcher == null) { | ||
matches.put(method, matcher = new PathTemplateMatcher<RoutingMatch>()); | ||
} | ||
RoutingMatch res = matcher.get(template); | ||
if (res == null) { | ||
matcher.add(template, res = new RoutingMatch()); | ||
} | ||
res.defaultHandler = handler; | ||
return this; | ||
} | ||
|
||
public synchronized RoutingHandler add(final String method, final String template, Predicate predicate, HttpHandler handler) { | ||
return add(new HttpString(method), template, predicate, handler); | ||
} | ||
|
||
public synchronized RoutingHandler add(HttpString method, String template, Predicate predicate, HttpHandler handler) { | ||
PathTemplateMatcher<RoutingMatch> matcher = matches.get(method); | ||
if (matcher == null) { | ||
matches.put(method, matcher = new PathTemplateMatcher<RoutingMatch>()); | ||
} | ||
RoutingMatch res = matcher.get(template); | ||
if (res == null) { | ||
matcher.add(template, res = new RoutingMatch()); | ||
} | ||
res.predicatedHandlers.add(new HandlerHolder(predicate, handler)); | ||
return this; | ||
} | ||
|
||
public HttpHandler getFallbackHandler() { | ||
return fallbackHandler; | ||
} | ||
|
||
public void setFallbackHandler(HttpHandler fallbackHandler) { | ||
this.fallbackHandler = fallbackHandler; | ||
} | ||
|
||
private static class RoutingMatch { | ||
|
||
final List<HandlerHolder> predicatedHandlers = new CopyOnWriteArrayList<HandlerHolder>(); | ||
volatile HttpHandler defaultHandler; | ||
|
||
} | ||
|
||
private static class HandlerHolder { | ||
final Predicate predicate; | ||
final HttpHandler handler; | ||
|
||
private HandlerHolder(Predicate predicate, HttpHandler handler) { | ||
this.predicate = predicate; | ||
this.handler = handler; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
core/src/main/java/io/undertow/util/PathTemplateMatch.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.undertow.util; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* The result of a path template match. | ||
* | ||
* @author Stuart Douglas | ||
*/ | ||
public class PathTemplateMatch { | ||
|
||
public static final AttachmentKey<PathTemplateMatch> ATTACHMENT_KEY = AttachmentKey.create(PathTemplateMatch.class); | ||
|
||
private final String matchedTemplate; | ||
private final Map<String, String> parameters; | ||
|
||
public PathTemplateMatch(String matchedTemplate, Map<String, String> parameters) { | ||
this.matchedTemplate = matchedTemplate; | ||
this.parameters = parameters; | ||
} | ||
|
||
public String getMatchedTemplate() { | ||
return matchedTemplate; | ||
} | ||
|
||
public Map<String, String> getParameters() { | ||
return parameters; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.