簡體   English   中英

Python扭曲:HTTPS API的反向代理:無法連接

[英]Python-Twisted: Reverse Proxy to HTTPS API: Could not connect

我正在嘗試建立反向代理以與某些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()

當我在容器中執行CURL時,我得到一個有效的請求(意味着我得到了適當的JSON響應)。

這是我使用CURL命令的方式:

curl https://api.github.com/users/defunkt

這是我得到的輸出:

{
  "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"
}

但是,當我嘗試使用以下方式通過Firefox獲取代理時:

http://10.5.5.225:8080/

我得到:“無法連接”

這是我的扭曲日志的樣子:

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)Gecko / 20100101 Firefox / 44.0“

2016-02-27 [-]停廠

如何使用Twisted進行API調用(無論如何,如今大多數API都是HTTPS)並獲得所需的響應(基本上,“ 200”響應/ JSON應該是什么)?

我嘗試着看這個問題: 在Twisted中將HTTP代理轉換為HTTPS代理

但這從編碼的角度來看並沒有多大意義(或提及任何有關反向代理的問題)。

**編輯:我還嘗試使用以下方法將HTTPS API調用切換為常規HTTP調用:

curl http [冒號] [slash] [slash] openlibrary [dot] org [slash] authors [slash] OL1A.json

(上面的URL已經過格式化,以避免鏈接沖突問題)

但是,我在瀏覽器中仍然遇到相同的錯誤(如上所述)。

** Edit2:我曾嘗試運行您的代碼,但出現此錯誤:

錯誤截圖

如果查看圖像,將看到以下錯誤(運行代碼時):

Builtins.AttributeError:'str'對象沒有屬性'decode'

如果您閱讀了ReverseProxyResourceAPI文檔 ,則會看到__init__的簽名是:

def __init__(self, host, port, path, reactor=reactor):

和“ host ”被記錄為“要代理的Web服務器的主機”。

因此,您正在傳遞Twisted需要主機的URI。

更糟糕的是, 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

如果運行此命令,則curl http://localhost:8080/應該可以完成您的期望。

我已經采取了某種方式使您的Twisted代碼現代化。 端點而不是listenTCP ,用logger而不是twisted.python.log ,並react而不是自己啟動反應堆。

末尾的奇怪的小putChild部分是因為當我們通過b"/users/defunkt"作為路徑時,這意味着對/的請求將導致客戶端請求/users/defunkt/ (請注意/users/defunkt/斜杠),這是GitHub API中的404。 如果我們明確地將空子段路徑代理為沒有尾段,我相信它將按照您的期望進行。

請注意 :從純文本HTTP代理到加密的HTTPS可能非常危險 ,因此我在此處添加了僅本地主機的默認偵聽接口。 如果字節在實際網絡上傳輸,則應確保已使用TLS對其進行了正確加密。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM