Skip to content

Assign lowest priority to "/**" in AntPathMatcher [SPR-10550] #15181

@spring-projects-issues

Description

@spring-projects-issues

Antonio Marrero opened SPR-10550 and commented

Problem:
Normally the pattern "/" is used to handle the requests that don't match any of the other Servlet requests, therefore its priority should be the lowest.
When there is a URI pattern with 3 or more PathVariable (i.e "/matches/{matchId}/periods/{periodId}/teams/{teamId}/results") the default URI ("/
") takes precedence.

Cause:
The problem is that the method AntPathMatcher.compare is giving higher priority to the patterns with less brackets "{}" and wildcards "*". See below an extract of code from the compare method:

        int wildCardCount1 = getWildCardCount(pattern1);
	int wildCardCount2 = getWildCardCount(pattern2);
			
	int bracketCount1 = StringUtils.countOccurrencesOf(pattern1, "{");
	int bracketCount2 = StringUtils.countOccurrencesOf(pattern2, "{");
			
	int totalCount1 = wildCardCount1 + bracketCount1;
	int totalCount2 = wildCardCount2 + bracketCount2;

	if (totalCount1 != totalCount2) {
		return totalCount1 - totalCount2;
	}

Solution:
The pattern "/**" should have a special treatment like null has. See below a proposed solution:

public int compare(String pattern1, String pattern2) {
			
	if (pattern1 == null && pattern2 == null) {
		return 0;
	}
	else if (pattern1 == null) {
		return 1;
	}
	else if (pattern2 == null) {
		return -1;
	}		
			
	boolean pattern1EqualsPath = pattern1.equals(path);
	boolean pattern2EqualsPath = pattern2.equals(path);
	if (pattern1EqualsPath && pattern2EqualsPath) {
		return 0;
	}
	else if (pattern1EqualsPath) {
		return -1;
	}
	else if (pattern2EqualsPath) {
		return 1;
	}
	
	// Setting lower priority to "/**"
	if(pattern1.equals("/**")){
		return 1;
	}else if (pattern2.equals("/**")){
		return -1;
	}
	
	int wildCardCount1 = getWildCardCount(pattern1);
	int wildCardCount2 = getWildCardCount(pattern2);
			
	int bracketCount1 = StringUtils.countOccurrencesOf(pattern1, "{");
	int bracketCount2 = StringUtils.countOccurrencesOf(pattern2, "{");
		
	int totalCount1 = wildCardCount1 + bracketCount1;
	int totalCount2 = wildCardCount2 + bracketCount2;
	if (totalCount1 != totalCount2) {
		return totalCount1 - totalCount2;
	}
	int pattern1Length = getPatternLength(pattern1);
	int pattern2Length = getPatternLength(pattern2);
		
	if (pattern1Length != pattern2Length) {
		return pattern2Length - pattern1Length;
	}

	if (wildCardCount1 < wildCardCount2) {
		return -1;
	}
	else if (wildCardCount2 < wildCardCount1) {
		return 1;
	}

	if (bracketCount1 < bracketCount2) {
		return -1;
	}
	else if (bracketCount2 < bracketCount1) {
		return 1;
	}

	return 0;
}

Affects: 3.2.2

Issue Links:

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions