Compare commits

...

11 Commits

Author SHA1 Message Date
Vedran Pavic
84479a0ba0 Release 2.1.8.RELEASE 2019-08-05 17:04:17 +02:00
Vedran Pavic
643f9cfd1a Update integration tests 2019-08-05 13:54:54 +02:00
Vedran Pavic
95e6d710ba Upgrade test dependencies 2019-08-05 13:54:29 +02:00
Vedran Pavic
0cf723c6aa Upgrade Spring Data to Lovelace-SR10
Resolves: #1473
2019-08-05 13:53:48 +02:00
Vedran Pavic
66cc442b5f Update integration tests 2019-08-03 09:27:46 +02:00
Vedran Pavic
23d8c18b22 Upgrade test dependencies 2019-08-03 09:26:52 +02:00
Vedran Pavic
28d1d4fd00 Upgrade Spring Framework to 5.1.9.RELEASE
Resolves: #1464
2019-08-03 09:25:15 +02:00
Vedran Pavic
e82a856d00 Upgrade Reactor to Californium-SR10
Resolves: #1472
2019-08-03 09:24:25 +02:00
Vedran Pavic
e40e55d1e9 Filtering for nested ERROR dispatch
Resolves: #1470
See: spring-projects/spring-framework#23196
2019-07-19 21:06:30 +02:00
Vedran Pavic
a289938c7c Upgrade samples to Spring Boot 2.1.6.RELEASE
Resolves: #1463
2019-06-20 11:43:05 +02:00
Rob Winch
63927aa4da Next Development Version 2019-06-14 16:52:21 -05:00
8 changed files with 99 additions and 34 deletions

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.1.5.RELEASE'
springBootVersion = '2.1.6.RELEASE'
}
repositories {

View File

@@ -1 +1 @@
version=2.1.7.RELEASE
version=2.1.8.RELEASE

View File

@@ -1,11 +1,11 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.9.6'
mavenBom 'io.projectreactor:reactor-bom:Californium-SR9'
mavenBom 'org.springframework:spring-framework-bom:5.1.8.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-SR9'
mavenBom 'io.projectreactor:reactor-bom:Californium-SR10'
mavenBom 'org.springframework:spring-framework-bom:5.1.9.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-SR10'
mavenBom 'org.springframework.security:spring-security-bom:5.1.5.RELEASE'
mavenBom 'org.testcontainers:testcontainers-bom:1.11.3'
mavenBom 'org.testcontainers:testcontainers-bom:1.12.0'
}
dependencies {
@@ -15,19 +15,19 @@ dependencyManagement {
}
dependency 'com.h2database:h2:1.4.199'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.2.2.jre8'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8'
dependency 'com.zaxxer:HikariCP:3.3.1'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:5.1.7.RELEASE'
dependency 'io.lettuce:lettuce-core:5.1.8.RELEASE'
dependency 'javax.annotation:javax.annotation-api:1.3.2'
dependency 'javax.servlet:javax.servlet-api:4.0.1'
dependency 'junit:junit:4.12'
dependency 'mysql:mysql-connector-java:8.0.16'
dependency 'mysql:mysql-connector-java:8.0.17'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.12.2'
dependency 'org.assertj:assertj-core:3.13.2'
dependency 'org.hsqldb:hsqldb:2.5.0'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
dependency 'org.mockito:mockito-core:2.28.2'
dependency 'org.postgresql:postgresql:42.2.5'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.4.3'
dependency 'org.mockito:mockito-core:3.0.0'
dependency 'org.postgresql:postgresql:42.2.6'
}
}

View File

@@ -68,13 +68,14 @@ abstract class OncePerRequestFilter implements Filter {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = this.alreadyFilteredAttributeName;
alreadyFilteredAttributeName = updateForErrorDispatch(
alreadyFilteredAttributeName, request);
boolean hasAlreadyFilteredAttribute = request
.getAttribute(alreadyFilteredAttributeName) != null;
if (hasAlreadyFilteredAttribute) {
if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);
return;
}
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
@@ -91,15 +92,39 @@ abstract class OncePerRequestFilter implements Filter {
}
}
private String updateForErrorDispatch(String alreadyFilteredAttributeName,
ServletRequest request) {
// Jetty does ERROR dispatch within sendError, so request attribute is still present
// Use a separate attribute for ERROR dispatches
if (DispatcherType.ERROR.equals(request.getDispatcherType())
&& request.getAttribute(alreadyFilteredAttributeName) != null) {
return alreadyFilteredAttributeName + ".ERROR";
}
return alreadyFilteredAttributeName;
/**
* Return the name of the request attribute that identifies that a request is already
* filtered.
* <p>
* The default implementation takes the configured name of the concrete filter
* instance and appends ".FILTERED". If the filter is not fully initialized, it falls
* back to its class name.
* @return the name of request attribute indicating already filtered request
* @see #ALREADY_FILTERED_SUFFIX
*/
protected String getAlreadyFilteredAttributeName() {
return this.alreadyFilteredAttributeName;
}
/**
* Typically an ERROR dispatch happens after the REQUEST dispatch completes, and the
* filter chain starts anew. On some servers however the ERROR dispatch may be nested
* within the REQUEST dispatch, e.g. as a result of calling {@code sendError} on the
* response. In that case we are still in the filter chain, on the same thread, but
* the request and response have been switched to the original, unwrapped ones.
* <p>
* Sub-classes may use this method to filter such nested ERROR dispatches and re-apply
* wrapping on the request or response. {@code ThreadLocal} context, if any, should
* still be active as we are still nested within the filter chain.
* @param request the request
* @param response the response
* @param filterChain the filter chain
* @throws ServletException if request is not HTTP request
* @throws IOException in case of I/O operation exception
*/
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilter(request, response, filterChain);
}
/**

View File

@@ -159,6 +159,12 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
this.servletContext = servletContext;
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilterInternal(request, response, filterChain);
}
/**
* Allows ensuring that the session is saved if the response is committed.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2019 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.
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -32,6 +33,7 @@ import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.util.WebUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -95,4 +97,36 @@ public class OncePerRequestFilterTests {
assertThat(this.invocations).containsOnly(this.filter, filter2);
}
@Test // gh-1470
public void filterNestedErrorDispatch() throws ServletException, IOException {
TestOncePerRequestFilter filter = new TestOncePerRequestFilter();
this.request.setAttribute(filter.getAlreadyFilteredAttributeName(), Boolean.TRUE);
this.request.setDispatcherType(DispatcherType.ERROR);
this.request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error");
filter.doFilter(this.request, new MockHttpServletResponse(), this.chain);
assertThat(filter.didFilter).isFalse();
assertThat(filter.didFilterNestedErrorDispatch).isTrue();
}
private static class TestOncePerRequestFilter extends OncePerRequestFilter {
private boolean didFilter;
private boolean didFilterNestedErrorDispatch;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) {
this.didFilter = true;
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) {
this.didFilterNestedErrorDispatch = true;
}
}
}

View File

@@ -88,7 +88,7 @@ final class DatabaseContainers {
private static class MariaDb10Container extends MariaDBContainer<MariaDb10Container> {
MariaDb10Container() {
super("mariadb:10.3.15");
super("mariadb:10.4.7");
}
@Override
@@ -103,7 +103,7 @@ final class DatabaseContainers {
private static class MySql5Container extends MySQLContainer<MySql5Container> {
MySql5Container() {
super("mysql:5.7.26");
super("mysql:5.7.27");
}
@Override
@@ -123,7 +123,7 @@ final class DatabaseContainers {
private static class MySql8Container extends MySQLContainer<MySql8Container> {
MySql8Container() {
super("mysql:8.0.16");
super("mysql:8.0.17");
}
@Override
@@ -143,7 +143,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql9Container> {
PostgreSql9Container() {
super("postgres:9.6.13");
super("postgres:9.6.14");
}
}
@@ -152,7 +152,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql10Container> {
PostgreSql10Container() {
super("postgres:10.8");
super("postgres:10.9");
}
}
@@ -161,7 +161,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql11Container> {
PostgreSql11Container() {
super("postgres:11.3");
super("postgres:11.4");
}
}
@@ -170,7 +170,7 @@ final class DatabaseContainers {
extends MSSQLServerContainer<SqlServer2017Container> {
SqlServer2017Container() {
super("mcr.microsoft.com/mssql/server:2017-CU15");
super("mcr.microsoft.com/mssql/server:2017-cu16");
}
}

View File

@@ -1 +1 @@
mcr.microsoft.com/mssql/server:2017-CU15
mcr.microsoft.com/mssql/server:2017-cu16