Make WebMvgTags use matched patterns for HTTP 404
Prior to this commit, `WebMvcTags' would always mark as "NOT_FOUND" or "REDIRECTION" *any* exchange with responses of 404 and 3xx status, even if those responses are actually returned by Controller handlers. This commit checks inverts those checks and first considers if the "BEST_MATCHING_PATTERN_ATTRIBUTE" request attribute is present and uses it - then falls back to "NOT_FOUND" and "REDIRECTION" to avoid cardinality explosion. Fixes gh-12577
This commit is contained in:
		
							parent
							
								
									cca5c0d2ee
								
							
						
					
					
						commit
						ebb2f70e0b
					
				|  | @ -31,10 +31,16 @@ import org.springframework.web.servlet.HandlerMapping; | |||
|  * | ||||
|  * @author Jon Schneider | ||||
|  * @author Andy Wilkinson | ||||
|  * @author Brian Clozel | ||||
|  * @since 2.0.0 | ||||
|  */ | ||||
| public final class WebMvcTags { | ||||
| 
 | ||||
| 	private static final Tag URI_NOT_FOUND = Tag.of("uri", "NOT_FOUND"); | ||||
| 
 | ||||
| 	private static final Tag URI_REDIRECTION = Tag.of("uri", "REDIRECTION"); | ||||
| 
 | ||||
| 
 | ||||
| 	private WebMvcTags() { | ||||
| 	} | ||||
| 
 | ||||
|  | @ -69,21 +75,24 @@ public final class WebMvcTags { | |||
| 	 * @return the uri tag derived from the request | ||||
| 	 */ | ||||
| 	public static Tag uri(HttpServletRequest request, HttpServletResponse response) { | ||||
| 		if (response != null) { | ||||
| 			HttpStatus status = extractStatus(response); | ||||
| 			if (status != null && status.is3xxRedirection()) { | ||||
| 				return Tag.of("uri", "REDIRECTION"); | ||||
| 		if (request != null) { | ||||
| 			String pattern = getMatchingPattern(request); | ||||
| 			if (pattern != null) { | ||||
| 				return Tag.of("uri", pattern); | ||||
| 			} | ||||
| 			if (status != null && status.equals(HttpStatus.NOT_FOUND)) { | ||||
| 				return Tag.of("uri", "NOT_FOUND"); | ||||
| 			else if (response != null) { | ||||
| 				HttpStatus status = extractStatus(response); | ||||
| 				if (status != null && status.is3xxRedirection()) { | ||||
| 					return URI_REDIRECTION; | ||||
| 				} | ||||
| 				if (status != null && status.equals(HttpStatus.NOT_FOUND)) { | ||||
| 					return URI_NOT_FOUND; | ||||
| 				} | ||||
| 			} | ||||
| 			String pathInfo = getPathInfo(request); | ||||
| 			return Tag.of("uri", pathInfo.isEmpty() ? "root" : pathInfo); | ||||
| 		} | ||||
| 		if (request == null) { | ||||
| 			return Tag.of("uri", "UNKNOWN"); | ||||
| 		} | ||||
| 		String uri = getUri(request); | ||||
| 		uri = uri.replaceAll("//+", "/").replaceAll("/$", ""); | ||||
| 		return Tag.of("uri", uri.isEmpty() ? "root" : uri); | ||||
| 		return Tag.of("uri", "UNKNOWN"); | ||||
| 	} | ||||
| 
 | ||||
| 	private static HttpStatus extractStatus(HttpServletResponse response) { | ||||
|  | @ -95,11 +104,16 @@ public final class WebMvcTags { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static String getUri(HttpServletRequest request) { | ||||
| 		String uri = (String) request | ||||
| 	private static String getMatchingPattern(HttpServletRequest request) { | ||||
| 		return (String) request | ||||
| 				.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); | ||||
| 		uri = (uri != null ? uri : request.getPathInfo()); | ||||
| 		return (StringUtils.hasText(uri) ? uri : "/"); | ||||
| 	} | ||||
| 
 | ||||
| 	private static String getPathInfo(HttpServletRequest request) { | ||||
| 		String uri = StringUtils.hasText(request.getPathInfo()) ? | ||||
| 				request.getPathInfo() : "/"; | ||||
| 		return uri.replaceAll("//+", "/") | ||||
| 				.replaceAll("/$", ""); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
|  * Tests for {@link WebMvcTags}. | ||||
|  * | ||||
|  * @author Andy Wilkinson | ||||
|  * @author Brian Clozel | ||||
|  */ | ||||
| public class WebMvcTagsTests { | ||||
| 
 | ||||
|  | @ -39,9 +40,17 @@ public class WebMvcTagsTests { | |||
| 
 | ||||
| 	@Test | ||||
| 	public void uriTrailingSlashesAreSuppressed() { | ||||
| 		this.request.setPathInfo("//spring/"); | ||||
| 		assertThat(WebMvcTags.uri(this.request, null).getValue()).isEqualTo("/spring"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void uriTagValueIsBestMatchingPatternWhenAvailable() { | ||||
| 		this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, | ||||
| 				"//foo/"); | ||||
| 		assertThat(WebMvcTags.uri(this.request, null).getValue()).isEqualTo("/foo"); | ||||
| 				"/spring"); | ||||
| 		this.response.setStatus(301); | ||||
| 		Tag tag = WebMvcTags.uri(this.request, this.response); | ||||
| 		assertThat(tag.getValue()).isEqualTo("/spring"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
|  | @ -65,4 +74,9 @@ public class WebMvcTagsTests { | |||
| 		assertThat(tag.getValue()).isEqualTo("root"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void uriTagIsUnknownWhenRequestIsNull() { | ||||
| 		Tag tag = WebMvcTags.uri(null, null); | ||||
| 		assertThat(tag.getValue()).isEqualTo("UNKNOWN"); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue