Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to parse the content-type value from ALB request (json format) #315

Open
dotekien opened this issue Jan 11, 2020 · 9 comments
Open

Comments

@dotekien
Copy link

dotekien commented Jan 11, 2020

  • Framework version: 1.4
  • Implementations: Spring Boot 2

Scenario

Using SAM cli pass the alb request
sam local invoke -e alb-post.json

Here is the alb-post.json:
{ "requestContext": { "elb": { "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a" } }, "httpMethod": "POST", "path": "/accounts", "queryStringParameters": {}, "headers": { "accept": "application/json;v=1", "content-type": "application/json;v=1", "accept-encoding": "gzip", "accept-language": "en-US,en;q=0.9", "connection": "keep-alive", "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476", "x-forwarded-for": "72.12.164.125", "x-forwarded-port": "11400", "x-forwarded-proto": "http", "x-imforwards": "20" }, "body": "{\"accountId\":\"9999\",\"nextScoreRefreshDate\":\"2018-12-06\"}", "isBase64Encoded": false }

Expected behavior

The rest controller should be invoke and insert the new account to database

Actual behavior

Get this error:
Unexpected and uncaught exceporg.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported

Steps to reproduce

Run a sample pet-store with the ALB json request

Full log output

[2020-01-11 05:06:29.149] 982b37fe-a426-1403-10cf-41495a1288ec ERROR c.c.c.l.ScenarioReporter - CWCCD-2008, Description:Unexpected and uncaught exceporg.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supportedr at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:215)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:420)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:366)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:66)r at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:402)r at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1233)r at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016)r at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)r at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)r at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)r at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)r at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)r at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager$ServletExecutionFilter.doFilter(FilterChainManager.java:351)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.filter.RequestLoggingFilter.doFilter(RequestLoggingFilter.java:49)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.filter.VersionFilter.doFilter(VersionFilter.java:49)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)r at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)r at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)r at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)r at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)r at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)r at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:150)r at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:143)r at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:43)r at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:211)r at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:246)r at com.StreamLambdaHandler.handleRequest(StreamLambdaHandler.java:34)r at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)r at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)r at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)r at java.lang.reflect.Method.invoke(Method.java:498)r at lambdainternal.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:354)r at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:906)r at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:341)r at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:63)r at java.lang.Class.forName0(Native Method)r at java.lang.Class.forName(Class.java:348)r at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:114)r [2020-01-11 05:06:29.149] 982b37fe-a426-1403-10cf-41495a1288ec ERROR c.c.c.l.ScenarioReporter - CWCCD-2008, Description:Unexpected and uncaught exceporg.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supportedr at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:215)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:420)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:366)r at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:66)r at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:402)r at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1233)r at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016)r at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)r at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)r at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)r at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)r at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)r at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager$ServletExecutionFilter.doFilter(FilterChainManager.java:351)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.filter.RequestLoggingFilter.doFilter(RequestLoggingFilter.java:49)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.filter.VersionFilter.doFilter(VersionFilter.java:49)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)r at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)r at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)r at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)r at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)r at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)r at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)r at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)r at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)r at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:90)r at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:150)r at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:143)r at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:43)r at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:211)r at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:246)r at com.StreamLambdaHandler.handleRequest(StreamLambdaHandler.java:34)r at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)r at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)r at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)r at java.lang.reflect.Method.invoke(Method.java:498)r at lambdainternal.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:354)r at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:906)r at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:341)r at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:63)r at java.lang.Class.forName0(Native Method)r at java.lang.Class.forName(Class.java:348)r at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:114)r

@dotekien
Copy link
Author

It sounds like currently only header settings in MultiValueHeaders are extracted from the json request:
https://github.com/awslabs/aws-serverless-java-container/blob/21430d65062f5f072a376f1d6e89ed7158b59ae8/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java#L377

With ALB, the header values could be in both headers or multiValueHeaders.

@sapessi
Copy link
Collaborator

sapessi commented Apr 2, 2020

@dotekien the multiValueHeaders map should always be populated, even if both properties are included. Is that not the case?

@sapessi
Copy link
Collaborator

sapessi commented Apr 7, 2020

I'm sorry @dotekien - it is not by default, you need to configure ALB to populate those values. See the blog post here. We will update the documentation to clarify this and leave this issue open to collect feedback

sapessi added a commit that referenced this issue Apr 8, 2020
* Bump spring.version in /aws-serverless-java-container-spring (#319)

Bumps `spring.version` from 5.1.9.RELEASE to 5.2.3.RELEASE.

Updates `spring-webmvc` from 5.1.9.RELEASE to 5.2.3.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](spring-projects/spring-framework@v5.1.9.RELEASE...v5.2.3.RELEASE)

