如何构建带SSL支持的uWSGI以使用WebSocket握手API功能?
我现在的环境: 使用的是ubuntu 14.4,uwsgi正在和flask(Python)一起运行,nginx作为反向代理。
我想要实现的: 运行这个WebSockets的示例: https://github.com/zeekay/flask-uwsgi-websocket/blob/master/examples/echo/echo.py
当我在5000端口用chromepy运行这个应用时,一切正常,但当我尝试不使用chromepy时,就出现了错误。
错误信息:
Thu Jun 12 12:58:24 2014 - you need to build uWSGI with SSL support to use the websocket handshake api function !!!
Traceback (most recent call last):
File "/home/lab_alglab/rep/car/local/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/lab_alglab/rep/car/local/lib/python2.7/site-packages/flask_uwsgi_websocket/websocket.py", line 54, in __call__
uwsgi.websocket_handshake(environ['HTTP_SEC_WEBSOCKET_KEY'], environ.get('HTTP_ORIGIN', ''))
IOError: unable to complete websocket handshake
6 个回答
这是针对 Ubuntu 20.04
和 python 3.8.10
的解决方案,pip
是通过 apt
安装的系统软件包:
# switch to root because system packages can't be changed without root privileges
# This is not necessary for user based environment like virtualenv or pyenv
sudo su -
# Uninstall previous version of `uwsgi` if exists
pip uninstall uwsgi
# Install libraries for SSL support
apt-get install libssl-dev
## Manually build uwsgi with SSL support
# set necessary lib paths
export CFLAGS="-I/usr/include/openssl"
# aarch64-linux-gnu folder used for ARM architecture and may be different for your env
# use [apt-file list libssl-dev] to check lib folders (apt-file should be additionally installed)
export LDFLAGS="-L/usr/lib/aarch64-linux-gnu"
# activate SSL support
export UWSGI_PROFILE_OVERRIDE=ssl=true
# build uwsgi using pip (--no-use-wheel depricated so used --no-binary instead)
# this command will install 2.0.20 version. Version may be changed or removed. It is not mandatory
pip install -I --no-binary=:all: --no-cache-dir uwsgi==2.0.20
# Check SSL support
uwsgi --help | grep https
预期的输出结果:
--https-socket bind to the specified UNIX/TCP socket using HTTPS protocol
--https-socket-modifier1 force the specified modifier1 when using HTTPS protocol
--https-socket-modifier2 force the specified modifier2 when using HTTPS protocol
--https add an https router/server on the specified address with specified certificate and key
--https2 add an https/spdy router/server using keyval options
--https-export-cert export uwsgi variable HTTPS_CC containing the raw client certificate
--https-session-context set the session id context to the specified value
--http-to-https add an http router/server on the specified address and redirect all of the requests to https
根据这个讨论中的其他回答和评论。谢谢大家
我解决这个问题的方法是通过pip安装了uwsgi(在虚拟环境外),然后修改了初始化脚本(在Ubuntu系统中是/etc/init.d/uwsgi),让它运行新安装的2.x版本(而不是1.9版本)。
Pip安装的路径是/usr/local/bin,所以我把脚本中的那行daemon改成了:DAEMON="/usr/local/bin/uwsgi"
只需要安装 OpenSSL 的开发头文件(libssl-dev),然后重新构建 uwsgi(它的构建系统会自动检测 SSL 是否可用)。
正如下面某位发帖者提到的,你需要openssl的头文件。如果这些文件放在不常见的位置(比如在Mac OS-X上),你需要告诉uWSGI它们在哪里。
在Debian/Ubuntu上,你可以通过命令“apt-get install libssl-dev”来安装它们。安装后,它们会放在/usr/include/目录下,这个目录是uWSGI自动查找的一部分。这样就可以了。
在Mac OS-X El Capitan(10.11)中,openssl的头文件被移除了。你可以用一个命令检查常见的位置——这些文件可能是通过像brew或macports这样的包管理工具安装的。
find /usr/local/include /usr/include /opt/local/include /usr/local/ssl/include -name openssl -type d 2> /dev/null
如果这个命令没有返回任何结果,你就需要安装这些头文件。你可以通过MacPorts(使用命令port install openssl)来安装,它会把文件放在/opt/local/include,并在/usr/local/include中建立一个链接。你也可以直接安装,方法是下载并解压openssl,然后运行“./Configure darwin64-x86_64-cc”,接着是“make”,最后是“sudo make install”。
Xcode的构建工具包提供了一个预定义的构建环境。对于XCode项目来说,这意味着开发者有一个共同的基础来进行开发,而任何不在基础中的东西都必须在XCode项目中。要在基础之外构建开源项目会有点麻烦,因为像openssl这样的依赖项通常不在基础目录中。你可以给uWSGI的构建链提供一个包含目录来使用。它不支持用冒号(:)分隔的路径样式。
在大多数安装情况下,以下命令应该可以用于OpenSSL。
UWSGI_INCLUDES=/usr/local/include/ pip install uwsgi
我需要通过brew来安装OpenSSL。然后运行这个命令。
CFLAGS="-I/usr/local/opt/openssl/include" LDFLAGS="-L/usr/local/opt/openssl/lib" UWSGI_PROFILE_OVERRIDE=ssl=true pip install uwsgi -Iv