aws-lambda-dotnet icon indicating copy to clipboard operation
aws-lambda-dotnet copied to clipboard

Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction Doesn't replace path params when proxy+ is present

Open erlinghi opened this issue 3 years ago • 5 comments

Describe the bug

Looking at the code of Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction

      if (apiGatewayRequest.PathParameters != null && apiGatewayRequest.PathParameters.ContainsKey("proxy") && !string.IsNullOrEmpty(apiGatewayRequest.Resource))
      {
        string pathParameter = apiGatewayRequest.PathParameters["proxy"];
        str1 = apiGatewayRequest.Resource.Replace("{proxy+}", pathParameter);
      }
      if (string.IsNullOrEmpty(str1))
        str1 = apiGatewayRequest.Path;
      if (!str1.StartsWith("/"))
        str1 = "/" + str1;
      aspNetCoreRequestFeature.Path = str1;

It doesn't replace other path params if proxy+ is present

Expected Behavior

I expect path params before the proxy+ to get replaced correctly. HTTP “GET” "/site/2626/status/testEndpoint/123123/asdasdasd"

Current Behavior

You can see that if you have a resource with proxy+, it doesn't replace other path parameters in the resource. So if you have a resource like this: /site/{siteId}/{proxy+} And do a call like this HTTP “GET” "/site/2626/status/testEndpoint/123123/asdasdasd" your lambda get hit with this HTTP “GET” “/site/{siteId}/status/testEndpoint/123123/asdasdasd”

Reproduction Steps

Setup a resource in your apigateway with both path params and a greedy path param. Example /site/{siteId}/{proxy+} Then APIGatewayProxyFunction won't pass on the value you use for siteId.

Possible Solution

A fix is to replace all path params in the path, if proxy+ is present, else do like before.

You can see our current workaround in our entrypoint

public class LambdaEntryPoint : APIGatewayProxyFunction
{
    static LambdaEntryPoint()
    {
        LogConfigurator.ConfigureSerilog();
    }

    protected override void MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
    {
        UseFixForProxyReplacementBugInApiGatewayProxyFunction(apiGatewayRequest);

        base.MarshallRequest(features, apiGatewayRequest, lambdaContext);
    }

    private static void UseFixForProxyReplacementBugInApiGatewayProxyFunction(APIGatewayProxyRequest apiGatewayRequest)
    {
        if (apiGatewayRequest.PathParameters == null || !apiGatewayRequest.PathParameters.ContainsKey("proxy") || string.IsNullOrEmpty(apiGatewayRequest.Resource))
        {
            return;
        }

        foreach (var pathParameter in apiGatewayRequest.PathParameters.Where(x => x.Key != "proxy"))
        {
            apiGatewayRequest.Resource = apiGatewayRequest.Resource.Replace($"{{{pathParameter.Key}}}", pathParameter.Value);
        }
    }

Additional Information/Context

No response

AWS .NET SDK and/or Package version used

Amazon.Lambda.AspNetCoreServer 7.0.1 Briefly looked over 7.2.0, and it has the same flow for .path

Targeted .NET Platform

.NET 6

Operating System and version

AmazonLinux

erlinghi avatar Jul 04 '22 09:07 erlinghi

Hi @erlinghi,

Good afternoon.

Thanks for submitting the bug report. Would it be possible for you to share the sample code solution to reproduce the issue so that we are using the same configuration and environment?

Thanks, Ashish

ashishdhingra avatar Jul 05 '22 20:07 ashishdhingra

Hey, I made a demo project that reproduces it. https://github.com/erlinghi/demo-broken-path-params Just follow the setup and use the test tool to invoke the lambda

I also provided the workaround in LambdaEntryPoint, that you can uncomment to test.

Thanks in advance

erlinghi avatar Jul 06 '22 09:07 erlinghi

Per Use a proxy resource to streamline API setup at Set up a method request in API Gateway:

  • {proxy+} is referred to as a greedy path parameter.
  • An API can have more than one proxy resource. For example, the following proxy resources are allowed within an API.
/{proxy+}
/parent/{proxy+}
/parent/{child}/{proxy+}

ashishdhingra avatar Jul 06 '22 21:07 ashishdhingra

Per Use a proxy resource to streamline API setup at Set up a method request in API Gateway:

  • {proxy+} is referred to as a greedy path parameter.
  • An API can have more than one proxy resource. For example, the following proxy resources are allowed within an API.
/{proxy+}
/parent/{proxy+}
/parent/{child}/{proxy+}

Yes, exactly. The last scenario (/parent/{child}/{proxy+}) is what this bug concerns. The two other scenarios work fine. Combining a non-greedy and a greedy path parameter does not work as expected, as stated in the original bug description

henningc avatar Jul 07 '22 09:07 henningc

Reproducible using customer provided code and scenario.

ashishdhingra avatar Jul 11 '22 22:07 ashishdhingra

The PR with this change has been released as part of version 8.0.0 of Amazon.Lambda.AspNetCoreServer. This was a major version bump to PR #899 shipped in this release which is a slight breaking change.

normj avatar Feb 13 '23 07:02 normj

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

github-actions[bot] avatar Feb 13 '23 07:02 github-actions[bot]