使用S3 generate_url的KeyError u'\ xae'

时间:2015-02-18 10:21:59

标签: python boto

我想为S3对象生成一个签名的URL,其下载文件名包含®,但它会引发错误:

    content_disposition = u'attachment; filename={}'.format(upload.filename)
    url = conn.generate_url(
        EXPIRES_IN,
        'GET',
        S3_PROTECTED_BUCKET_NAME,
        upload.file_key,
        response_headers = {
            'response-content-type': content_type,
            'response-content-disposition': content_disposition
        })

违规字符串repr是:

u'attachment; filename=Rita-PMP\xae Exam Prep 8th Edition - Rita Mulcahy.png'

print很好用®。

它会抛出以下错误:

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/home/likewise-open/SUYATITECH/jjvattamattom/dev/force4change/projectapp/views.py" in show
  203.         attachment.file_key = signed_download_url(attachment)
File "/home/likewise-open/SUYATITECH/jjvattamattom/dev/force4change/baseapp/uploads.py" in signed_download_url
  69.             'response-content-disposition': content_disposition
File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py" in generate_url
  399.                 extra_qp.append("%s=%s" % (k, urllib.parse.quote(v)))
File "/usr/lib/python2.7/urllib.py" in quote
  1288.     return ''.join(map(quoter, s))

Exception Type: KeyError at /projects/show/50
Exception Value: u'\xae'

当符号容易为ASCII时,为什么会抛出此错误?


更新:传递编码的字节字符串也不起作用:

content_disposition = 'attachment; filename={}'.format(upload.filename.encode('utf-8'))

给了我:

Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/home/likewise-open/SUYATITECH/jjvattamattom/dev/force4change/projectapp/views.py" in show
  203.         attachment.file_key = signed_download_url(attachment)
File "/home/likewise-open/SUYATITECH/jjvattamattom/dev/force4change/baseapp/uploads.py" in signed_download_url
  69.             'response-content-disposition': content_disposition
File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py" in generate_url
  407.         b64_hmac = self._auth_handler.sign_string(c_string)
File "/usr/local/lib/python2.7/dist-packages/boto/auth.py" in sign_string
  91.         new_hmac.update(string_to_sign.encode('utf-8'))

Exception Type: UnicodeDecodeError at /projects/show/50
Exception Value: 'ascii' codec can't decode byte 0xc2 in position 130: ordinal not in range(128)

1 个答案:

答案 0 :(得分:1)

在将content-disposition标头传递给generate_url之前,您应对其进行编码(urllib无法使用unicode):

>>> content_disposition = u'attachment filename=Rita-PMP\xae Exam Prep 8th Edition - Rita Mulcahy.png'
>>> urllib.quote(content_disposition)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/urllib.py", line 1288, in quote
    return ''.join(map(quoter, s))
KeyError: u'\xae'
>>> urllib.quote(content_disposition.encode('utf-8'))
'attachment%20filename%3DRita-PMP%C2%AE%20Exam%20Prep%208th%20Edition%20-%20Rita%20Mulcahy.png'