awslabs / aws-lambda-go-api-proxy

lambda-go-api-proxy makes it easy to port APIs written with Go frameworks such as Gin (https://gin-gonic.github.io/gin/ ) to AWS Lambda and Amazon API Gateway.
Apache License 2.0
1.05k stars 197 forks source link

Request for overriding DefaultServerAddress #13

Closed jeroenkoknl closed 5 years ago

jeroenkoknl commented 6 years ago

The proxied http.Request URL will currently always start with https://aws-serverless-go-api.com because of the way the the URL is created here: https://github.com/awslabs/aws-lambda-go-api-proxy/blob/master/core/request.go#L137

This is an issue when API Gateway is configured to use a custom domain. For instance Gorrila MUX will redirect the client to a 'clean' version of the URL path. It makes use of the request URL to construct the redirect URL in de HTTP response: https://github.com/gorilla/mux/blob/master/mux.go#L125-L137

Could you please create the ability to override the server address? Another option would be to use the value of request.host in the API Gateway Proxy Request Event.

dave-malone commented 6 years ago

@jeroenkoknl Could you help me understand what issue this is causing in your scenario? Do you have a code example you could share?

As I see it, the handlers that use the generated http.Request simply use that to invoke ServeHTTP on the HandlerFunc in order to generate an http.Response, which is then returned to the caller of Proxy.

I've used this same method in mocking out test cases with no real impact on the HandlerFunc; as long as the response produces what we want, we should be ok.

jeroenkoknl commented 6 years ago

Hi @dave-malone, thank you for looking into this issue.

The issue is that the URL field of the generated http.Request always starts with https://aws-serverless-go-api.com regardless of the URL of the original request. This becomes a problem when the HandlerFunc uses this value to for instance generate other URLs to return in the http.Response (e.g. a HTTP 304 redirect to the same domain). The generated URL will incorrectly start with https://aws-serverless-go-api.com instead of the original request's domain.

We tried to work around this by ignoring the URL field of the http.Request but we cannot control how frameworks like Gorilla MUX use this field to generate response URLs.

I'll have a look at your test cases to see if I can point out a way to easiliy test this scenario for you.

sapessi commented 6 years ago

Hi @jeroenkoknl, @dave-malone - we have been struggling with this on our java framework too. Unfortunately, the only way to tell the original host the client contacted is to trust the X-Forwarded-For, which we should not be doing. Even then, the header would not contain the custom domain name. In the Java framework we use a configuration object to allow developers to override these values.

We have asked the API Gateway team to add the full client request url to the proxy object. until then, I would recommend using environment variables in Lambda to statically set the url the API is running on, you can populate them using a reference in the SAM template (look at the exported values in the sample)

captainbeardo commented 6 years ago

For what it's worth, this also makes the traces in X-Ray (github.com/aws/aws-xray-sdk-go/xray) all have the same host in the URL, this makes filtering the traces on hostname virtually impossible. It would be nice as a fallback to be able to specify the hostname for the proxy. In my case I have an environment variable that specifies what it should be, just don't have a way to pass it down.

sapessi commented 6 years ago

@captainbeardo that issue we could address with a similar methodology of the Java framework. I was just hoping to go for something cleaner and get the domain directly from API GW.

Perhaps using an environment variable is an acceptable solution for the time being. What do you think @jeroenkoknl?

jeroenkoknl commented 6 years ago

@SAPessi Yes, using an environment variable could work, although it doesn't help in a scenario where the same Lambda handler service multiple domains.

In that case the original host address should come from the request. We are relying on AWS API Gateway to forward this information. I was under the impression this was already done but your comment on May 15 suggest this isn't the case.

Maybe for the time being provide a way to override the DefaultServerAddress by for instance an environment variable?

sapessi commented 6 years ago

Hi @jeroenkoknl, I've checked the proxy event again and it does not contain the original request uri. I will implement the environment variable fix by the end of this week.

jeroenkoknl commented 6 years ago

Thanks @SAPessi for doing this!

kon commented 5 years ago

Any progress on this? Thanks :D

sapessi commented 5 years ago

Fix for this is now in PR #21 - let me know if the proposed changes work for you.

sapessi commented 5 years ago

Resolving since PR is merged