Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ under the License.
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="AvoidStarImport"/>
<module name="OneTopLevelClass">
<property name="severity" value="warning"/>
</module>
<module name="OneTopLevelClass" />
<module name="NoLineWrap">
<property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
</module>
Expand Down Expand Up @@ -254,7 +252,6 @@ under the License.
<property name="tokens" value="CLASS_DEF"/>
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
<property name="severity" value="warning"/>
</module>
<module name="TypeName">
<property name="tokens" value="INTERFACE_DEF, ENUM_DEF,
Expand All @@ -273,13 +270,11 @@ under the License.
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
<property name="severity" value="warning"/>
</module>
<module name="LambdaParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
<property name="severity" value="warning"/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
Expand Down Expand Up @@ -387,7 +382,6 @@ under the License.
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,
RECORD_DEF, RECORD_PATTERN_DEF"/>
<property name="severity" value="warning"/>
</module>
<module name="OperatorWrap">
<property name="option" value="NL"/>
Expand All @@ -410,9 +404,7 @@ under the License.
<module name="NonEmptyAtclauseDescription">
<property name="severity" value="warning"/>
</module>
<module name="InvalidJavadocPosition">
<property name="severity" value="warning"/>
</module>
<module name="InvalidJavadocPosition" />
<module name="JavadocTagContinuationIndentation">
<property name="severity" value="warning"/>
</module>
Expand Down Expand Up @@ -470,7 +462,6 @@ under the License.
value="^(?![a-z]$)(?![a-z][A-Z])[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*(?:_[0-9]+)*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
<property name="severity" value="warning"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="checks" value="MethodName"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,184 +183,184 @@ public void loadJSONResources(InputStream inputStream)
}
return urlToFilter;
}
}

