首页 > 解决方案 > 请求/响应标头 Python Eve 中的神秘空格字符

问题描述

我将请求/响应放在标题中的原因是因为我不确定请求或响应是否有问题。

我使用基于 Python 框架 Flask 的框架 Eve 在 Python 中创建了一个小的 RESTful API。API 需要使用 mod_wsgi 部署在 apache 网络服务器上。

部署 API 后,按照这篇文章https://flask.palletsprojects.com/en/1.1.x/deploying/mod_wsgi/,我可以GET通过 Postman 成功发出请求,但不幸的是,POST请求给了我一个500错误。

处理 app.wsgi 脚本时发生异常

mod_wsgi (pid=11774): Exception occurred processing WSGI script '/var/www/example.com/app.wsgi'.
Traceback (most recent call last):
  File "/home/user/env/lib/python3.6/site-packages/eve/flaskapp.py", line 1106, in __call__
    return super(Eve, self).__call__(environ, start_response)
  File "/home/user/env/lib/python3.6/site-packages/flask/app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/user/env/lib/python3.6/site-packages/flask/app.py", line 2453, in wsgi_app
    return response(environ, start_response)
  File "/home/user/env/lib/python3.6/site-packages/werkzeug/wrappers/base_response.py", line 701, in __call__
    start_response(status, headers)
ValueError: space character present in header name

异常表示标题名称中不允许有空格字符。但我不明白空格字符的来源。我尝试通过 cURL 创建一个请求,因为我认为 Postman 在标题中创建了这些空格字符,但遗憾的是没有运气,它给出了相同的异常:

卷曲代码示例

curl -d '[{"username":"test","password":"secret","roles":["admin"]}]' -H 'Content-Type:application/json'  https://example.com/accounts

在查看错误时,它表明问题发生在创建响应时,因此可能是框架内部的错误,但我不确定。我搜索了任何类似的问题,但找不到任何问题。我希望有人可以帮助我更进一步或给我正确的方向。

下面是一些代码示例,例如我为 apache 创建的配置文件、app.wsgi 文件和 Eve 的 settings.py。

阿帕奇配置文件

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName example.com

    WSGIDaemonProcess app threads=5 python-home=/home/user/env
    WSGIScriptAlias / /var/www/example.com/app.wsgi

    <Directory /var/www/example.com>
        WSGIProcessGroup app
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>

    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

app.wsgi 文件

activate_this = '/home/user/env/bin/activate_this.py'
with open(activate_this) as file_:
    exec(file_.read(), dict(__file__=activate_this))

import sys
sys.path.insert(0, "/var/www/example.com/")
from app import app as application

settings.py 文件

settings = {
    'DEBUG': True,
    'SOFT_DELETE': SOFT_DELETE,

    'MONGO_HOST': os.getenv('MONGO_HOST'),
    'MONGO_PORT': int((os.getenv('MONGO_PORT'))),
    'MONGO_USERNAME': os.getenv('MONGO_USER'),
    'MONGO_PASSWORD': os.getenv('MONGO_PASS'),
    'MONGO_AUTH_SOURCE': os.getenv('MONGO_AUTH_SOURCE'),
    'MONGO_DBNAME': os.getenv('MONGO_DBNAME'),

    # Enable reads (GET), inserts (POST) and DELETE for resources/collections
    'RESOURCE_METHODS': ['GET', 'POST', 'DELETE'],

    # Enable reads (GET), edits (PATCH), replacements (PUT) and deletes of
    # individual items
    'ITEM_METHODS': ['GET', 'PATCH', 'PUT', 'DELETE'],

    'PUBLIC_METHODS': ['GET'],
    'PUBLIC_ITEM_METHODS': ['GET'],

    'AUTH_FIELD': 'user_id',

    'JWT_SECRET': os.getenv('SECRET'),
    'JWT_ISSUER': os.getenv('APP_URL') + '/token',
    'JWT_ROLES_CLAIM': 'roles',

    'DOMAIN': DOMAIN,
}

名为 accounts.py 的域文件示例

schema = {
    'username': {
        'type': 'string',
        'required': True,
        'unique': True,
        },
    'password': {
        'type': 'string',
        'required': True,
    },
    'roles': {
        'type': 'list',
        'allowed': ['user', 'admin'],
        'required': True,
    },
}

accounts = {
    'additional_lookup': {
        'url': 'regex("[\w]+")',
        'field': 'username',
    },
    'cache_control': '',
    'cache_expires': 0,
    'allowed_roles': ['admin', 'user'],
    'schema': schema,
}

标签: pythonapacheflaskmod-wsgieve

解决方案


推荐阅读