Python FastCGI 客户端

5 投票
1 回答
4718 浏览
提问于 2025-04-16 22:08

我正在用Python写一个工具,用来监控fastcgi应用。对于fastcgi,我只需要加载ping和状态页面(如果失败就返回某种错误)。

有很多库(从python-fasctgi绑定到twisted)看起来都能做到这一点,但大多数对我来说都太复杂了,而且很多会让我增加额外的依赖,导致一些打包问题。

所以,有没有简单的Python fastcgi 客户端实现或库,安装和打包(成rpm)都很简单,或者足够小,可以和项目一起分发的?

更新

多亏了agf,我已经能够连接到fastcgi应用并发送请求了。它其实就是标准的php-fpm。但我无法从任何位置获取响应:我尝试从'/ping'获取,应该返回200 OK和'pong'在内容里。结果我得到的只是200 OK的响应,但内容是空的。

我这样发送请求:

def _load_page(self, url):
    """ load fastcgi page """
    fcgi = fcgi_client.FCGIApp(host = self.fcgi_host, port = self.fcgi_port)
    env = {
           'SCRIPT_FILENAME': url,
           'QUERY_STRING': url,
           'REQUEST_METHOD': 'GET',
           'SCRIPT_NAME': url,
           'REQUEST_URI': url,
           'GATEWAY_INTERFACE': 'CGI/1.1',
           'SERVER_SOFTWARE': 'ztc',
           'REDIRECT_STATUS': '200',
           'CONTENT_TYPE': '',
           'CONTENT_LENGTH': '0',
           'DOCUMENT_URI': url,
           'DOCUMENT_ROOT': '/',
           #'SERVER_PROTOCOL' : ???
           'REMOTE_ADDR': '127.0.0.1',
           'REMOTE_PORT': '123',
           'SERVER_ADDR': self.fcgi_host,
           'SERVER_PORT': str(self.fcgi_port),
           'SERVER_NAME': self.fcgi_host
           }
    ret = fcgi(env)
    print ret

我还不得不修改flup客户端的标准输入处理:

# Transfer wsgi.input to FCGI_STDIN
content_length = int(environ.get('CONTENT_LENGTH') or 0)
s = ''
while True:
    chunk_size = min(content_length, 4096)
    #s = environ['wsgi.input'].read(chunk_size)
    content_length -= len(s)
    rec = Record(FCGI_STDIN, requestId)
    rec.contentData = s
    rec.contentLength = len(s)
    rec.write(sock)

    if not s: break

注意我把s=''加上,而不是s = environ['wsgi.input'].read(chunk_size),这部分是flup的一些wsgi相关内容。所以它应该发送空的标准输入。

另外,我还修改了flup,让它return status, headers, result

我检查了响应读取的代码,似乎没问题:fpm确实返回了空的内容。我用wireshark检查了网络通信,感觉也没问题——所有参数都在传输。

有什么想法吗?

更新

问题出在fastcgi参数过滤函数上:它过滤掉了很多有用的参数,比如DOCUMENT_ROOT、SCRIPT_FILENAME等等。禁用这个后,一切都正常了。

对感兴趣的人,这里是修改过的客户端:https://bitbucket.org/rvs/ztc/src/6ec59525156d/src/ztc/lib/flup_fcgi_client.py,还有使用示例:https://bitbucket.org/rvs/ztc/src/6ec59525156d/src/ztc/php/fpm.py

1 个回答

6

虽然 flup 主要是用作一个快速cgi的 服务器,但它也包含了一个快速cgi的客户端。

http://hg.saddi.com/flup-server/file/tip/flup/client/fcgi_app.py

看起来它是一个独立的单文件实现,不需要其他依赖。它的许可证也很宽松。

撰写回答