coo*_*lpy 3 python reverse-proxy twisted twisted.web lxc
我正在尝试构建一个反向代理来与某些 API(如 Twitter、Github、Instagram)交谈,然后我可以用我的反向代理调用我想要的任何(客户端)应用程序(把它想象成一个 API 管理器) .
另外,我正在使用 LXC 容器来执行此操作。
例如,这是我从 Twisted Docs 上的示例中破解的最简单的代码:
from twisted.internet import reactor
from twisted.web import proxy, server
from twisted.python.log import startLogging
from sys import stdout
startLogging(stdout)
site = server.Site(proxy.ReverseProxyResource('https://api.github.com/users/defunkt', 443, b''))
reactor.listenTCP(8080, site)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
当我在容器内执行 CURL 时,我得到一个有效的请求(意味着我得到了适当的 JSON 响应)。
这是我如何使用 CURL 命令:
curl https://api.github.com/users/defunkt
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出:
{
"login": "defunkt",
"id": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/2?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/defunkt",
"html_url": "https://github.com/defunkt",
"followers_url": "https://api.github.com/users/defunkt/followers",
"following_url": "https://api.github.com/users/defunkt/following{/other_user}",
"gists_url": "https://api.github.com/users/defunkt/gists{/gist_id}",
"starred_url": "https://api.github.com/users/defunkt/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/defunkt/subscriptions",
"organizations_url": "https://api.github.com/users/defunkt/orgs",
"repos_url": "https://api.github.com/users/defunkt/repos",
"events_url": "https://api.github.com/users/defunkt/events{/privacy}",
"received_events_url": "https://api.github.com/users/defunkt/received_events",
"type": "User",
"site_admin": true,
"name": "Chris Wanstrath",
"company": "GitHub",
"blog": "http://chriswanstrath.com/",
"location": "San Francisco",
"email": "chris@github.com",
"hireable": true,
"bio": null,
"public_repos": 107,
"public_gists": 280,
"followers": 15153,
"following": 208,
"created_at": "2007-10-20T05:24:19Z",
"updated_at": "2016-02-26T22:34:27Z"
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用以下方法通过 Firefox 获取代理时:
我得到:“无法连接”
这是我的 Twisted 日志的样子:
2016-02-27 [-] 日志打开。
2016-02-27 [-] 网站从 8080 开始
2016-02-27 [-] 开工
2016-02-27 [-] 开工
2016-02-27 [-] "10.5.5.225" - - [27/Feb/2016: +0000] "GET / HTTP/1.1" 501 26 "-" "Mozilla/5.0 (X11; Debian; Linux x86_64; rv :44.0) 壁虎/20100101 Firefox/44.0"
2016-02-27 [-] 停厂
我如何使用 Twisted 进行 API 调用(现在大多数 API 都是 HTTPS)并获得所需的响应(基本上,“200”响应/JSON 应该是什么)?
我试着看这个问题:Convert HTTP Proxy to HTTPS Proxy in Twisted
但是从编码的角度来看它没有多大意义(或提及任何有关反向代理的内容)。
**编辑:我还尝试使用以下方法为常规 HTTP 调用切换 HTTPS API 调用:
curl http[colon][slash][slash]openlibrary[dot]org[slash]authors[slash]OL1A.json
(上面的 URL 已被格式化以避免链接冲突问题)
但是,我的浏览器中仍然出现相同的错误(如上所述)。
**Edit2:我试过运行您的代码,但出现此错误:
如果您查看图像,您将看到以下错误(运行代码时):
builtins.AttributeError: 'str' 对象没有属性 'decode'
如果您阅读 的API 文档ReverseProxyResource,您将看到 的签名__init__是:
def __init__(self, host, port, path, reactor=reactor):
Run Code Online (Sandbox Code Playgroud)
并且“ host”被记录为“要代理的网络服务器的主机”。
因此,您正在传递一个 URI,其中 Twisted 需要一个主机。
更糟糕的是,ReverseProxyResource它是为在 Web 服务器上本地使用而设计的,并不完全支持https://开箱即用的 URL。
不过,它确实有一个(非常有限的)可扩展性挂钩proxyClientFactoryClass——并且为ReverseProxyResource没有开箱即用的功能而道歉,我将向您展示如何使用它来扩展ReverseProxyResource以添加https://支持,以便您可以使用 GitHub API :)。
from twisted.web import proxy, server
from twisted.logger import globalLogBeginner, textFileLogObserver
from twisted.protocols.tls import TLSMemoryBIOFactory
from twisted.internet import ssl, defer, task, endpoints
from sys import stdout
globalLogBeginner.beginLoggingTo([textFileLogObserver(stdout)])
class HTTPSReverseProxyResource(proxy.ReverseProxyResource, object):
def proxyClientFactoryClass(self, *args, **kwargs):
"""
Make all connections using HTTPS.
"""
return TLSMemoryBIOFactory(
ssl.optionsForClientTLS(self.host.decode("ascii")), True,
super(HTTPSReverseProxyResource, self)
.proxyClientFactoryClass(*args, **kwargs))
def getChild(self, path, request):
"""
Ensure that implementation of C{proxyClientFactoryClass} is honored
down the resource chain.
"""
child = super(HTTPSReverseProxyResource, self).getChild(path, request)
return HTTPSReverseProxyResource(child.host, child.port, child.path,
child.reactor)
@task.react
def main(reactor):
import sys
forever = defer.Deferred()
myProxy = HTTPSReverseProxyResource('api.github.com', 443,
b'/users/defunkt')
myProxy.putChild("", myProxy)
site = server.Site(myProxy)
endpoint = endpoints.serverFromString(
reactor,
dict(enumerate(sys.argv)).get(1, "tcp:8080:interface=127.0.0.1")
)
endpoint.listen(site)
return forever
Run Code Online (Sandbox Code Playgroud)
如果你运行这个,curl http://localhost:8080/应该做你期望的。
我冒昧地对您的 Twisted 代码进行了一些现代化改造;端点而不是listenTCP,记录器而不是twisted.python.log,而react不是自己启动反应器。
最后一个奇怪的小putChild部分是因为当我们b"/users/defunkt"作为路径传递时,这意味着请求/将导致客户端请求/users/defunkt/(注意尾部斜杠),这是 GitHub API 中的 404。如果我们明确地代理空子段路径,就好像它没有尾随段一样,我相信它会做你所期望的。
请注意:从纯文本 HTTP 代理到加密的 HTTPS 可能非常危险,所以我在这里添加了一个仅限本地主机的默认监听接口。如果您的字节通过实际网络传输,您应该确保它们使用 TLS 正确加密。
| 归档时间: |
|
| 查看次数: |
1913 次 |
| 最近记录: |