Python瓶子。使用app.mount()时,UTF8路径字符串无效。[英] Python bottle: UTF8 path string invalid when using app.mount()

本文是小编为大家收集整理的关于Python瓶子。使用app.mount()时,UTF8路径字符串无效。的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

尝试在URL路径中使用特殊字符时使用app.mount:

http://127.0.0.1:8080/test/äöü

导致:

Error: 400 Bad Request
Invalid path string. Expected UTF-8

test.py:

#!/usr/bin/python
import bottle
import testapp
bottle.debug(True)
app = bottle.Bottle()
app.mount('/test',testapp.app)
app.run(reloader=True, host='0.0.0.0', port=8080)
run(host="localhost",port=8080)

testapp.py:

import bottle
app = bottle.Bottle()
@app.route("/:category", method=["GET","POST"])
def admin(category):
    try:
        return category
    except Exception(e):
        print ("e:"+str(e))

当不使用app.mount时,同一代码可以很好地工作:

test_working.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import bottle
import testapp
bottle.debug(True)
app = bottle.Bottle()
@app.route("/test/:category", method=["GET","POST"])
def admin(category):
    try:
        return category
    except Exception(e):
        print ("e:"+str(e))
app.run(reloader=True, host='0.0.0.0', port=8080)
run(host="localhost",port=8080)

这看起来像一个错误,还是我在这里错过了一些东西? :/

推荐答案

是的,因为这似乎是瓶中的错误.

问题在

def _handle(self, environ):
    path = environ['bottle.raw_path'] = environ['PATH_INFO']
    if py3k:
        try:
            environ['PATH_INFO'] = path.encode('latin1').decode('utf8')
        except UnicodeError:
            return HTTPError(400, 'Invalid path string. Expected UTF-8')

there environ['PATH_INFO']转换为UTF8,因此,当再次调用同一方法为已安装的应用程序调用时,内容将已经是UTF8,因此转换将失败.

一个非常快的修复方法是更改​​该代码以跳过转换,如果已经完成:

def _handle(self, environ):
    converted = 'bottle.raw_path' in environ
    path = environ['bottle.raw_path'] = environ['PATH_INFO']
    if py3k and not converted:
        try:
            environ['PATH_INFO'] = path.encode('latin1').decode('utf8')
        except UnicodeError:
            return HTTPError(400, 'Invalid path string. Expected UTF-8')

,最好针对瓶子提交错误报告.

本文地址:https://www.itbaoku.cn/post/1975368.html

问题描述

Trying to use special chars in an URL path fails when using app.mount:

http://127.0.0.1:8080/test/äöü

results in:

Error: 400 Bad Request
Invalid path string. Expected UTF-8

test.py:

#!/usr/bin/python
import bottle
import testapp
bottle.debug(True)
app = bottle.Bottle()
app.mount('/test',testapp.app)
app.run(reloader=True, host='0.0.0.0', port=8080)
run(host="localhost",port=8080)

testapp.py:

import bottle
app = bottle.Bottle()
@app.route("/:category", method=["GET","POST"])
def admin(category):
    try:
        return category
    except Exception(e):
        print ("e:"+str(e))

Where as the same code works well when not using app.mount:

test_working.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import bottle
import testapp
bottle.debug(True)
app = bottle.Bottle()
@app.route("/test/:category", method=["GET","POST"])
def admin(category):
    try:
        return category
    except Exception(e):
        print ("e:"+str(e))
app.run(reloader=True, host='0.0.0.0', port=8080)
run(host="localhost",port=8080)

This looks like a bug or am I missing something here? :/

推荐答案

Yes, as it seems this is a bug in bottle.

The problem is in the _handle method:

def _handle(self, environ):
    path = environ['bottle.raw_path'] = environ['PATH_INFO']
    if py3k:
        try:
            environ['PATH_INFO'] = path.encode('latin1').decode('utf8')
        except UnicodeError:
            return HTTPError(400, 'Invalid path string. Expected UTF-8')

Here environ['PATH_INFO'] is converted to utf8, so when the same method is called again for the mounted app, the contents will already be utf8, therefore the conversion will fail.

A very quick fix would be to change that code to skip the conversion if it was already done:

def _handle(self, environ):
    converted = 'bottle.raw_path' in environ
    path = environ['bottle.raw_path'] = environ['PATH_INFO']
    if py3k and not converted:
        try:
            environ['PATH_INFO'] = path.encode('latin1').decode('utf8')
        except UnicodeError:
            return HTTPError(400, 'Invalid path string. Expected UTF-8')

And it would probably be good to file a bug report against bottle.