009. HTTP 代理,但是加強(qiáng)版
前言
在去年的一篇舊文中(002. HTTP 代理原理及 Python 簡(jiǎn)單實(shí)現(xiàn)),實(shí)現(xiàn)了簡(jiǎn)單的 HTTP 代理服務(wù)器。現(xiàn)在回頭看來,發(fā)覺十分簡(jiǎn)陋,實(shí)際用處并不大,特此加以改進(jìn)。
主要改進(jìn)方面如下:
優(yōu)化了代碼邏輯,高度封裝,調(diào)用方便;
全部采用 Python 內(nèi)置標(biāo)準(zhǔn)庫(kù),深入了解底層原理;
支持代理認(rèn)證機(jī)制,用于驗(yàn)證客戶端身份;
支持多層代理,可配置代理服務(wù)器的代理;
支持 HTTP 的 GET、POST 方法;
豐富了代碼注釋與類型注解。
優(yōu)化
創(chuàng)建?ProxyServer 服務(wù)器類,繼承自?http.server 的?ThreadingHTTPServer。新增 auth、proxy_addr、proxy_auth,用于實(shí)現(xiàn)多層代理與身份認(rèn)證。
Proxy-Authorization 是一個(gè)請(qǐng)求首部,其中包含了用戶代理提供給代理服務(wù)器的用于身份驗(yàn)證的憑證。這個(gè)首部通常是在服務(wù)器返回了 407 Proxy Authentication Required 響應(yīng)狀態(tài)碼及 Proxy-Authenticate 首部后發(fā)送的。
Proxy-Authorization: <type> <credentials>
一個(gè)服務(wù)器實(shí)例最多有兩個(gè)用于身份驗(yàn)證的憑證,且服務(wù)器運(yùn)行后一般不會(huì)再改變。為避免每次請(qǐng)求都需計(jì)算比對(duì)認(rèn)證,初始化時(shí)就先計(jì)算好密鑰。
在請(qǐng)求處理程序中,由于增加了認(rèn)證機(jī)制,故每次請(qǐng)求前均需進(jìn)行身份認(rèn)證。同時(shí),為了起到較好的匿名效果,刪去與 Proxy 相關(guān)請(qǐng)求頭。
每次請(qǐng)求前認(rèn)證,不成功直接結(jié)束該次請(qǐng)求:
對(duì)于隧道代理,專門用一個(gè)函數(shù)實(shí)現(xiàn)當(dāng)前服務(wù)器與另一代理服務(wù)器或目標(biāo)網(wǎng)站服務(wù)器之間的連接。采用 http.client 中的?HTTPConnection 實(shí)現(xiàn)二者之間的連接:
在建立好隧道之后,剩下的就比較簡(jiǎn)單了。先給客戶端響應(yīng) CONNECT 成功,再直接轉(zhuǎn)發(fā) TCP 數(shù)據(jù)就可以了。
對(duì)于 handle_tcp 方法,相較于原來略有優(yōu)化。主要是精簡(jiǎn)了代碼,實(shí)現(xiàn)邏輯并未改變。
雖然現(xiàn)在主流網(wǎng)站均采用 HTTPS 加密傳輸,但仍有些時(shí)候需要用到 HTTP 請(qǐng)求,也需考慮在內(nèi)。簡(jiǎn)單實(shí)現(xiàn)邏輯如下:
由于 GET 與 POST 方法在?HTTPConnection 中差別不大,可以用 GET 的方法來處理 POST 請(qǐng)求,其他 HTTP 方法不予考慮。
使用
在全面優(yōu)化后,使用十分簡(jiǎn)單。四行代碼即可搭建一個(gè)最簡(jiǎn)單的代理服務(wù)器:
若有多層代理及身份認(rèn)證需要,可以參照以下例子使用:
代碼
完整代碼如下:
延伸閱讀
由淺入深寫代理(6)-http-代理:https://zhuanlan.zhihu.com/p/28737960
由淺入深寫代理(7)-https-代理:https://zhuanlan.zhihu.com/p/2876766
http.server --- HTTP 服務(wù)器:https://docs.python.org/zh-cn/3/library/http.server.html
http.client --- HTTP 客戶端:https://docs.python.org/zh-cn/3/library/http.client.html
Proxy-Authorization:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Proxy-Authorization
HTTP 身份驗(yàn)證:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication
請(qǐng)求測(cè)試網(wǎng)站:https://httpbin.org/