Java Code Examples for org.springframework.web.cors.CorsUtils#isPreFlightRequest()

The following examples show how to use org.springframework.web.cors.CorsUtils#isPreFlightRequest() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RequestMethodsRequestCondition.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Check if any of the HTTP request methods match the given request and
 * return an instance that contains the matching HTTP request method only.
 * @param request the current request
 * @return the same instance if the condition is empty (unless the request
 * method is HTTP OPTIONS), a new condition with the matched request method,
 * or {@code null} if there is no match or the condition is empty and the
 * request method is OPTIONS.
 */
@Override
@Nullable
public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return matchPreFlight(request);
	}

	if (getMethods().isEmpty()) {
		if (RequestMethod.OPTIONS.name().equals(request.getMethod()) &&
				!DispatcherType.ERROR.equals(request.getDispatcherType())) {

			return null; // We handle OPTIONS transparently, so don't match if no explicit declarations
		}
		return this;
	}

	return matchRequestMethod(request.getMethod());
}
 
Example 2
Source File: FrameworkServlet.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Delegate OPTIONS requests to {@link #processRequest}, if desired.
 * <p>Applies HttpServlet's standard OPTIONS processing otherwise,
 * and also if there is still no 'Allow' header set after dispatching.
 * @see #doService
 */
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

	if (this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)) {
		processRequest(request, response);
		if (response.containsHeader("Allow")) {
			// Proper OPTIONS response coming from a handler - we're done.
			return;
		}
	}

	// Use response wrapper for Servlet 2.5 compatibility where
	// the getHeader() method does not exist
	super.doOptions(request, new HttpServletResponseWrapper(response) {
		@Override
		public void setHeader(String name, String value) {
			if ("Allow".equals(name)) {
				value = (StringUtils.hasLength(value) ? value + ", " : "") + HttpMethod.PATCH.name();
			}
			super.setHeader(name, value);
		}
	});
}
 
Example 3
Source File: RequestMethodsRequestCondition.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Check if any of the HTTP request methods match the given request and
 * return an instance that contains the matching HTTP request method only.
 * @param request the current request
 * @return the same instance if the condition is empty (unless the request
 * method is HTTP OPTIONS), a new condition with the matched request method,
 * or {@code null} if there is no match or the condition is empty and the
 * request method is OPTIONS.
 */
@Override
public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return matchPreFlight(request);
	}

	if (getMethods().isEmpty()) {
		if (RequestMethod.OPTIONS.name().equals(request.getMethod()) &&
				!DispatcherType.ERROR.equals(request.getDispatcherType())) {

			return null; // No implicit match for OPTIONS (we handle it)
		}
		return this;
	}

	return matchRequestMethod(request.getMethod());
}
 
Example 4
Source File: FrameworkServlet.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Delegate OPTIONS requests to {@link #processRequest}, if desired.
 * <p>Applies HttpServlet's standard OPTIONS processing otherwise,
 * and also if there is still no 'Allow' header set after dispatching.
 * @see #doService
 */
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

	if (this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)) {
		processRequest(request, response);
		if (response.containsHeader("Allow")) {
			// Proper OPTIONS response coming from a handler - we're done.
			return;
		}
	}

	// Use response wrapper in order to always add PATCH to the allowed methods
	super.doOptions(request, new HttpServletResponseWrapper(response) {
		@Override
		public void setHeader(String name, String value) {
			if ("Allow".equals(name)) {
				value = (StringUtils.hasLength(value) ? value + ", " : "") + HttpMethod.PATCH.name();
			}
			super.setHeader(name, value);
		}
	});
}
 
Example 5
Source File: ConsumesRequestCondition.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Checks if any of the contained media type expressions match the given
 * request 'Content-Type' header and returns an instance that is guaranteed
 * to contain matching expressions only. The match is performed via
 * {@link MediaType#includes(MediaType)}.
 * @param request the current request
 * @return the same instance if the condition contains no expressions;
 * or a new condition with matching expressions only;
 * or {@code null} if no expressions match
 */
@Override
@Nullable
public ConsumesRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return PRE_FLIGHT_MATCH;
	}
	if (isEmpty()) {
		return this;
	}

	MediaType contentType;
	try {
		contentType = (StringUtils.hasLength(request.getContentType()) ?
				MediaType.parseMediaType(request.getContentType()) :
				MediaType.APPLICATION_OCTET_STREAM);
	}
	catch (InvalidMediaTypeException ex) {
		return null;
	}

	Set<ConsumeMediaTypeExpression> result = new LinkedHashSet<>(this.expressions);
	result.removeIf(expression -> !expression.match(contentType));
	return (!result.isEmpty() ? new ConsumesRequestCondition(result) : null);
}
 
Example 6
Source File: RequestMethodsRequestCondition.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Check if any of the HTTP request methods match the given request and
 * return an instance that contains the matching HTTP request method only.
 * @param request the current request
 * @return the same instance if the condition is empty (unless the request
 * method is HTTP OPTIONS), a new condition with the matched request method,
 * or {@code null} if there is no match or the condition is empty and the
 * request method is OPTIONS.
 */
@Override
@Nullable
public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return matchPreFlight(request);
	}

	if (getMethods().isEmpty()) {
		if (RequestMethod.OPTIONS.name().equals(request.getMethod()) &&
				!DispatcherType.ERROR.equals(request.getDispatcherType())) {

			return null; // No implicit match for OPTIONS (we handle it)
		}
		return this;
	}

	return matchRequestMethod(request.getMethod());
}
 
Example 7
Source File: CorsFilter.java    From halo with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;

    // Set customized header
    String originHeaderValue = httpServletRequest.getHeader(HttpHeaders.ORIGIN);
    if (StringUtils.isNotBlank(originHeaderValue)) {
        httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, originHeaderValue);
    }
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, ALLOW_HEADERS);
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS");
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");

    if (!CorsUtils.isPreFlightRequest(httpServletRequest)) {
        chain.doFilter(httpServletRequest, httpServletResponse);
    }
}
 
Example 8
Source File: CorsFilter.java    From java-technology-stack with MIT License 6 votes vote down vote up
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
		FilterChain filterChain) throws ServletException, IOException {

	if (CorsUtils.isCorsRequest(request)) {
		CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
		if (corsConfiguration != null) {
			boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
			if (!isValid || CorsUtils.isPreFlightRequest(request)) {
				return;
			}
		}
	}

	filterChain.doFilter(request, response);
}
 
Example 9
Source File: FrameworkServlet.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Delegate OPTIONS requests to {@link #processRequest}, if desired.
 * <p>Applies HttpServlet's standard OPTIONS processing otherwise,
 * and also if there is still no 'Allow' header set after dispatching.
 * @see #doService
 */
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

	if (this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)) {
		processRequest(request, response);
		if (response.containsHeader("Allow")) {
			// Proper OPTIONS response coming from a handler - we're done.
			return;
		}
	}

	// Use response wrapper in order to always add PATCH to the allowed methods
	super.doOptions(request, new HttpServletResponseWrapper(response) {
		@Override
		public void setHeader(String name, String value) {
			if ("Allow".equals(name)) {
				value = (StringUtils.hasLength(value) ? value + ", " : "") + HttpMethod.PATCH.name();
			}
			super.setHeader(name, value);
		}
	});
}
 
Example 10
Source File: HeadersRequestCondition.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns "this" instance if the request matches all expressions;
 * or {@code null} otherwise.
 */
@Override
public HeadersRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return PRE_FLIGHT_MATCH;
	}
	for (HeaderExpression expression : expressions) {
		if (!expression.match(request)) {
			return null;
		}
	}
	return this;
}
 
Example 11
Source File: ConsumesRequestCondition.java    From spring-analysis-note with MIT License 5 votes vote down vote up
/**
 * Checks if any of the contained media type expressions match the given
 * request 'Content-Type' header and returns an instance that is guaranteed
 * to contain matching expressions only. The match is performed via
 * {@link MediaType#includes(MediaType)}.
 * @param request the current request
 * @return the same instance if the condition contains no expressions;
 * or a new condition with matching expressions only;
 * or {@code null} if no expressions match
 */
@Override
@Nullable
public ConsumesRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return EMPTY_CONDITION;
	}
	if (isEmpty()) {
		return this;
	}
	if (!hasBody(request) && !this.bodyRequired) {
		return EMPTY_CONDITION;
	}

	// Common media types are cached at the level of MimeTypeUtils

	MediaType contentType;
	try {
		contentType = StringUtils.hasLength(request.getContentType()) ?
				MediaType.parseMediaType(request.getContentType()) :
				MediaType.APPLICATION_OCTET_STREAM;
	}
	catch (InvalidMediaTypeException ex) {
		return null;
	}

	List<ConsumeMediaTypeExpression> result = getMatchingExpressions(contentType);
	return !CollectionUtils.isEmpty(result) ? new ConsumesRequestCondition(result) : null;
}
 
Example 12
Source File: ProducesRequestCondition.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Checks if any of the contained media type expressions match the given
 * request 'Content-Type' header and returns an instance that is guaranteed
 * to contain matching expressions only. The match is performed via
 * {@link MediaType#isCompatibleWith(MediaType)}.
 * @param request the current request
 * @return the same instance if there are no expressions;
 * or a new condition with matching expressions;
 * or {@code null} if no expressions match.
 */
@Override
public ProducesRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return PRE_FLIGHT_MATCH;
	}
	if (isEmpty()) {
		return this;
	}
	List<MediaType> acceptedMediaTypes;
	try {
		acceptedMediaTypes = getAcceptedMediaTypes(request);
	}
	catch (HttpMediaTypeException ex) {
		return null;
	}
	Set<ProduceMediaTypeExpression> result = new LinkedHashSet<ProduceMediaTypeExpression>(expressions);
	for (Iterator<ProduceMediaTypeExpression> iterator = result.iterator(); iterator.hasNext();) {
		ProduceMediaTypeExpression expression = iterator.next();
		if (!expression.match(acceptedMediaTypes)) {
			iterator.remove();
		}
	}
	if (!result.isEmpty()) {
		return new ProducesRequestCondition(result, this.contentNegotiationManager);
	}
	else if (acceptedMediaTypes.contains(MediaType.ALL)) {
		return EMPTY_CONDITION;
	}
	else {
		return null;
	}
}
 
Example 13
Source File: RequestMappingInfo.java    From spring4-understanding with Apache License 2.0 5 votes vote down vote up
/**
 * Checks if all conditions in this request mapping info match the provided request and returns
 * a potentially new request mapping info with conditions tailored to the current request.
 * <p>For example the returned instance may contain the subset of URL patterns that match to
 * the current request, sorted with best matching patterns on top.
 * @return a new instance in case all conditions match; or {@code null} otherwise
 */
@Override
public RequestMappingInfo getMatchingCondition(HttpServletRequest request) {
	RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(request);
	ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(request);
	HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(request);
	ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(request);
	ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(request);

	if (methods == null || params == null || headers == null || consumes == null || produces == null) {
		if (CorsUtils.isPreFlightRequest(request)) {
			methods = getAccessControlRequestMethodCondition(request);
			if (methods == null || params == null) {
				return null;
			}
		}
		else {
			return null;
		}
	}

	PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(request);
	if (patterns == null) {
		return null;
	}

	RequestConditionHolder custom = this.customConditionHolder.getMatchingCondition(request);
	if (custom == null) {
		return null;
	}

	return new RequestMappingInfo(this.name, patterns,
			methods, params, headers, consumes, produces, custom.getCondition());
}
 
Example 14
Source File: ProducesRequestCondition.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * Checks if any of the contained media type expressions match the given
 * request 'Content-Type' header and returns an instance that is guaranteed
 * to contain matching expressions only. The match is performed via
 * {@link MediaType#isCompatibleWith(MediaType)}.
 * @param request the current request
 * @return the same instance if there are no expressions;
 * or a new condition with matching expressions;
 * or {@code null} if no expressions match.
 */
@Override
@Nullable
public ProducesRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return PRE_FLIGHT_MATCH;
	}
	if (isEmpty()) {
		return this;
	}

	List<MediaType> acceptedMediaTypes;
	try {
		acceptedMediaTypes = getAcceptedMediaTypes(request);
	}
	catch (HttpMediaTypeException ex) {
		return null;
	}

	Set<ProduceMediaTypeExpression> result = new LinkedHashSet<>(this.expressions);
	result.removeIf(expression -> !expression.match(acceptedMediaTypes));
	if (!result.isEmpty()) {
		return new ProducesRequestCondition(result, this.contentNegotiationManager);
	}
	else if (MediaType.ALL.isPresentIn(acceptedMediaTypes)) {
		return EMPTY_CONDITION;
	}
	else {
		return null;
	}
}
 
Example 15
Source File: HeadersRequestCondition.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * Returns "this" instance if the request matches all expressions;
 * or {@code null} otherwise.
 */
@Override
@Nullable
public HeadersRequestCondition getMatchingCondition(HttpServletRequest request) {
	if (CorsUtils.isPreFlightRequest(request)) {
		return PRE_FLIGHT_MATCH;
	}
	for (HeaderExpression expression : this.expressions) {
		if (!expression.match(request)) {
			return null;
		}
	}
	return this;
}
 
Example 16
Source File: CorsFilter.java    From zfile with MIT License 5 votes vote down vote up
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;

    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, httpServletRequest.getHeader(HttpHeaders.ORIGIN));
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Origin, X-Requested-With, Content-Type, Accept");
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS");
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");

    if (!CorsUtils.isPreFlightRequest(httpServletRequest)) {
        chain.doFilter(httpServletRequest, httpServletResponse);
    }
}
 
Example 17
Source File: CorsFilter.java    From spring-analysis-note with MIT License 5 votes vote down vote up
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
		FilterChain filterChain) throws ServletException, IOException {

	CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
	boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
	if (!isValid || CorsUtils.isPreFlightRequest(request)) {
		return;
	}
	filterChain.doFilter(request, response);
}
 
Example 18
Source File: AbstractHandlerMethodMapping.java    From spring4-understanding with Apache License 2.0 5 votes vote down vote up
/**
 * Look up the best-matching handler method for the current request.
 * If multiple matches are found, the best match is selected.
 * @param lookupPath mapping lookup path within the current servlet mapping
 * @param request the current request
 * @return the best-matching handler method, or {@code null} if no match
 * @see #handleMatch(Object, String, HttpServletRequest)
 * @see #handleNoMatch(Set, String, HttpServletRequest)
 */
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
	List<Match> matches = new ArrayList<Match>();
	List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
	if (directPathMatches != null) {
		addMatchingMappings(directPathMatches, matches, request);
	}
	if (matches.isEmpty()) {
		// No choice but to go through all mappings...
		addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
	}

	if (!matches.isEmpty()) {
		Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
		Collections.sort(matches, comparator);
		if (logger.isTraceEnabled()) {
			logger.trace("Found " + matches.size() + " matching mapping(s) for [" +
					lookupPath + "] : " + matches);
		}
		Match bestMatch = matches.get(0);
		if (matches.size() > 1) {
			if (CorsUtils.isPreFlightRequest(request)) {
				return PREFLIGHT_AMBIGUOUS_MATCH;
			}
			Match secondBestMatch = matches.get(1);
			if (comparator.compare(bestMatch, secondBestMatch) == 0) {
				Method m1 = bestMatch.handlerMethod.getMethod();
				Method m2 = secondBestMatch.handlerMethod.getMethod();
				throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +
						request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
			}
		}
		handleMatch(bestMatch.mapping, lookupPath, request);
		return bestMatch.handlerMethod;
	}
	else {
		return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
	}
}
 
Example 19
Source File: AbstractHandlerMethodMapping.java    From java-technology-stack with MIT License 4 votes vote down vote up
/**
 * Look up the best-matching handler method for the current request.
 * If multiple matches are found, the best match is selected.
 * @param lookupPath mapping lookup path within the current servlet mapping
 * @param request the current request
 * @return the best-matching handler method, or {@code null} if no match
 * @see #handleMatch(Object, String, HttpServletRequest)
 * @see #handleNoMatch(Set, String, HttpServletRequest)
 */
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
	List<Match> matches = new ArrayList<>();
	List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
	if (directPathMatches != null) {
		addMatchingMappings(directPathMatches, matches, request);
	}
	if (matches.isEmpty()) {
		// No choice but to go through all mappings...
		addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
	}

	if (!matches.isEmpty()) {
		Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
		matches.sort(comparator);
		Match bestMatch = matches.get(0);
		if (matches.size() > 1) {
			if (logger.isTraceEnabled()) {
				logger.trace(matches.size() + " matching mappings: " + matches);
			}
			if (CorsUtils.isPreFlightRequest(request)) {
				return PREFLIGHT_AMBIGUOUS_MATCH;
			}
			Match secondBestMatch = matches.get(1);
			if (comparator.compare(bestMatch, secondBestMatch) == 0) {
				Method m1 = bestMatch.handlerMethod.getMethod();
				Method m2 = secondBestMatch.handlerMethod.getMethod();
				String uri = request.getRequestURI();
				throw new IllegalStateException(
						"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
			}
		}
		request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
		handleMatch(bestMatch.mapping, lookupPath, request);
		return bestMatch.handlerMethod;
	}
	else {
		return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
	}
}
 
Example 20
Source File: AbstractHandlerMethodMapping.java    From spring-analysis-note with MIT License 4 votes vote down vote up
/**
 * Look up the best-matching handler method for the current request.
 * If multiple matches are found, the best match is selected.
 *
 * 为当前请求寻找最合适的处理器,如果有多个匹配,选择最合适的一个
 *
 * @param lookupPath mapping lookup path within the current servlet mapping
 * @param request the current request
 * @return the best-matching handler method, or {@code null} if no match
 * @see #handleMatch(Object, String, HttpServletRequest)
 * @see #handleNoMatch(Set, String, HttpServletRequest)
 */
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
	List<Match> matches = new ArrayList<>();
	List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
	if (directPathMatches != null) {
		addMatchingMappings(directPathMatches, matches, request);
	}
	if (matches.isEmpty()) {
		// No choice but to go through all mappings...
		addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
	}

	if (!matches.isEmpty()) {
		Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
		matches.sort(comparator);
		Match bestMatch = matches.get(0);
		if (matches.size() > 1) {
			if (logger.isTraceEnabled()) {
				logger.trace(matches.size() + " matching mappings: " + matches);
			}
			if (CorsUtils.isPreFlightRequest(request)) {
				return PREFLIGHT_AMBIGUOUS_MATCH;
			}
			Match secondBestMatch = matches.get(1);
			if (comparator.compare(bestMatch, secondBestMatch) == 0) {
				Method m1 = bestMatch.handlerMethod.getMethod();
				Method m2 = secondBestMatch.handlerMethod.getMethod();
				String uri = request.getRequestURI();
				throw new IllegalStateException(
						"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
			}
		}
		request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
		handleMatch(bestMatch.mapping, lookupPath, request);
		return bestMatch.handlerMethod;
	}
	else {
		return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
	}
}