org.picketlink.http.internal.PathMatcher Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.picketlink.http.internal;
import org.picketlink.config.http.InboundHeaderConfiguration;
import org.picketlink.config.http.PathConfiguration;
import org.picketlink.http.HttpMethod;
import org.picketlink.internal.el.ELProcessor;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Pedro Igor
*/
public class PathMatcher {
private static final String ANY_RESOURCE_PATTERN = "/*";
private final Map> uriConfiguration;
private final ELProcessor elProcessor;
public PathMatcher(Map> uriConfiguration, ELProcessor elProcessor) {
this.uriConfiguration = uriConfiguration;
this.elProcessor = elProcessor;
}
public PathConfiguration matches(HttpServletRequest request) {
String requestedUri = request.getRequestURI();
int contextPathIndex = requestedUri.indexOf(request.getContextPath());
if (contextPathIndex != -1) {
requestedUri = requestedUri.substring(contextPathIndex + request.getContextPath().length());
}
List configurations = null;
String actualConfig = null;
for (Map.Entry> entry : this.uriConfiguration.entrySet()) {
String protectedUri = entry.getKey();
String selectedUri = null;
if (protectedUri.equals(ANY_RESOURCE_PATTERN) && actualConfig == null) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
int suffixIndex = protectedUri.indexOf(ANY_RESOURCE_PATTERN + ".");
if (suffixIndex != -1) {
String protectedSuffix = protectedUri.substring(suffixIndex + ANY_RESOURCE_PATTERN.length());
if (requestedUri.endsWith(protectedSuffix)) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
}
if (protectedUri.equals(requestedUri)) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
if (protectedUri.endsWith(ANY_RESOURCE_PATTERN)) {
String formattedPattern = removeWildCardsFromUri(protectedUri);
if (!formattedPattern.equals("/") && requestedUri.startsWith(formattedPattern)) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
if (!formattedPattern.equals("/") && formattedPattern.endsWith("/") && formattedPattern.substring(0, formattedPattern.length() - 1).equals(requestedUri)) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
}
int startRegex = protectedUri.indexOf('{');
if (startRegex != -1) {
String prefix = protectedUri.substring(0, startRegex);
if (requestedUri.startsWith(prefix)) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
}
if (selectedUri != null) {
configurations = this.uriConfiguration.get(entry.getKey());
selectedUri = protectedUri;
}
if (selectedUri != null) {
if (actualConfig == null) {
actualConfig = entry.getKey();
} else {
if (actualConfig.equals(ANY_RESOURCE_PATTERN)) {
actualConfig = entry.getKey();
}
if (protectedUri.startsWith(removeWildCardsFromUri(actualConfig))) {
actualConfig = entry.getKey();
}
}
}
}
if (configurations != null) {
if (configurations.size() == 1) {
return configurations.get(0);
}
int configIndex = -1;
int lastMatchCount = 0;
for (int i = 0; i < configurations.size(); i++) {
PathConfiguration pathConfiguration = configurations.get(i);
InboundHeaderConfiguration headerConfiguration = pathConfiguration.getInboundHeaderConfiguration();
Set methods = pathConfiguration.getMethods();
if (!methods.contains(HttpMethod.valueOf(request.getMethod().toUpperCase()))) {
continue;
}
if (headerConfiguration == null) {
if (configIndex == -1) {
configIndex = i;
}
} else {
Map inboundHeaders = headerConfiguration.getHeaders();
if (inboundHeaders.isEmpty()) {
configIndex = i;
} else {
for (String inboundHeaderName : inboundHeaders.keySet()) {
Enumeration requestHeaderValues = request.getHeaders(inboundHeaderName);
if (requestHeaderValues == null) {
break;
}
List inboundHeaderValues = Arrays.asList(inboundHeaders.get(inboundHeaderName));
int matchCount = 0;
while (requestHeaderValues.hasMoreElements()) {
String requestHeaderValue = requestHeaderValues.nextElement();
if (inboundHeaderValues.contains(requestHeaderValue)) {
matchCount++;
}
}
if (matchCount > lastMatchCount) {
lastMatchCount = matchCount;
configIndex = i;
}
}
}
}
}
if (configIndex >= 0) {
return configurations.get(configIndex);
}
}
return null;
}
private String removeWildCardsFromUri(String protectedUri) {
return protectedUri.replaceAll("/[*]", "/");
}
}