Python 如何处理Django'中的utf-8与punycode问题;s csrf中间件?
我有一个具有非ascii字符的域,类似于使用其punycode等效项注册的域:Python 如何处理Django'中的utf-8与punycode问题;s csrf中间件?,python,django,django-csrf,punycode,Python,Django,Django Csrf,Punycode,我有一个具有非ascii字符的域,类似于使用其punycode等效项注册的域: xn--bl-zia.no Apache vhost中也设置了: <VirtualHost *:443> ServerName xn--bl-zia.no ... 也就是说,参考号以utf-8而非punycode的形式发送。我得到的例外是: Traceback (most recent call last): File "/srv/cleanup-project/venv/dev
xn--bl-zia.no
Apache vhost中也设置了:
<VirtualHost *:443>
ServerName xn--bl-zia.no
...
也就是说,参考号以utf-8而非punycode的形式发送。我得到的例外是:
Traceback (most recent call last):
File "/srv/cleanup-project/venv/dev/lib/python2.7/site-packages/django/core/handlers/base.py", line 153, in get_response
response = callback(request, **param_dict)
File "/srv/cleanup-project/venv/dev/lib/python2.7/site-packages/django/utils/decorators.py", line 87, in _wrapped_view
result = middleware.process_view(request, view_func, args, kwargs)
File "/srv/cleanup-project/venv/dev/lib/python2.7/site-packages/django/middleware/csrf.py", line 157, in process_view
reason = REASON_BAD_REFERER % (referer, good_referer)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
csrf.py
中的相关代码为:
good_referer = 'https://%s/' % request.get_host()
if not same_origin(referer, good_referer):
reason = REASON_BAD_REFERER % (referer, good_referer)
(get_host()
使用请求中的服务器名称
)
是否有一种本地Django方法来处理这个问题,或者我是否需要在referer头的域部分编写一个将utf-8转换为punycode的中间件?这里有一个中间件解决方案
import urlparse
class PunyCodeU8RefererFixerMiddleware(object):
def process_request(self, request):
servername = request.META['SERVER_NAME']
if 'xn--' not in servername:
return None
referer = request.META.get("HTTP_REFERER")
if not referer:
return None
url = urlparse.urlparse(referer)
try:
netloc = url.netloc.decode('u8')
except UnicodeDecodeError:
return None
def isascii(txt):
return all(ord(ch) < 128 for ch in txt)
netloc = '.'.join([
str(p) if isascii(p) else 'xn--' + p.encode('punycode')
for p in netloc.split('.')
])
url = url._replace(netloc=netloc)
request.META['HTTP_REFERER'] = urlparse.urlunparse(url)
return None
导入URL解析
类PunyCodeu8RefererFixerMixedWare(对象):
def过程_请求(自我,请求):
servername=request.META['SERVER\u NAME']
如果servername中没有“xn--”:
一无所获
referer=request.META.get(“HTTP\u referer”)
如果未提交:
一无所获
url=urlparse.urlparse(referer)
尝试:
netloc=url.netloc.decode('u8')
除UNICEDECODEERROR外:
一无所获
def isascii(txt):
返回全部(对于txt中的ch,ord(ch)<128)
netloc='.'。加入([
str(p)如果isascii(p)else'xn--'+p.encode('punycode'))
对于netloc.split('.')中的p
])
url=url.\u替换(netloc=netloc)
request.META['HTTP_REFERER']=urlparse.urlumprase(url)
一无所获
当它检测到它不能做任何有用的事情时,它会尽可能早地跳伞。当然,必须先安装csrf中间件
import urlparse
class PunyCodeU8RefererFixerMiddleware(object):
def process_request(self, request):
servername = request.META['SERVER_NAME']
if 'xn--' not in servername:
return None
referer = request.META.get("HTTP_REFERER")
if not referer:
return None
url = urlparse.urlparse(referer)
try:
netloc = url.netloc.decode('u8')
except UnicodeDecodeError:
return None
def isascii(txt):
return all(ord(ch) < 128 for ch in txt)
netloc = '.'.join([
str(p) if isascii(p) else 'xn--' + p.encode('punycode')
for p in netloc.split('.')
])
url = url._replace(netloc=netloc)
request.META['HTTP_REFERER'] = urlparse.urlunparse(url)
return None