How do I convert a unicode header to byte string i

2019-05-11 00:57发布

I have a flask app that I've been able to get running on my development server. However, when I try to run the same app under mod_wsgi I get an error:

TypeError: expected byte string object for header name, value of type unicode found

I've tried to convert the headers many different ways but I'm getting the same error:

for k,v in dict(request.headers).iteritems():
    response.headers[k.encode('latin-1')] = v.encode('latin-1')

I've also tried the following but get the same exact error:

.encode('utf-8'), decode('utf-8'), decode('latin-1'), str()

Am I doing something wrong?

EDIT (the real stacktrace...I think):

[Wed Mar 12 23:26:49 2014] [notice] Apache/2.2.25 (Unix) mod_wsgi/3.4 Python/2.7.5 configured -- resuming normal operations
[Wed Mar 12 23:26:49 2014] [info] Server built: Sep  9 2013 06:59:27
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:51 2014] [info] mod_wsgi (pid=524833): Create interpreter 'web23.webfaction.com|'.
[Wed Mar 12 23:26:51 2014] [info] mod_wsgi (pid=524833): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:51 2014] [info] [client 127.0.0.1] mod_wsgi (pid=524833, process='api', application='web23.webfaction.com|'): Loading WSGI script '/path/to/api/wsgi.py'.
[Wed Mar 12 23:26:52 2014] [error] [client 127.0.0.1] mod_wsgi (pid=524833): Exception occurred processing WSGI script '/path/to/api/wsgi.py'.
[Wed Mar 12 23:26:52 2014] [error] [client 127.0.0.1] TypeError: expected byte string object for header name, value of type unicode found

EDIT #2: Here's the view in Flask where I'm trying to get a token and how I'm modifying the headers (or, at least, trying to):

@app.route('/oauth/token/', methods=['GET','POST'],subdomain='api')
@oauth.token_handler # e.g. the decorator for OAuthlib/OAuthlib-Flask
def access_token():
  return None

@app.after_request
def after(response):
  import urllib
  for k,v in dict(request.headers).iteritems():
    response.headers[urllib.quote(k)] = urllib.quote(v)

  return response

EDIT #3 ( output from "print dict(request.headers).items()" ):

[('Forwarded-Request-Uri', u'/oauth/token?client_secret=rDRzy2Qgt627dZK6eFtnylluOad7PRuLNUBothIpb0KQWJmOBl&grant_type=client_credentials&client_id=lryd8PqzlSObOQNUUEgEjqKYIeCnnkifs1s16NZ1'), ('Accept-Encoding', u'gzip, deflate, compress'), ('X-Forwarded-Host', u'api.example.com'), ('X-Forwarded-For', u'917.85.235.27'), ('Http-X-Forwarded-Proto', u'https'), ('Host', u'api.example.com'), ('Accept', u'*/*'), ('User-Agent', u'python-requests/2.2.1 CPython/2.7.5+ Linux/3.11.0-12-generic'), ('Connection', u'close'), ('X-Forwarded-Proto', u'https'), ('Https', u'on'), ('X-Forwarded-Server', u'api.example.com'), ('X-Forwarded-Ssl', u'on')]

2条回答
男人必须洒脱
2楼-- · 2019-05-11 01:13

how bout

bytes(whatever_unicode.encode("utf-8"))

or per J.F. Sebastians comment

some_unicode.encode("ISO-8859-1")

or perhaps

import urllib
urllib.quote(unicode_string)

one of those should work ... I think

查看更多
Luminary・发光体
3楼-- · 2019-05-11 01:26

I got stuck on this for a long time. I am not at all satisfied with the selected answer. Here's what I have working in production

@app.after_request
def after(response):
    new_resp_headers = {}
    for k, v in response.headers.items():
        new_resp_headers[k.encode('ISO-8859-1')] = v.encode('ISO-8859-1')
    response.headers = new_resp_headers
    return response
查看更多
登录 后发表回答