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

Illegal Argument Exception when using domain name as resource identifier on the REST API #158

Closed
OnkarKadam opened this issue Jun 19, 2018 · 3 comments
Assignees
Milestone

Comments

@OnkarKadam
Copy link

  • Framework version: 1.1
  • Implementations: Spring Boot

Scenario

I am trying to implement an API which takes in a domain name as the Path parameter. When I test this API locally using SAM it works as expected but when I try to test it on AWS Lambda I get the exception I mentioned below.

Steps I followed:

  • Created the app using the maven archetype
  • Added endpoint to get information about domain name
  • Ran locally using SAM, tested using curl and it works
  • Deployed the code to AWS using SAM template
  • Created test events on the lambda function
  • Tested the Lambda function, ping works correctly
  • Tested the GET endpoint, see the exception below

This is the test event I am using for testing :

{
  "resource": "/{proxy+}",
  "path": "/v1/domains/test.com",
  "httpMethod": "GET",
  "headers": null,
  "queryStringParameters": null,
  "pathParameters": {
    "proxy": "/v1/domains/test.com"
  },
  "stageVariables": null,
    "resourcePath": "/{proxy+}",
    "httpMethod": "GET",
    "extendedRequestId": "test-invoke-extendedRequestId",
    "apiId": "038lirvukg"
  },
  "body": null,
  "isBase64Encoded": false
}

Expected behavior

The request handler should be able to map to the correct handler in the API.

Actual behavior

Request Handler fails to map to the correct method.

Steps to reproduce

  • Create a sample app using the maven archetype and add an endpoint to get domain names.
  • Test locally using SAM should work as expected
  • Test on AWS Lambda, you should see the exception

Full log output

2018-06-19 21:03:31.364 ERROR 1 --- [ main] o.s.boot.web.support.ErrorPageFilter : Forwarding to error page from request [/v1/domains/test.com] due to exception [File path not allowed: /file.com]
java.lang.IllegalArgumentException: File path not allowed: /file.com
at com.amazonaws.serverless.proxy.internal.SecurityUtils.getValidFilePath(SecurityUtils.java:192) ~[task/:na]
at com.amazonaws.serverless.proxy.internal.SecurityUtils.getValidFilePath(SecurityUtils.java:160) ~[task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.AwsServletContext.getMimeType(AwsServletContext.java:147) ~[task/:na]
at org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy.handleNoMatch(ServletPathExtensionContentNegotiationStrategy.java:72) ~[task/:na]
at org.springframework.web.accept.AbstractMappingContentNegotiationStrategy.resolveMediaTypeKey(AbstractMappingContentNegotiationStrategy.java:78) ~[task/:na]
at org.springframework.web.accept.AbstractMappingContentNegotiationStrategy.resolveMediaTypes(AbstractMappingContentNegotiationStrategy.java:61) ~[task/:na]
at org.springframework.web.accept.ContentNegotiationManager.resolveMediaTypes(ContentNegotiationManager.java:125) ~[task/:na]
at org.springframework.web.servlet.mvc.condition.ProducesRequestCondition.getAcceptedMediaTypes(ProducesRequestCondition.java:261) ~[task/:na]
at org.springframework.web.servlet.mvc.condition.ProducesRequestCondition.getMatchingCondition(ProducesRequestCondition.java:194) ~[task/:na]
at org.springframework.web.servlet.mvc.method.RequestMappingInfo.getMatchingCondition(RequestMappingInfo.java:214) ~[task/:na]
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfoHandlerMapping.java:94) ~[task/:na]
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfoHandlerMapping.java:58) ~[task/:na]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.addMatchingMappings(AbstractHandlerMethodMapping.java:380) ~[task/:na]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:347) ~[task/:na]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:314) ~[task/:na]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:61) ~[task/:na]
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:352) ~[task/:na]
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1160) ~[task/:na]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:940) ~[task/:na]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[task/:na]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[task/:na]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[task/:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[task/:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[task/:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.FilterChainManager$ServletExecutionFilter.doFilter(FilterChainManager.java:351) ~[task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:84) [task/:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[task/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:84) [task/:na]
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115) [task/:na]
at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59) [task/:na]
at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90) [task/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [task/:na]
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108) [task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.FilterChainHolder.doFilter(FilterChainHolder.java:84) [task/:na]
at com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler.doFilter(AwsLambdaServletContainerHandler.java:207) [task/:na]
at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:154) [task/:na]
at com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler.handleRequest(SpringBootLambdaContainerHandler.java:52) [task/:na]
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:168) [task/:na]
at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:200) [task/:na]
at com.godaddy.afternic.ims.StreamLambdaHandler.handleRequest(StreamLambdaHandler.java:31) [task/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_141]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_141]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_141]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_141]
at lambdainternal.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:350) [LambdaSandboxJava-1.0.jar:na]
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888) [LambdaSandboxJava-1.0.jar:na]
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:283) [LambdaSandboxJava-1.0.jar:na]
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64) [LambdaSandboxJava-1.0.jar:na]
at java.lang.Class.forName0(Native Method) [na:1.8.0_141]
at java.lang.Class.forName(Class.java:348) [na:1.8.0_141]
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:94) [LambdaJavaRTEntry-1.0.jar:na]
@sapessi
Copy link
Collaborator

sapessi commented Jun 20, 2018

Thanks for the report @OnkarKadam, I suspect this has something to do with url encoding. Perhaps SAM CLI encodes the path correctly, whereas API Gateway passes the path in the event decoded. I'll sync-up with the SAM CLI team to make sure the behavior is the same and fix the issue in the library.

Can you share your request mapping annotation on the resource?

@sapessi sapessi self-assigned this Jun 20, 2018
@sapessi sapessi added the bug label Jun 20, 2018
@sapessi sapessi added this to the Release 1.1.1 milestone Jun 20, 2018
@sapessi sapessi removed the bug label Jun 20, 2018
@sapessi
Copy link
Collaborator

sapessi commented Jun 20, 2018

Hey @OnkarKadam, figured out what the problem is. It's actually in the Spring Boot configuration and not with the framework - therefore closing this issue.

Spring Boot is treating your .com extension as if it was a file. After you have solved that initial issue, you'll run into a really annoying content negotiation issue with Spring. This blog post explains this pretty well.

Take a look at the commit attached to this issue, I've added a unit test for this use-case.

@OnkarKadam
Copy link
Author

Thanks @sapessi that worked.

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

No branches or pull requests

2 participants