From 4351f3511c600158c7daa20e6afb77f7bc9e47f1 Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Tue, 7 Aug 2018 09:30:42 +0200 Subject: [PATCH] Override JSON Content-Type sent by client for /v2 Fixes regression introduced by commit 7eec95aea7e68e3d3c42ba714d731f27894df61d. --- .../java/de/thm/arsnova/config/AppConfig.java | 6 +- .../controller/v2/LegacyController.java | 2 +- .../web/V2ContentTypeOverrideFilter.java | 73 +++++++++++++++++++ src/main/webapp/WEB-INF/web.xml | 10 +++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 src/main/java/de/thm/arsnova/web/V2ContentTypeOverrideFilter.java diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java index 75b6e5b8d..ac83e4602 100644 --- a/src/main/java/de/thm/arsnova/config/AppConfig.java +++ b/src/main/java/de/thm/arsnova/config/AppConfig.java @@ -100,8 +100,10 @@ import java.util.List; encoding = "UTF-8" ) public class AppConfig implements WebMvcConfigurer { - public static final MediaType API_V2_MEDIA_TYPE = new MediaType("application", "vnd.de.thm.arsnova.v2+json"); - public static final MediaType API_V3_MEDIA_TYPE = new MediaType("application", "vnd.de.thm.arsnova.v3+json"); + public static final String API_V2_MEDIA_TYPE_VALUE = "application/vnd.de.thm.arsnova.v2+json"; + public static final String API_V3_MEDIA_TYPE_VALUE = "application/vnd.de.thm.arsnova.v3+json"; + public static final MediaType API_V2_MEDIA_TYPE = MediaType.valueOf(API_V2_MEDIA_TYPE_VALUE); + public static final MediaType API_V3_MEDIA_TYPE = MediaType.valueOf(API_V3_MEDIA_TYPE_VALUE); @Autowired private Environment env; diff --git a/src/main/java/de/thm/arsnova/controller/v2/LegacyController.java b/src/main/java/de/thm/arsnova/controller/v2/LegacyController.java index 80eb19c4d..834d1fd97 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/LegacyController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/LegacyController.java @@ -159,7 +159,7 @@ public class LegacyController extends AbstractController { } @DeprecatedApi - @RequestMapping(value = "/whoami") + @RequestMapping(value = { "/whoami", "/whoami.json" }) public String redirectWhoami() { return "forward:/v2/auth/whoami"; } diff --git a/src/main/java/de/thm/arsnova/web/V2ContentTypeOverrideFilter.java b/src/main/java/de/thm/arsnova/web/V2ContentTypeOverrideFilter.java new file mode 100644 index 000000000..b31f747b3 --- /dev/null +++ b/src/main/java/de/thm/arsnova/web/V2ContentTypeOverrideFilter.java @@ -0,0 +1,73 @@ +package de.thm.arsnova.web; + +import de.thm.arsnova.config.AppConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +/** + * This {@link javax.servlet.Filter} overrides the Content-Type for JSON data sent by the client with the ARSnova API v2 + * JSON Content-Type. + * + * @author Daniel Gerhardt + */ +@Component +public class V2ContentTypeOverrideFilter extends OncePerRequestFilter { + private static final Logger logger = LoggerFactory.getLogger(V2ContentTypeOverrideFilter.class); + private final List<String> contentTypeHeaders; + + { + contentTypeHeaders = new ArrayList<>(); + contentTypeHeaders.add(AppConfig.API_V2_MEDIA_TYPE_VALUE); + } + + @Override + protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, + final FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest requestWrapper = new HttpServletRequestWrapper(request) { + @Override + public String getHeader(final String name) { + String header = super.getHeader(name); + if (header != null && HttpHeaders.CONTENT_TYPE.equals(name) + && MediaType.APPLICATION_JSON.includes(MediaType.valueOf(header))) { + logger.debug("Overriding {} header: {}", HttpHeaders.CONTENT_TYPE, AppConfig.API_V2_MEDIA_TYPE_VALUE); + return AppConfig.API_V2_MEDIA_TYPE_VALUE; + } + + return header; + } + + @Override + public String getContentType() { + return getHeader(HttpHeaders.CONTENT_TYPE); + } + + @Override + public Enumeration<String> getHeaders(final String name) { + String firstHeader = super.getHeaders(name).nextElement(); + if (firstHeader != null && HttpHeaders.CONTENT_TYPE.equals(name) + && MediaType.APPLICATION_JSON.includes(MediaType.valueOf(firstHeader))) { + logger.debug("Overriding {} header: {}", HttpHeaders.CONTENT_TYPE, AppConfig.API_V2_MEDIA_TYPE_VALUE); + return Collections.enumeration(contentTypeHeaders); + } + + return super.getHeaders(name); + } + }; + filterChain.doFilter(requestWrapper, response); + } +} diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 573718341..f5e11a6bb 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -86,6 +86,16 @@ <url-pattern>/*</url-pattern> </filter-mapping> + <filter> + <filter-name>v2ContentTypeOverrideFilter</filter-name> + <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> + <async-supported>true</async-supported> + </filter> + <filter-mapping> + <filter-name>v2ContentTypeOverrideFilter</filter-name> + <url-pattern>/v2/*</url-pattern> + </filter-mapping> + <session-config> <tracking-mode>COOKIE</tracking-mode> </session-config> -- GitLab