Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

[New requirement] Solution to make awsgi working with Http Api that invoke Lambda functions #67

Closed
malekadrar opened this issue Sep 11, 2021 · 0 comments

Comments

@malekadrar
Copy link

malekadrar commented Sep 11, 2021

Hello,

This package works fine when I create Rest API for the Lambda function by using Amazon API Gateway or AWS SAM, but not with Http API type . It is very easy to notice this gap. To do this, just create an API that invoke the Lambda function with HTTP API type instead of REST API type.

The reason that make this package not working with HTTP API type is that HTTP APIs are newer and are built with the API Gateway version 2 API. So, the event json structure is different than the previous one. By the way, the http Method and the path are specified by the following paths:

  • requestContext.http.method instead of httpMethod
  • requestContext.http.path instead of path

For more details, please look into the following link (paragraph: Choosing an API type)
Using AWS Lambda with Amazon API Gateway

To deal with that, I think we have no choice, we should modify the function def environ (event, context) a bit. And here are my retrocompatible modifications:

def environ(event, context):
    body = event.get('body', '') or ''

    if event.get('isBase64Encoded', False):
        body = b64decode(body)
    # FIXME: Flag the encoding in the headers
    body = convert_byte(body)

    httpMethod = ''
    path = ''
    if 'httpMethod' in event and 'path' in event:
        httpMethod =  event['httpMethod']
        path =  event['path']
    elif 'http' in event['requestContext']:
        if 'method' in event['requestContext']['http']:
            httpMethod =  event['requestContext']['http']['method']
        if 'path' in event['requestContext']['http']:
            path =  event['requestContext']['http']['path']

    queryStringParameters = ''
    if 'queryStringParameters' in event and event['queryStringParameters'] is not None:
        queryStringParameters = urlencode(event['queryStringParameters'])
    
    environ = {
        'REQUEST_METHOD': httpMethod,
        'SCRIPT_NAME': '',
        'SERVER_NAME': '',
        'SERVER_PORT': '',
        'PATH_INFO': path ,
        'QUERY_STRING':queryStringParameters,
        'REMOTE_ADDR': '127.0.0.1',
        'CONTENT_LENGTH': str(len(body)),
        'HTTP': 'on',
        'SERVER_PROTOCOL': 'HTTP/1.1',
        'wsgi.version': (1, 0),
        'wsgi.input': BytesIO(body),
        'wsgi.errors': sys.stderr,
        'wsgi.multithread': False,
        'wsgi.multiprocess': False,
        'wsgi.run_once': False,
        'wsgi.url_scheme': '',
        'awsgi.event': event,
        'awsgi.context': context,
    }
    headers = event.get('headers', {}) or {}
    for k, v in headers.items():
        k = k.upper().replace('-', '_')

        if k == 'CONTENT_TYPE':
            environ['CONTENT_TYPE'] = v
        elif k == 'HOST':
            environ['SERVER_NAME'] = v
        elif k == 'X_FORWARDED_FOR':
            environ['REMOTE_ADDR'] = v.split(', ')[0]
        elif k == 'X_FORWARDED_PROTO':
            environ['wsgi.url_scheme'] = v
        elif k == 'X_FORWARDED_PORT':
            environ['SERVER_PORT'] = v

        environ['HTTP_' + k] = v

    return environ

Of course I've tested (locally with aws sam and in AWS console after deployment) that this code enhancement is working properly.

Best regards,

@malekadrar malekadrar changed the title [New requirement] Make awsgi working with Http Api that invoke Lambda functions [New requirement] Solution to make awsgi working with Http Api that invoke Lambda functions Sep 11, 2021
@slank slank closed this as completed Mar 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants