Skip to content

Commit 6920a1f

Browse files
committed
ForwardedHeaderFilter handles query+fragment correctly
Issue: SPR-16506
1 parent dcf5c64 commit 6920a1f

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -324,13 +324,33 @@ public void sendRedirect(String location) throws IOException {
324324
return;
325325
}
326326

327+
String fragment = null;
328+
int fragmentIndex = location.indexOf('#');
329+
if (fragmentIndex != -1) {
330+
if (location.length() > fragmentIndex) {
331+
fragment = location.substring(fragmentIndex + 1);
332+
}
333+
location = location.substring(0, fragmentIndex);
334+
}
335+
336+
String query = null;
337+
int queryIndex = location.indexOf('?');
338+
if (queryIndex != -1) {
339+
if (location.length() > queryIndex) {
340+
query = location.substring(queryIndex + 1);
341+
}
342+
location = location.substring(0, queryIndex);
343+
}
344+
327345
// Relative to Servlet container root or to current request
328346
String path = (location.startsWith(FOLDER_SEPARATOR) ? location :
329347
StringUtils.applyRelativePath(this.request.getRequestURI(), location));
330348

331349
String result = UriComponentsBuilder
332350
.fromHttpRequest(new ServletServerHttpRequest(this.request))
333351
.replacePath(path)
352+
.replaceQuery(query)
353+
.fragment(fragment)
334354
.build().normalize().toUriString();
335355

336356
super.sendRedirect(result);

spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -301,6 +301,17 @@ public void sendRedirectWithAbsolutePath() throws Exception {
301301
assertEquals("https://example.com/foo/bar", redirectedUrl);
302302
}
303303

304+
@Test // SPR-16506
305+
public void sendRedirectWithAbsolutePathQueryParamAndFragment() throws Exception {
306+
this.request.addHeader(X_FORWARDED_PROTO, "https");
307+
this.request.addHeader(X_FORWARDED_HOST, "example.com");
308+
this.request.addHeader(X_FORWARDED_PORT, "443");
309+
this.request.setQueryString("oldqp=1");
310+
311+
String redirectedUrl = sendRedirect("/foo/bar?newqp=2#fragment");
312+
assertEquals("https://example.com/foo/bar?newqp=2#fragment", redirectedUrl);
313+
}
314+
304315
@Test
305316
public void sendRedirectWithContextPath() throws Exception {
306317
this.request.addHeader(X_FORWARDED_PROTO, "https");

0 commit comments

Comments
 (0)