prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Set_Cookie option sets duplicate cookies on AWS Lambda
  ## Context
  I have an API running Python3.7 and Zappa (in a virtualenv).
  I am setting 6 cookies by using the option "set_cookie" in flask. It looks something like this:
  ```
  resp = make_response(jsonify({'success':'true', 'message': 'Successfully authenticated!'}), 200)
  resp.set_cookie("1", value="1", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  resp.set_cookie("2", value="2", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  resp.set_cookie("3", value="3", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  resp.set_cookie("4", value="4", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  resp.set_cookie("5", value="5", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  resp.set_cookie("6", value="6", secure=True, samesite='Lax', domain=".example.com",max_age=3600)
  return resp
  ```
  
  On localhost testing Flask, this works as expected.
  
  If I deploy the same code to AWS using Zappa, the response header will show 36 "set-cookie" headers. So the formula here is n^2. So if I add 4 cookies using the above method, it will show 16 in the request header.
  
  The browser takes care of duplicate cookies, but the response from the API is still huge because of this issue.
  
  Same thing happens if I use: 
  `resp.headers.add("set-cookie""1"="1; Domain=.example.com; Max-Age=3600; Secure; Path=/; SameSite=Lax")`
  
  ## Expected Behavior
  I believe Zappa or something at AWS is at fault here. Expected behaviour is to send 6 "set-cookie" headers and not 36.
  
  ## Actual Behavior
  Sets n^2 cookies as response.
  
  ## Steps to Reproduce
  Deploy a Flask route using Zappa which sets the cookies. Use the code above.
  
  ## Your Environment
  * Zappa version used: 0.48.2
  * Operating System and Python version: Ubuntu 18.04, Python3.7
  * The output of `pip freeze`: https://pastebin.com/d4QTaTuG
  * Your `zappa_settings.py`: https://pastebin.com/d1GK8sbe
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `zappa/middleware.py`
  Content:
  ```
  1 from werkzeug.wsgi import ClosingIterator
  2 
  3 
  4 def all_casings(input_string):
  5     """
  6     Permute all casings of a given string.
  7 
  8     A pretty algorithm, via @Amber
  9     http://stackoverflow.com/questions/6792803/finding-all-possible-case-permutations-in-python
  10     """
  11     if not input_string:
  12         yield ""
  13     else:
  14         first = input_string[:1]
  15         if first.lower() == first.upper():
  16             for sub_casing in all_casings(input_string[1:]):
  17                 yield first + sub_casing
  18         else:
  19             for sub_casing in all_casings(input_string[1:]):
  20                 yield first.lower() + sub_casing
  21                 yield first.upper() + sub_casing
  22 
  23 
  24 class ZappaWSGIMiddleware(object):
  25     """
  26     Middleware functions necessary for a Zappa deployment.
  27 
  28     Most hacks have now been remove except for Set-Cookie permutation.
  29     """
  30     def __init__(self, application):
  31         self.application = application
  32 
  33     def __call__(self, environ, start_response):
  34         """
  35         We must case-mangle the Set-Cookie header name or AWS will use only a
  36         single one of these headers.
  37         """
  38 
  39         def encode_response(status, headers, exc_info=None):
  40             """
  41             Create an APIGW-acceptable version of our cookies.
  42 
  43             We have to use a bizarre hack that turns multiple Set-Cookie headers into
  44             their case-permutated format, ex:
  45 
  46             Set-cookie:
  47             sEt-cookie:
  48             seT-cookie:
  49 
  50             To get around an API Gateway limitation.
  51 
  52             This is weird, but better than our previous hack of creating a Base58-encoded
  53             supercookie.
  54             """
  55 
  56             # All the non-cookie headers should be sent unharmed.
  57             
  58             # The main app can send 'set-cookie' headers in any casing
  59             # Related: https://github.com/Miserlou/Zappa/issues/990
  60             new_headers = [header for header in headers
  61                            if ((type(header[0]) != str) or (header[0].lower() != 'set-cookie'))]
  62             cookie_headers = [header for header in headers 
  63                               if ((type(header[0]) == str) and (header[0].lower() == "set-cookie"))]
  64             for header, new_name in zip(cookie_headers,
  65                                         all_casings("Set-Cookie")):
  66                 new_headers.append((new_name, header[1]))
  67             return start_response(status, new_headers, exc_info)
  68 
  69         # Call the application with our modifier
  70         response = self.application(environ, encode_response)
  71 
  72         # Return the response as a WSGI-safe iterator
  73         return ClosingIterator(response)
  74
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/zappa/middleware.py b/zappa/middleware.py
  --- a/zappa/middleware.py
  +++ b/zappa/middleware.py
  @@ -38,32 +38,17 @@
   
           def encode_response(status, headers, exc_info=None):
               """
  -            Create an APIGW-acceptable version of our cookies.
  -
  -            We have to use a bizarre hack that turns multiple Set-Cookie headers into
  -            their case-permutated format, ex:
  -
  -            Set-cookie:
  -            sEt-cookie:
  -            seT-cookie:
  -
  -            To get around an API Gateway limitation.
  -
  -            This is weird, but better than our previous hack of creating a Base58-encoded
  -            supercookie.
  +            This makes the 'set-cookie' headers name lowercase,
  +            all the non-cookie headers should be sent unharmed.
  +            Related: https://github.com/Miserlou/Zappa/issues/1965
               """
   
  -            # All the non-cookie headers should be sent unharmed.
  -            
  -            # The main app can send 'set-cookie' headers in any casing
  -            # Related: https://github.com/Miserlou/Zappa/issues/990
               new_headers = [header for header in headers
                              if ((type(header[0]) != str) or (header[0].lower() != 'set-cookie'))]
  -            cookie_headers = [header for header in headers 
  +            cookie_headers = [(header[0].lower(), header[1]) for header in headers
                                 if ((type(header[0]) == str) and (header[0].lower() == "set-cookie"))]
  -            for header, new_name in zip(cookie_headers,
  -                                        all_casings("Set-Cookie")):
  -                new_headers.append((new_name, header[1]))
  +            new_headers = new_headers + cookie_headers
  +
               return start_response(status, new_headers, exc_info)
   
           # Call the application with our modifier
  
verification_info: {"golden_diff": "diff --git a/zappa/middleware.py b/zappa/middleware.py\n--- a/zappa/middleware.py\n+++ b/zappa/middleware.py\n@@ -38,32 +38,17 @@\n \n         def encode_response(status, headers, exc_info=None):\n             \"\"\"\n-            Create an APIGW-acceptable version of our cookies.\n-\n-            We have to use a bizarre hack that turns multiple Set-Cookie headers into\n-            their case-permutated format, ex:\n-\n-            Set-cookie:\n-            sEt-cookie:\n-            seT-cookie:\n-\n-            To get around an API Gateway limitation.\n-\n-            This is weird, but better than our previous hack of creating a Base58-encoded\n-            supercookie.\n+            This makes the 'set-cookie' headers name lowercase,\n+            all the non-cookie headers should be sent unharmed.\n+            Related: https://github.com/Miserlou/Zappa/issues/1965\n             \"\"\"\n \n-            # All the non-cookie headers should be sent unharmed.\n-            \n-            # The main app can send 'set-cookie' headers in any casing\n-            # Related: https://github.com/Miserlou/Zappa/issues/990\n             new_headers = [header for header in headers\n                            if ((type(header[0]) != str) or (header[0].lower() != 'set-cookie'))]\n-            cookie_headers = [header for header in headers \n+            cookie_headers = [(header[0].lower(), header[1]) for header in headers\n                               if ((type(header[0]) == str) and (header[0].lower() == \"set-cookie\"))]\n-            for header, new_name in zip(cookie_headers,\n-                                        all_casings(\"Set-Cookie\")):\n-                new_headers.append((new_name, header[1]))\n+            new_headers = new_headers + cookie_headers\n+\n             return start_response(status, new_headers, exc_info)\n \n         # Call the application with our modifier\n", "issue": "Set_Cookie option sets duplicate cookies on AWS Lambda\n## Context\r\nI have an API running Python3.7 and Zappa (in a virtualenv).\r\nI am setting 6 cookies by using the option \"set_cookie\" in flask. It looks something like this:\r\n```\r\nresp = make_response(jsonify({'success':'true', 'message': 'Successfully authenticated!'}), 200)\r\nresp.set_cookie(\"1\", value=\"1\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nresp.set_cookie(\"2\", value=\"2\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nresp.set_cookie(\"3\", value=\"3\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nresp.set_cookie(\"4\", value=\"4\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nresp.set_cookie(\"5\", value=\"5\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nresp.set_cookie(\"6\", value=\"6\", secure=True, samesite='Lax', domain=\".example.com\",max_age=3600)\r\nreturn resp\r\n```\r\n\r\nOn localhost testing Flask, this works as expected.\r\n\r\nIf I deploy the same code to AWS using Zappa, the response header will show 36 \"set-cookie\" headers. So the formula here is n^2. So if I add 4 cookies using the above method, it will show 16 in the request header.\r\n\r\nThe browser takes care of duplicate cookies, but the response from the API is still huge because of this issue.\r\n\r\nSame thing happens if I use: \r\n`resp.headers.add(\"set-cookie\"\"1\"=\"1; Domain=.example.com; Max-Age=3600; Secure; Path=/; SameSite=Lax\")`\r\n\r\n## Expected Behavior\r\nI believe Zappa or something at AWS is at fault here. Expected behaviour is to send 6 \"set-cookie\" headers and not 36.\r\n\r\n## Actual Behavior\r\nSets n^2 cookies as response.\r\n\r\n## Steps to Reproduce\r\nDeploy a Flask route using Zappa which sets the cookies. Use the code above.\r\n\r\n## Your Environment\r\n* Zappa version used: 0.48.2\r\n* Operating System and Python version: Ubuntu 18.04, Python3.7\r\n* The output of `pip freeze`: https://pastebin.com/d4QTaTuG\r\n* Your `zappa_settings.py`: https://pastebin.com/d1GK8sbe\n", "before_files": [{"content": "from werkzeug.wsgi import ClosingIterator\n\n\ndef all_casings(input_string):\n    \"\"\"\n    Permute all casings of a given string.\n\n    A pretty algorithm, via @Amber\n    http://stackoverflow.com/questions/6792803/finding-all-possible-case-permutations-in-python\n    \"\"\"\n    if not input_string:\n        yield \"\"\n    else:\n        first = input_string[:1]\n        if first.lower() == first.upper():\n            for sub_casing in all_casings(input_string[1:]):\n                yield first + sub_casing\n        else:\n            for sub_casing in all_casings(input_string[1:]):\n                yield first.lower() + sub_casing\n                yield first.upper() + sub_casing\n\n\nclass ZappaWSGIMiddleware(object):\n    \"\"\"\n    Middleware functions necessary for a Zappa deployment.\n\n    Most hacks have now been remove except for Set-Cookie permutation.\n    \"\"\"\n    def __init__(self, application):\n        self.application = application\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        We must case-mangle the Set-Cookie header name or AWS will use only a\n        single one of these headers.\n        \"\"\"\n\n        def encode_response(status, headers, exc_info=None):\n            \"\"\"\n            Create an APIGW-acceptable version of our cookies.\n\n            We have to use a bizarre hack that turns multiple Set-Cookie headers into\n            their case-permutated format, ex:\n\n            Set-cookie:\n            sEt-cookie:\n            seT-cookie:\n\n            To get around an API Gateway limitation.\n\n            This is weird, but better than our previous hack of creating a Base58-encoded\n            supercookie.\n            \"\"\"\n\n            # All the non-cookie headers should be sent unharmed.\n            \n            # The main app can send 'set-cookie' headers in any casing\n            # Related: https://github.com/Miserlou/Zappa/issues/990\n            new_headers = [header for header in headers\n                           if ((type(header[0]) != str) or (header[0].lower() != 'set-cookie'))]\n            cookie_headers = [header for header in headers \n                              if ((type(header[0]) == str) and (header[0].lower() == \"set-cookie\"))]\n            for header, new_name in zip(cookie_headers,\n                                        all_casings(\"Set-Cookie\")):\n                new_headers.append((new_name, header[1]))\n            return start_response(status, new_headers, exc_info)\n\n        # Call the application with our modifier\n        response = self.application(environ, encode_response)\n\n        # Return the response as a WSGI-safe iterator\n        return ClosingIterator(response)\n", "path": "zappa/middleware.py"}], "after_files": [{"content": "from werkzeug.wsgi import ClosingIterator\n\n\ndef all_casings(input_string):\n    \"\"\"\n    Permute all casings of a given string.\n\n    A pretty algorithm, via @Amber\n    http://stackoverflow.com/questions/6792803/finding-all-possible-case-permutations-in-python\n    \"\"\"\n    if not input_string:\n        yield \"\"\n    else:\n        first = input_string[:1]\n        if first.lower() == first.upper():\n            for sub_casing in all_casings(input_string[1:]):\n                yield first + sub_casing\n        else:\n            for sub_casing in all_casings(input_string[1:]):\n                yield first.lower() + sub_casing\n                yield first.upper() + sub_casing\n\n\nclass ZappaWSGIMiddleware(object):\n    \"\"\"\n    Middleware functions necessary for a Zappa deployment.\n\n    Most hacks have now been remove except for Set-Cookie permutation.\n    \"\"\"\n    def __init__(self, application):\n        self.application = application\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        We must case-mangle the Set-Cookie header name or AWS will use only a\n        single one of these headers.\n        \"\"\"\n\n        def encode_response(status, headers, exc_info=None):\n            \"\"\"\n            This makes the 'set-cookie' headers name lowercase,\n            all the non-cookie headers should be sent unharmed.\n            Related: https://github.com/Miserlou/Zappa/issues/1965\n            \"\"\"\n\n            new_headers = [header for header in headers\n                           if ((type(header[0]) != str) or (header[0].lower() != 'set-cookie'))]\n            cookie_headers = [(header[0].lower(), header[1]) for header in headers\n                              if ((type(header[0]) == str) and (header[0].lower() == \"set-cookie\"))]\n            new_headers = new_headers + cookie_headers\n\n            return start_response(status, new_headers, exc_info)\n\n        # Call the application with our modifier\n        response = self.application(environ, encode_response)\n\n        # Return the response as a WSGI-safe iterator\n        return ClosingIterator(response)\n", "path": "zappa/middleware.py"}]}