001/*002 * Copyright 2002-2020 the original author or authors.003 *004 * Licensed under the Apache License, Version 2.0 (the "License");005 * you may not use this file except in compliance with the License.006 * You may obtain a copy of the License at007 *008 * https://www.apache.org/licenses/LICENSE-2.0009 *010 * Unless required by applicable law or agreed to in writing, software011 * distributed under the License is distributed on an "AS IS" BASIS,012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.013 * See the License for the specific language governing permissions and014 * limitations under the License.015 */016017package org.springframework.web.servlet.mvc.condition;018019import java.util.Collection;020import java.util.Collections;021import java.util.LinkedHashSet;022import java.util.Set;023024import javax.servlet.http.HttpServletRequest;025026import org.springframework.lang.Nullable;027import org.springframework.util.ObjectUtils;028import org.springframework.web.bind.annotation.RequestMapping;029import org.springframework.web.cors.CorsUtils;030031/**032 * A logical conjunction (' && ') request condition that matches a request against033 * a set of header expressions with syntax defined in {@link RequestMapping#headers()}.034 *035 * <p>Expressions passed to the constructor with header names 'Accept' or036 * 'Content-Type' are ignored. See {@link ConsumesRequestCondition} and037 * {@link ProducesRequestCondition} for those.038 *039 * @author Arjen Poutsma040 * @author Rossen Stoyanchev041 * @since 3.1042 */043public final class HeadersRequestCondition extends AbstractRequestCondition<HeadersRequestCondition> {044045 private static final HeadersRequestCondition PRE_FLIGHT_MATCH = new HeadersRequestCondition();046047048 private final Set<HeaderExpression> expressions;049050051 /**052 * Create a new instance from the given header expressions. Expressions with053 * header names 'Accept' or 'Content-Type' are ignored. See {@link ConsumesRequestCondition}054 * and {@link ProducesRequestCondition} for those.055 * @param headers media type expressions with syntax defined in {@link RequestMapping#headers()};056 * if 0, the condition will match to every request057 */058 public HeadersRequestCondition(String... headers) {059 this.expressions = parseExpressions(headers);060 }061062 private static Set<HeaderExpression> parseExpressions(String... headers) {063 Set<HeaderExpression> result = null;064 if (!ObjectUtils.isEmpty(headers)) {065 for (String header : headers) {066 HeaderExpression expr = new HeaderExpression(header);067 if ("Accept".equalsIgnoreCase(expr.name) || "Content-Type".equalsIgnoreCase(expr.name)) {068 continue;069 }070 result = (result != null ? result : new LinkedHashSet<>(headers.length));071 result.add(expr);072