Skip to content

Commit

Permalink
#1183 apiproxy subpaths matching fix (#1185)
Browse files Browse the repository at this point in the history
* Expanded APIProxyKeyTest to check for subpaths in response to issue #1183

* Refactor APIProxyKeyTest

* temp state

* Fixed copy of useRegExp

* resolved conflicts

---------

Co-authored-by: Torben Burchgart <[email protected]>
Co-authored-by: Christian Gördes <[email protected]>
  • Loading branch information
3 people authored Jul 17, 2024
1 parent c0cf3d4 commit 2ca6a57
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private Map<String, OpenAPIRecord> getOpenAPIMap() {
paths.put(UriUtil.getPathFromURL(router.getUriFactory(), url), rec);
} catch (URISyntaxException e) {
log.error("Cannot parse URL {}", url);
throw new RuntimeException();
throw new RuntimeException("Cannot parse URL %s".formatted(url));
}
}));
return paths;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public class APIProxyKey extends ServiceProxyKey {
private Expression testExpr;

public APIProxyKey(RuleKey key, String test, boolean openAPI) {
this(key.getIp(), key.getHost(), key.getPort(), key.getPath(), key.getMethod(), test, openAPI);
super(key);
init(test, openAPI);
setUsePathPattern(true);
}

public APIProxyKey(String ip, String host, int port, String path, String method, String test, boolean openAPI) {
Expand Down Expand Up @@ -71,7 +73,7 @@ public boolean complexMatch(Exchange exc) {
if (!uri.startsWith(basePath))
continue;

log.debug("Rule matches " + uri);
log.debug("Rule matches {}", uri);
return true;

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ public AbstractRuleKey(int port, String ip) {
this.ip = ip;
}

public AbstractRuleKey(RuleKey key) {
port = key.getPort();
path = key.getPath();
usePathPattern = key.isUsePathPattern();
ip = key.getIp();

if (key instanceof AbstractRuleKey arKey) {
pathPattern = arKey.getPathPattern();
pathRegExp = arKey.getPathRegExp();
}
}

public String getHost() {
return "";
}
Expand Down Expand Up @@ -73,6 +85,10 @@ public boolean isPathRegExp() {
return pathRegExp;
}

public boolean getPathRegExp() {
return pathRegExp;
}

public void setPathRegExp(boolean pathRegExp) {
this.pathRegExp = pathRegExp;
}
Expand Down Expand Up @@ -102,8 +118,7 @@ public boolean matchesPath(String path) {
}

private boolean matchesPathPattern(String path) {
log.debug("matches path: " + path + " with path pattern: "
+ getPathPattern());
log.debug("matches path: {} with path pattern: {}", path, getPathPattern());
return getPathPattern().matcher(path).matches();
}

Expand Down
261 changes: 136 additions & 125 deletions core/src/main/java/com/predic8/membrane/core/rules/ServiceProxyKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,114 +21,125 @@
import org.slf4j.LoggerFactory;

public class ServiceProxyKey extends AbstractRuleKey {
private static Logger log = LoggerFactory.getLogger(ServiceProxyKey.class.getName());

private String method = "*";
private String host = "*";
private boolean isHostWildCard = true;
private Pattern hostPattern;

public ServiceProxyKey(int port) {
this(port, null);
}

public ServiceProxyKey(int port, String ip) {
super(port, ip);
}

public ServiceProxyKey(String host, String method, String path, int port) {
this(host, method, path, port, null);
}

public ServiceProxyKey(String host, String method, String path, int port, String ip) {
super(port, ip);
setHost(host);
setPath(path);
this.method = method;
}

@Override
public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

@Override
public boolean isMethodWildcard() {
return "*".equals(method.trim());
}

@Override
public boolean isHostWildcard() {
return isHostWildCard;
}

@Override
public String toString() {
return ( host.equals("*") ? "" : host+" " )
+ ( method.equals("*") ? "" : method+" " )
+ StringUtils.defaultIfEmpty(getPath(), "")
+ ":" + port;
}



@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((host == null) ? 0 : host.hashCode());
result = prime * result + ((method == null) ? 0 : method.hashCode());
result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
ServiceProxyKey other = (ServiceProxyKey) obj;
if (host == null) {
if (other.host != null)
return false;
} else if (!host.equals(other.host))
return false;
if (method == null) {
if (other.method != null)
return false;
} else if (!method.equals(other.method))
return false;
if (getPath() == null) {
if (other.getPath() != null)
return false;
} else if (!getPath().equals(other.getPath()))
return false;
return true;
}

@Override
public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host.trim();
this.isHostWildCard = "*".equals(this.host);
if (!isHostWildCard) {
String pattern = createHostPattern(this.host);
log.debug("Created host pattern match: " + pattern);
this.hostPattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
} else {
this.hostPattern = null;
}
}
private static final Logger log = LoggerFactory.getLogger(ServiceProxyKey.class.getName());

private String method = "*";
private String host = "*";
private boolean isHostWildCard = true;
private Pattern hostPattern;

public ServiceProxyKey(RuleKey key) {
super(key);
method = key.getMethod();
host = key.getHost();

if (key instanceof AbstractRuleKey arKey) {
isHostWildCard = arKey.isHostWildcard();
}

if (key instanceof ServiceProxyKey spKey) {
hostPattern = spKey.getHostPattern();
}
}


public ServiceProxyKey(int port) {
this(port, null);
}

public ServiceProxyKey(int port, String ip) {
super(port, ip);
}

public ServiceProxyKey(String host, String method, String path, int port) {
this(host, method, path, port, null);
}

public ServiceProxyKey(String host, String method, String path, int port, String ip) {
super(port, ip);
setHost(host);
setPath(path);
this.method = method;
}

@Override
public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

@Override
public boolean isMethodWildcard() {
return "*".equals(method.trim());
}

@Override
public boolean isHostWildcard() {
return isHostWildCard;
}

@Override
public String toString() {
return (host.equals("*") ? "" : host + " ")
+ (method.equals("*") ? "" : method + " ")
+ StringUtils.defaultIfEmpty(getPath(), "")
+ ":" + port;
}


@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((host == null) ? 0 : host.hashCode());
result = prime * result + ((method == null) ? 0 : method.hashCode());
result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
ServiceProxyKey other = (ServiceProxyKey) obj;
if (host == null) {
if (other.host != null)
return false;
} else if (!host.equals(other.host))
return false;
if (method == null) {
if (other.method != null)
return false;
} else if (!method.equals(other.method))
return false;
if (getPath() == null) {
return other.getPath() == null;
} else return getPath().equals(other.getPath());
}

@Override
public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host.trim();
this.isHostWildCard = "*".equals(this.host);
if (!isHostWildCard) {
String pattern = createHostPattern(this.host);
log.debug("Created host pattern match: {}", pattern);
this.hostPattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
} else {
this.hostPattern = null;
}
}

public static String createHostPattern(String host) {
StringBuilder regex = new StringBuilder();
Expand All @@ -153,7 +164,7 @@ public static String createHostPattern(String host) {
regex.append("\\E");
quoted = false;
}
regex.append(".*");
regex.append(".+");
notWhitespace = true;
break;
default:
Expand All @@ -179,25 +190,25 @@ public static String createHostPattern(String host) {
}


@Override
public boolean matchesHostHeader(String hostHeader) {
if (isHostWildCard)
return true;
@Override
public boolean matchesHostHeader(String hostHeader) {
if (isHostWildCard)
return true;

if (hostHeader == null)
return false;
if (hostHeader == null)
return false;

String requestHost = hostHeader.split(":")[0];
String requestHost = hostHeader.split(":")[0];

log.debug("Rule host: " + host + "; Request host: " + requestHost);
log.debug("Rule host: {} Request host: {}", host, requestHost);

return hostPattern.matcher(requestHost).matches();
}
return hostPattern.matcher(requestHost).matches();
}

/**
* The pattern used to match the host name, or null if any host name matches.
*/
public Pattern getHostPattern() {
return hostPattern;
}
/**
* The pattern used to match the host name, or null if any host name matches.
*/
public Pattern getHostPattern() {
return hostPattern;
}
}
Loading

0 comments on commit 2ca6a57

Please sign in to comment.