Updates `spring-test` from 5.1.9.RELEASE to 5.2.3.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](spring-projects/spring-framework@v5.1.9.RELEASE...v5.2.3.RELEASE)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump spring-webflux in /aws-serverless-java-container-springboot2 (#318)

Bumps [spring-webflux](https://github.com/spring-projects/spring-framework) from 5.1.9.RELEASE to 5.2.0.RELEASE.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](spring-projects/spring-framework@v5.1.9.RELEASE...v5.2.0.RELEASE)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* ci: Fixing Spring build to use 5.2 as latest

* chore(deps): Bump Spring 5.1 path release to address a security vulnerability

* chore(deps): Fixing usual spring dependency mess with exlusions out of the spring-security package used in the tests

* Fix for issue #317 (#323)

* fix issue 317 - use charset from request

* update dependencies

* update build dependencies, remove spring boot 2.0.x

* restoring ci config

Co-authored-by: Stefano Buliani <[email protected]>

* test: Fixed Spring security tests for SpringBoot 2, added validation tests and updated servlet tests to use the new servletApplication option

* fix: Avoid flushing the response buffer if we are dispatching the request asynchronously. This was causing race conditions in the SpringBoot 2 WebFlux implementation - requests that had to run through security or validation filters took longer and the library flushed an empty request, which caused the status code to default to 200. This fix addresses issues #279, #304, and #306

* chore(deps): Bump spring dependency version and added webmvc optional dependency to truly support Servlet-only server

* feat: New application type parameter to SpringBootLambdaContainerHandler that tells the framework whether to start a reactive or servlet-based embedded server. Also added a new servletApplication method to the builder object.

* test: Fixed UTF-8 encoding test

* ci: Fixed dependencies for CI run on SpringBoot 2

* ci: More Spring dependency convergence issues during CI

* fix: Added null-check on getServerName in case the multi-value headers property is null. Unlikely outside of tests but better safe than sorry. This addresses #327

* fix: Changed servlet initialization mechanism so that servlet that requests load on startup are initialized right away, as part of the initialization() method call in LambdaServletContainerHandler. Also centralized the lazy Servlet initialization to the ServletExecutionFilter so that we don't have code scattered all around. This begins to address #287

* feat: Added new 0-parameter constructor for async initializer that uses the actual JVM start time to calculate the timeout milliseconds. Also added the new method to the builder object and deprecated the current method that receives a milliseconds epoch parameter. I'm not deprecating the constructor of the async initializer class that receives the parameter as it may still be useful for tests. This change was suggested in #287

* fix: Updated SpringBoot 1.x handler to use the new servlet initialization mechanism

* ci: switch SpringBoot slow integration test to use a custom async time since the JVM is reused for both tests in the and we cannot reuse the actual JVM init time

* feat: New models for HTTP API support for #329

* feat: First implementation of HTTP API servlet request, request reader, and security context writer - continuing to address #329

* test: Basic unit tests for the new HTTP API support in core library (#329)

* feat: Updated log formatter to support both versions (1 and 2) of the proxy request model (#329)

* feat: Further generified request readers to read to a generic HttpServletRequest rather than specific implementations of it. This makes it easier to create container handler implementations that support HTTP API, API Gateway, and ALB (#329)

* test: Fixed tests for new logged and generified request readers

* feat: Added HTTP API support to Jersey implementation with new getHttpApiV2ProxyHandler method (#329)

* feat: Added HTTP API support to Spark implementation (#329)

* feat: Added HTTP API support to Spring implementation (#329)

* feat: HTTP API support in SpringBoot 2 implementation. bug: Fixed an issue with the implementation of AsyncContext where it wasn't dispatching if the handler wasn't set

* feat: First pass of HTTP API support in struts 2 implementation (#329)

* fix: Added support for HTTP APIs to the request dispatcher

* chore(deps): Dependency bump all around. Rotated Jersey ci versions

* fix: Updated stream handling logic to work with reactive applications as suggested in #316

* test: Added unit test to replicate #333

* feat: New configuration parameter to skip exception mapping and allow exception to bubble up from #307

* fix: Fixed spotbugs issue in RuntimeException cast

* test: Added tests for more complex content types mentioned in issue #315

* docs: Updated samples to support SAM CLI operations out of the box to address #293 and switched to HTTP API by default

* feat: Updated archetypes to work out of the box with the SAM CLI, continuing to address #293

* chore: License header pass on the entire project

* fix: Set default value for setDisableException mapper in config to false

* fix: Updated default initialization timeout to 20 seconds

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Eran Medan <[email protected]>
@sigpwned
Copy link
Contributor

sigpwned commented Jul 28, 2022

This just bit me and cost me an hour or two of debugging. Not the end of the world, but it would be nice to add a blurb on the TargetGroup docs to this effect, at the very least. Perhaps right after:

Before you register a Lambda function as a target, you must create a AWS::Lambda::Permission resource that grants the Elastic Load Balancing service principal permission to invoke the Lambda function.

Would the team entertain a PR on those docs?

Or, alternatively, a code PR to this project that falls back to the single-value headers if the multi-value headers are not populated?

Or both?

@deki
Copy link
Collaborator

deki commented Jul 28, 2022

Thanks for the feedback. We should definitely improve the docs.

The fallback also sounds good to me, can't think of any side-effects right now.

@sigpwned
Copy link
Contributor

From above: I've proposed the code change in #470 and the documentation change in awsdocs/aws-cloudformation-user-guide#1247.

@sigpwned
Copy link
Contributor

sigpwned commented Aug 2, 2022

Just checking in. Any thoughts, @deki?

@deki
Copy link
Collaborator

deki commented Aug 26, 2022

Sorry for the delay @sigpwned, I was on vacation and had to catch up with a lot of things afterwards. I've commented in #470.

@sigpwned
Copy link
Contributor

No problem at all, @deki. I understand busy, and I hope you enjoyed the vacation. I've responded over on #470!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants