为什么我用Djang得到一个“SSL错误:调用了一个不应该调用的函数”

2024-04-19 12:07:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python 3.5/Django 1.10应用程序,它通过SSL服务于Apache/mod_wsgi。它连接到Postgres 9.5.2数据库(使用psycopg2==2.6.2),并在AlwaysData的服务器上运行

它大多数时候都很好,但有时我会有一个我不理解的错误。在

(SSL error: called a function you should not call)

如果我输入以下数据库设置:错误似乎每次都会发生

^{pr2}$

它似乎是在查询数据库时发生的。在

# django/db/backends/utils.py line 64
return self.cursor.execute(sql, params)

当Angular2应用程序调用restapi(使用django REST框架生成)时,就会出现问题。在

我激活了以下设置:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

为什么会这样?如何在我的Django项目中修复这个问题。在

注意:This question看起来很相似,但我不直接管理OpenSSL层,所以它没有很大帮助。在

编辑:这是完整的回溯

File "proj/env/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _legacy_get_response
  249.             response = self._get_response(request)

File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "proj/env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "proj/env/lib/python3.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)

File "proj/env/lib/python3.5/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
  474.             response = self.handle_exception(exc)

File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in handle_exception
  434.             self.raise_uncaught_exception(exc)

File "proj/env/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
  471.             response = handler(request, *args, **kwargs)

File "proj/apps/costs/apis.py" in get
  296.         data = self.get_spends_stats(cost_items, perimeter, start_date, end_date)

File "proj/apps/costs/apis.py" in get_spends_stats
  306.         for building in buildings:

File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in __iter__
  256.         self._fetch_all()

File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in _fetch_all
  1087.             self._result_cache = list(self.iterator())

File "proj/env/lib/python3.5/site-packages/django/db/models/query.py" in __iter__
  54.         results = compiler.execute_sql()

File "proj/env/lib/python3.5/site-packages/django/db/models/sql/compiler.py" in execute_sql
  835.             cursor.execute(sql, params)

File "proj/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "proj/env/lib/python3.5/site-packages/django/db/utils.py" in __exit__
  94.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "proj/env/lib/python3.5/site-packages/django/utils/six.py" in reraise
  685.             raise value.with_traceback(tb)

File "proj/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

Exception Type: OperationalError at /costs/api/benchmark/cost-center/3/38/2016-01/2017-12/
Exception Value: SSL error: called a function you should not call

Tags: djangoinpyselfenvexecutedbsql
3条回答

在SSL关机握手中有一个相关的bug #58956 in Apache + OpenSSL,以与2016年2月fixed by OpenSSL完全相同的错误消息结尾。尝试升级到1.0.2g或1.1.0或更高版本。在


编辑:如果您有一些1.0.2版本(可能有更多版本,但是您感兴趣的包链接到1.0.2),那么SSL的升级是值得考虑的。这里写的版本1.1.0只是为了完整起见,任何人都可以很容易地在以后检查一个版本,是否与这个bug有关。现在没有人在生产主机上安装了1.1版本,而自行升级可能是个坏主意。在

这个问题似乎可以通过更改数据库设置来解决

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'name',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': 'host',
        'PORT': '',
        'OPTIONS': {
            'sslmode': 'disable',
        },
    }
}

如果未设置,则该选项将使用prefer作为默认值(请参见https://www.postgresql.org/docs/9.5/static/libpq-ssl.html),这似乎具有不可预测的行为。在

我想根本原因是Apache和Postgres之间的OpenSSL不匹配。必须进行调查。在

当前的修复使数据库连接不安全,但这是另一回事。在

看起来像是psycopg2bug(或者更确切地说,as piro pointed out,底层的libpq的bug)。它似乎违反了所需的调用顺序-likely not waiting for some event。由于这是不规则发生的,这可能是一种竞争状态。在

它甚至提供了关于另一个错误的不完整信息。它应该使用^{}来获得格式为[pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message]的完整消息。在

相关问题 更多 >