diff --git a/packages/python/test/fixtures/32-fail-duplicate-header/index.py b/packages/python/test/fixtures/32-fail-duplicate-header/index.py new file mode 100644 index 000000000..cd35dbf74 --- /dev/null +++ b/packages/python/test/fixtures/32-fail-duplicate-header/index.py @@ -0,0 +1,14 @@ +async def app(scope, receive, send): + assert scope["type"] == "http" + await send( + { + "type": "http.response.start", + "status": 200, + } + ) + await send( + { + "type": "http.response.body", + "body": b"hello world" + } + ) diff --git a/packages/python/test/fixtures/32-fail-duplicate-header/probe.js b/packages/python/test/fixtures/32-fail-duplicate-header/probe.js new file mode 100644 index 000000000..42288f664 --- /dev/null +++ b/packages/python/test/fixtures/32-fail-duplicate-header/probe.js @@ -0,0 +1,18 @@ +const execa = require('execa'); + +module.exports = async function ({ deploymentUrl, fetch }) { + const probeUrl = `https://${deploymentUrl}`; + const result = await execa('curl', [ + probeUrl, + '-s', + '-H', + 'foo: bar', + '-H', + 'foo: bar', + ]); + if (result.stdout.includes('FUNCTION_INVOCATION_FAILED')) { + throw new Error( + 'Duplicate headers should not cause a function invocation failure' + ); + } +}; diff --git a/packages/python/test/fixtures/32-fail-duplicate-header/vercel.json b/packages/python/test/fixtures/32-fail-duplicate-header/vercel.json new file mode 100644 index 000000000..af212f2da --- /dev/null +++ b/packages/python/test/fixtures/32-fail-duplicate-header/vercel.json @@ -0,0 +1,9 @@ +{ + "version": 2, + "builds": [ + { + "src": "*.py", + "use": "@vercel/python" + } + ] +} diff --git a/packages/python/vc_init.py b/packages/python/vc_init.py index 5e7310c32..2f56d30af 100644 --- a/packages/python/vc_init.py +++ b/packages/python/vc_init.py @@ -276,6 +276,14 @@ elif 'app' in __vc_variables: query = url.query.encode() path = url.path + headers_encoded = [] + for k, v in headers.items(): + # Cope with repeated headers in the encoding. + if isinstance(v, list): + headers_encoded.append([k.lower().encode(), [i.encode() for i in v]]) + else: + headers_encoded.append([k.lower().encode(), v.encode()]) + scope = { 'server': (headers.get('host', 'lambda'), headers.get('x-forwarded-port', 80)), 'client': (headers.get( @@ -285,7 +293,7 @@ elif 'app' in __vc_variables: 'scheme': headers.get('x-forwarded-proto', 'http'), 'root_path': '', 'query_string': query, - 'headers': [[k.lower().encode(), v.encode()] for k, v in headers.items()], + 'headers': headers_encoded, 'type': 'http', 'http_version': '1.1', 'method': payload['method'],