All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.web.filter.reactive.ForwardedHeaderFilter Maven / Gradle / Ivy

There is a newer version: 6.1.6
Show newest version
/*
 * Copyright 2002-2017 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.filter.reactive;

import java.net.URI;
import java.util.LinkedHashSet;
import java.util.Set;

import reactor.core.publisher.Mono;

import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.lang.Nullable;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponentsBuilder;

/**
 * Extract values from "Forwarded" and "X-Forwarded-*" headers in order to change
 * and override {@link ServerHttpRequest#getURI()}.
 * In effect the request URI will reflect the client-originated
 * protocol and address.
 *
 * 

Note: This filter can also be used in a * {@link #setRemoveOnly removeOnly} mode where "Forwarded" and "X-Forwarded-*" * headers are only eliminated without being used. * @author Arjen Poutsma * @see https://tools.ietf.org/html/rfc7239 * @since 5.0 */ public class ForwardedHeaderFilter implements WebFilter { private static final Set FORWARDED_HEADER_NAMES = new LinkedHashSet<>(5); static { FORWARDED_HEADER_NAMES.add("Forwarded"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Host"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Port"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Proto"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix"); } private boolean removeOnly; /** * Enables mode in which any "Forwarded" or "X-Forwarded-*" headers are * removed only and the information in them ignored. * @param removeOnly whether to discard and ignore forwarded headers */ public void setRemoveOnly(boolean removeOnly) { this.removeOnly = removeOnly; } @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { if (shouldNotFilter(exchange.getRequest())) { return chain.filter(exchange); } if (this.removeOnly) { ServerWebExchange withoutForwardHeaders = exchange.mutate() .request(builder -> builder.headers( headers -> { for (String headerName : FORWARDED_HEADER_NAMES) { headers.remove(headerName); } })).build(); return chain.filter(withoutForwardHeaders); } else { URI uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).build().toUri(); String prefix = getForwardedPrefix(exchange.getRequest().getHeaders()); ServerWebExchange withChangedUri = exchange.mutate() .request(builder -> { builder.uri(uri); if (prefix != null) { builder.path(prefix + uri.getPath()); builder.contextPath(prefix); } }).build(); return chain.filter(withChangedUri); } } private boolean shouldNotFilter(ServerHttpRequest request) { HttpHeaders headers = request.getHeaders(); for (String headerName : FORWARDED_HEADER_NAMES) { if (headers.containsKey(headerName)) { return false; } } return true; } @Nullable private static String getForwardedPrefix(HttpHeaders headers) { String prefix = headers.getFirst("X-Forwarded-Prefix"); if (prefix != null) { while (prefix.endsWith("/")) { prefix = prefix.substring(0, prefix.length() - 1); } } return prefix; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy