Skip to content

Commit

Permalink
Defer initialization of HandlerMethod validation flags
Browse files Browse the repository at this point in the history
Re-create the HandlerMethod only after the original is used as a key
in the CORS lookup map.

Closes gh-34375
  • Loading branch information
rstoyanchev committed Feb 7, 2025
1 parent ff49b0b commit 8499253
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -636,9 +636,6 @@ public void register(T mapping, Object handler, Method method) {
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
validateMethodMapping(handlerMethod, mapping);

// Enable method validation, if applicable
handlerMethod = handlerMethod.createWithValidateFlags();

Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);
for (String path : directPaths) {
this.pathLookup.add(path, mapping);
Expand All @@ -657,6 +654,10 @@ public void register(T mapping, Object handler, Method method) {
this.corsLookup.put(handlerMethod, corsConfig);
}

// Init validation flags
// We do this strictly after using the original instance in the CORS lookups
handlerMethod = handlerMethod.createWithValidateFlags();

this.registry.put(mapping,
new MappingRegistration<>(mapping, handlerMethod, directPaths, name, corsConfig != null));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -292,6 +292,23 @@ void getCorsConfigWithBeanNameHandler() throws Exception {
HandlerMethod handlerMethod = this.mapping.getHandlerInternal(new MockHttpServletRequest("GET", key));
}

@Test
void registerCustomHandlerMethod() throws Exception {
this.mapping.setCustomerHandlerMethod(true);
this.mapping.registerMapping("/foo", this.handler, this.handler.getClass().getMethod("corsHandlerMethod"));

MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/foo");
request.addParameter("abort", "true");
request.addHeader(HttpHeaders.ORIGIN, "https://domain.com");
request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");

MockHttpServletResponse response = new MockHttpServletResponse();

HandlerExecutionChain chain = this.mapping.getHandler(request);

assertThat(chain).isNotNull();
assertThat(response.getStatus()).isEqualTo(200);
}


private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping<String> {
Expand All @@ -302,6 +319,8 @@ private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping

private final List<String> matches = new ArrayList<>();

private boolean customerHandlerMethod;

public MyHandlerMethodMapping() {
setHandlerMethodMappingNamingStrategy(new SimpleMappingNamingStrategy());
}
Expand All @@ -326,6 +345,16 @@ protected String getMappingForMethod(Method method, Class<?> handlerType) {
return methodName.startsWith("handler") ? methodName : null;
}

public void setCustomerHandlerMethod(boolean customerHandlerMethod) {
this.customerHandlerMethod = customerHandlerMethod;
}

@Override
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
return (this.customerHandlerMethod ?
new CustomHandlerMethod(handler, method) : super.createHandlerMethod(handler, method));
}

@Override
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, String mapping) {
CrossOrigin crossOrigin = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class);
Expand Down Expand Up @@ -355,6 +384,7 @@ protected Comparator<String> getMappingComparator(HttpServletRequest request) {

}


private static class SimpleMappingNamingStrategy implements HandlerMethodMappingNamingStrategy<String> {

@Override
Expand All @@ -363,6 +393,16 @@ public String getName(HandlerMethod handlerMethod, String mapping) {
}
}


private static class CustomHandlerMethod extends HandlerMethod {

public CustomHandlerMethod(Object bean, Method method) {
super(bean, method);
}

}


@Controller
static class MyHandler {

Expand Down

0 comments on commit 8499253

Please sign in to comment.