class Rules {

private Scope globalRules;
private Map<String, Scope> domainRules = new HashMap<>();
private Map<String, Scope> hostNameRules = new HashMap<>();
private List<MDScope> metadataRules = new ArrayList<>();

public void addScope(Scope s, Scope.Type t, String value) {
if (t.equals(Scope.Type.GLOBAL)) {
globalRules = s;
} else if (t.equals(Scope.Type.DOMAIN)) {
domainRules.put(value, s);
} else if (t.equals(Scope.Type.HOSTNAME)) {
hostNameRules.put(value, s);
} else if (t.equals(Scope.Type.METADATA)) {
metadataRules.add(new MDScope(value, s.getRules()));
}
}

/**
* Try the rules from the hostname, domain name, metadata and global scopes in this order.
* Returns true if the URL should be removed, false otherwise. The value returns the value of
* the first matching rule, be it positive or negative.
*
* @throws MalformedURLException
*/
public boolean filter(String url, Metadata metadata) throws MalformedURLException {
URL u = URLUtil.toURL(url);

// first try the full hostname
String hostname = u.getHost();
if (checkScope(hostNameRules.get(hostname), u)) {
return true;
static class Rules {

private Scope globalRules;
private Map<String, Scope> domainRules = new HashMap<>();
private Map<String, Scope> hostNameRules = new HashMap<>();
private List<MDScope> metadataRules = new ArrayList<>();

public void addScope(Scope s, Scope.Type t, String value) {
if (t.equals(Scope.Type.GLOBAL)) {
globalRules = s;
} else if (t.equals(Scope.Type.DOMAIN)) {
domainRules.put(value, s);
} else if (t.equals(Scope.Type.HOSTNAME)) {
hostNameRules.put(value, s);
} else if (t.equals(Scope.Type.METADATA)) {
metadataRules.add(new MDScope(value, s.getRules()));
}
}

// then on the various components of the domain
final String[] domainParts = hostname.split("\\.");
String domain = null;
for (int i = domainParts.length - 1; i >= 0; i--) {
domain = domainParts[i] + (domain == null ? "" : "." + domain);
if (checkScope(domainRules.get(domain), u)) {
/**
* Try the rules from the hostname, domain name, metadata and global scopes in this order.
* Returns true if the URL should be removed, false otherwise. The value returns the value
* of the first matching rule, be it positive or negative.
*
* @throws MalformedURLException
*/
public boolean filter(String url, Metadata metadata) throws MalformedURLException {
URL u = URLUtil.toURL(url);

// first try the full hostname
String hostname = u.getHost();
if (checkScope(hostNameRules.get(hostname), u)) {
return true;
}
}

// check on parent's URL metadata
for (MDScope scope : metadataRules) {
final String[] vals = metadata.getValues(scope.getKey());
if (vals == null) {
continue;
// then on the various components of the domain
final String[] domainParts = hostname.split("\\.");
String domain = null;
for (int i = domainParts.length - 1; i >= 0; i--) {
domain = domainParts[i] + (domain == null ? "" : "." + domain);
if (checkScope(domainRules.get(domain), u)) {
return true;
}
}
for (String v : vals) {
if (v.equalsIgnoreCase(scope.getValue())) {
FastURLFilter.LOG.debug(
"Filtering {} matching metadata {}:{}",
url,
scope.getKey(),
scope.getValue());
if (checkScope(scope, u)) {
return true;

// check on parent's URL metadata
for (MDScope scope : metadataRules) {
final String[] vals = metadata.getValues(scope.getKey());
if (vals == null) {
continue;
}
for (String v : vals) {
if (v.equalsIgnoreCase(scope.getValue())) {
FastURLFilter.LOG.debug(
"Filtering {} matching metadata {}:{}",
url,
scope.getKey(),
scope.getValue());
if (checkScope(scope, u)) {
return true;
}
}
}
}
}

if (checkScope(globalRules, u)) {
return true;
}

return false;
}
if (checkScope(globalRules, u)) {
return true;
}

private boolean checkScope(Scope s, URL u) {
if (s == null) {
return false;
}
for (Rule r : s.getRules()) {
String haystack = u.getPath();
// whether to include the query as well?
if (r.getType().toString().endsWith("QUERY")) {
if (u.getQuery() != null) {
haystack += "?" + u.getQuery();
}

private boolean checkScope(Scope s, URL u) {
if (s == null) {
return false;
}
if (r.getPattern().matcher(haystack).find()) {
// matches! returns true for DENY, false for ALLOW
return r.getType().toString().startsWith("DENY");
for (Rule r : s.getRules()) {
String haystack = u.getPath();
// whether to include the query as well?
if (r.getType().toString().endsWith("QUERY")) {
if (u.getQuery() != null) {
haystack += "?" + u.getQuery();
}
}
if (r.getPattern().matcher(haystack).find()) {
// matches! returns true for DENY, false for ALLOW
return r.getType().toString().startsWith("DENY");
}
}
return false;
}
return false;
}
}

class Scope {
static class Scope {

public enum Type {
DOMAIN,
GLOBAL,
HOSTNAME,
METADATA
}
public enum Type {
DOMAIN,
GLOBAL,
HOSTNAME,
METADATA
}

protected Rule[] rules;
protected Rule[] rules;

public void setRules(List<Rule> rlist) {
this.rules = rlist.toArray(new Rule[0]);
}
public void setRules(List<Rule> rlist) {
this.rules = rlist.toArray(new Rule[0]);
}

public Rule[] getRules() {
return rules;
public Rule[] getRules() {
return rules;
}
}
}

class MDScope extends Scope {
static class MDScope extends Scope {

private String key;
private String value;
private String key;
private String value;

MDScope(String constraint, Rule[] rules) {
this.rules = rules;
int eq = constraint.indexOf("=");
if (eq != -1) {
key = constraint.substring(0, eq);
value = constraint.substring(eq + 1);
} else {
key = constraint;
MDScope(String constraint, Rule[] rules) {
this.rules = rules;
int eq = constraint.indexOf("=");
if (eq != -1) {
key = constraint.substring(0, eq);
value = constraint.substring(eq + 1);
} else {
key = constraint;
}
}
}

public String getKey() {
return key;
}
public String getKey() {
return key;
}

public String getValue() {
return value;
public String getValue() {
return value;
}
}
}

class Rule {
static class Rule {

public enum Type {
DENYPATH,
DENYPATHQUERY,
ALLOWPATH,
ALLOWPATHQUERY
}
public enum Type {
DENYPATH,
DENYPATHQUERY,
ALLOWPATH,
ALLOWPATHQUERY
}

private Type type;
private Pattern pattern;

public Rule(String line) {
int offset = 0;
String lcline = line.toLowerCase(Locale.ROOT);
// separate the type from the pattern
for (Type t : Type.values()) {
String start = t.toString().toLowerCase(Locale.ROOT) + " ";
if (lcline.startsWith(start)) {
type = t;
offset = start.length();
break;
private Type type;
private Pattern pattern;

public Rule(String line) {
int offset = 0;
String lcline = line.toLowerCase(Locale.ROOT);
// separate the type from the pattern
for (Type t : Type.values()) {
String start = t.toString().toLowerCase(Locale.ROOT) + " ";
if (lcline.startsWith(start)) {
type = t;
offset = start.length();
break;
}
}
// no match?
if (type == null) {
return;
}
}
// no match?
if (type == null) {
return;
}

String patternString = line.substring(offset).trim();
pattern = Pattern.compile(patternString);
}
String patternString = line.substring(offset).trim();
pattern = Pattern.compile(patternString);
}

public Type getType() {
return type;
}
public Type getType() {
return type;
}

public Pattern getPattern() {
return pattern;
public Pattern getPattern() {
return pattern;
}
}
}
Loading