How to return GZIP Content-Encoding
Closed this issue · 4 comments
Hi,
I am trying to return a GZIP encoded response but getting the error :
{
"errorMessage": "'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte",
"errorType": "UnicodeDecodeError",
"stackTrace": [
" File \"/var/task/lambda_handler.py\", line 75, in handler\n return awsgi.response(app, event, context)\n",
" File \"/var/task/awsgi/__init__.py\", line 22, in response\n return sr.response(output)\n",
" File \"/var/task/awsgi/__init__.py\", line 41, in response\n 'body': self.body.getvalue() + ''.join(map(convert_str, output)),\n",
" File \"/var/task/awsgi/__init__.py\", line 9, in convert_str\n return s.decode('utf-8') if isinstance(s, bytes) else s\n"
]
}
Is there any way to skip the response transformed in String ?
@fpozzobon Does this StackOverflow question help?
I've never needed to return content through this module in other encodings. I'm happy to help, but I think I'll need more information. Could you make a small complete code example that produces the error? I think it's important to see how you're calling the APIs and what data you're passing in headers and body.
Hi @slank thanks for your quick reply :)
Please find below how we zip the content, I am using the following annotation on top of the route :
def gzipped(f):
@functools.wraps(f)
def view_func(*args, **kwargs):
@after_this_request
def zipper(response):
accept_encoding = request.headers.get('Accept-Encoding', '')
if 'gzip' not in accept_encoding.lower():
return response
response.direct_passthrough = False
if (response.status_code < 200 or
response.status_code >= 300 or
'Content-Encoding' in response.headers):
return response
gzip_buffer = IO()
gzip_file = gzip.GzipFile(mode='wb',
fileobj=gzip_buffer)
gzip_file.write(response.data)
gzip_file.close()
response.data = gzip_buffer.getvalue()
response.headers['Content-Encoding'] = 'gzip'
response.headers['Vary'] = 'Accept-Encoding'
response.headers['Content-Length'] = len(response.data)
return response
return f(*args, **kwargs)
return view_func
This isn't possible with isBase64Encoded
hard-coded to False. There's a fork of this project that checks for common binary Content-Type
headers and then encodes based on that.
I don't think this will really do what you want though (i.e., send a gzipped response to the client), because lambda's have to be exposed with an ALB or API Gateway. You would have to also base64 encode the gzipped body, in addition to setting the correct Content-Type
header and specifying isBase64Encoded = True
. In the end, it might end up actually increasing your response time.
This is fixed in v0.1.0