最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Python的Tornado框架中實(shí)現(xiàn)簡(jiǎn)單的在線代理的教程

 更新時(shí)間:2015年05月02日 17:10:07   投稿:goldensun  
這篇文章主要介紹了在Python的Tornado框架中實(shí)現(xiàn)簡(jiǎn)單的在線代理的教程,代理功能是一個(gè)常見(jiàn)的網(wǎng)絡(luò)編程實(shí)現(xiàn),需要的朋友可以參考下

實(shí)現(xiàn)代理的方式很多種,流行的web服務(wù)器也大都有代理的功能,比如http://www.tornadoweb.cn用的就是nginx的代理功能做的tornadoweb官網(wǎng)的鏡像。

最近,我在開(kāi)發(fā)一個(gè)移動(dòng)運(yùn)用(以下簡(jiǎn)稱(chēng)APP)的后臺(tái)程序(Server),該運(yùn)用需要調(diào)用到另一平臺(tái)產(chǎn)品(Platform)的API。對(duì)于這個(gè)系統(tǒng)來(lái)說(shuō),可選的一種實(shí)現(xiàn)方式方式是APP同時(shí)跟Server&Platform兩者交互;另一種則在Server端封裝掉Platform的API,APP只和Server交互。顯然后一種方式的系統(tǒng)架構(gòu)會(huì)清晰些,APP編程時(shí)也就相對(duì)簡(jiǎn)單。那么如何在Server端封裝Platform的API呢,我首先考慮到的就是用代理的方式來(lái)實(shí)現(xiàn)。碰巧最近Tornado郵件群組里有人在討論using Tornado as a proxy,貼主提到的運(yùn)用場(chǎng)景跟我這碰到的場(chǎng)景非常的相似,我把原帖的代碼做了些整理和簡(jiǎn)化,源代碼如下:

# -*- coding: utf-8 -*-
#
# Copyright(c) 2011 Felinx Lee & http://feilong.me/
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
 
import logging
 
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.web import HTTPError, asynchronous
from tornado.httpclient import HTTPRequest
from tornado.options import define, options
try:
  from tornado.curl_httpclient import CurlAsyncHTTPClient as AsyncHTTPClient
except ImportError:
  from tornado.simple_httpclient import SimpleAsyncHTTPClient as AsyncHTTPClient
 
define("port", default=8888, help="run on the given port", type=int)
define("api_protocol", default="http")
define("api_host", default="feilong.me")
define("api_port", default="80")
define("debug", default=True, type=bool)
 
class ProxyHandler(tornado.web.RequestHandler):
  @asynchronous
  def get(self):
    # enable API GET request when debugging
    if options.debug:
      return self.post()
    else:
      raise HTTPError(405)
 
  @asynchronous
  def post(self):
    protocol = options.api_protocol
    host = options.api_host
    port = options.api_port
 
    # port suffix
    port = "" if port == "80" else ":%s" % port
 
    uri = self.request.uri
    url = "%s://%s%s%s" % (protocol, host, port, uri)
 
    # update host to destination host
    headers = dict(self.request.headers)
    headers["Host"] = host
 
    try:
      AsyncHTTPClient().fetch(
        HTTPRequest(url=url,
              method="POST",
              body=self.request.body,
              headers=headers,
              follow_redirects=False),
        self._on_proxy)
    except tornado.httpclient.HTTPError, x:
      if hasattr(x, "response") and x.response:
        self._on_proxy(x.response)
      else:
        logging.error("Tornado signalled HTTPError %s", x)
 
  def _on_proxy(self, response):
    if response.error and not isinstance(response.error,
                       tornado.httpclient.HTTPError):
      raise HTTPError(500)
    else:
      self.set_status(response.code)
      for header in ("Date", "Cache-Control", "Server", "Content-Type", "Location"):
        v = response.headers.get(header)
        if v:
          self.set_header(header, v)
      if response.body:
        self.write(response.body)
      self.finish()
 
def main():
  tornado.options.parse_command_line()
  application = tornado.web.Application([
    (r"/.*", ProxyHandler),
  ])
  http_server = tornado.httpserver.HTTPServer(application)
  http_server.listen(options.port)
  tornado.ioloop.IOLoop.instance().start()
 
if __name__ == "__main__":
  main()

運(yùn)行上面的代碼后,訪問(wèn) http://localhost:8888/ 將會(huì)完整顯示飛龍博客的首頁(yè),即代理訪問(wèn)了http://feilong.me/的內(nèi)容。

我考慮用程序的方式來(lái)做代理而不是直接用Nginx來(lái)做代理,其中一點(diǎn)是考慮到用程序可以很容易的控制Platform的哪些API是需要代理的,而哪些是要屏蔽掉的,還有哪些可能是要重寫(xiě)的(比如Server的login可能不能直接代理Platform的login,但卻要調(diào)用到Platform的login API)。

以上這段代碼只是做了簡(jiǎn)單的頁(yè)面內(nèi)容代理,并沒(méi)有對(duì)頁(yè)面進(jìn)行進(jìn)一步的解析處理,比如鏈接替換等,這些就交個(gè)有興趣的朋友去開(kāi)發(fā)了。基于以上這段代碼,將其擴(kuò)展一下,是完全可以實(shí)現(xiàn)一個(gè)完整的在線代理程序的。

這段代碼我已放到了我的實(shí)驗(yàn)項(xiàng)目里,見(jiàn)https://bitbucket.org/felinx/labs,我將會(huì)放更多類(lèi)似于這樣的實(shí)驗(yàn)性質(zhì)的小項(xiàng)目到這個(gè)repository里來(lái),有興趣的朋友可以關(guān)注一下。

轉(zhuǎn)載請(qǐng)注明出處:http://feilong.me/2011/09/tornado-as-a-proxy

相關(guān)文章

  • django之導(dǎo)入并執(zhí)行自定義的函數(shù)模塊圖解

    django之導(dǎo)入并執(zhí)行自定義的函數(shù)模塊圖解

    這篇文章主要介紹了django之導(dǎo)入并執(zhí)行自定義的函數(shù)模塊圖解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-04-04
  • python創(chuàng)建文件備份的腳本

    python創(chuàng)建文件備份的腳本

    這篇文章主要介紹了python創(chuàng)建文件備份的腳本,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • Django使用channels + websocket打造在線聊天室

    Django使用channels + websocket打造在線聊天室

    本文將教你如何使用channels + websocket打造個(gè)在線聊天室。一共只有四步,你可以輕松上手并學(xué)會(huì)。項(xiàng)目中大部分代碼是基于channels的官方文檔的,加入了些自己的理解,以便新手學(xué)習(xí)使用。
    2021-05-05
  • 你知道怎么用Python監(jiān)控聊天記錄嗎

    你知道怎么用Python監(jiān)控聊天記錄嗎

    今天有位同事和我吐槽關(guān)于公司 XX 的問(wèn)題,我告訴他不要在公司電腦上說(shuō)這些,因?yàn)楹芸赡軙?huì)被狙擊,這位同事剛開(kāi)始還不信,直到我寫(xiě)了這邊文章,他才恍然大悟
    2021-10-10
  • 利用Rust實(shí)現(xiàn)Python加速的技巧分享

    利用Rust實(shí)現(xiàn)Python加速的技巧分享

    這篇文章主要想來(lái)和大家一起探討一下關(guān)于使用Rust對(duì)Python計(jì)算進(jìn)行加速的問(wèn)題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • kali最新國(guó)內(nèi)更新源sources

    kali最新國(guó)內(nèi)更新源sources

    這篇文章主要介紹了kali最新國(guó)內(nèi)更新源sources的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • numpy之多維數(shù)組的創(chuàng)建全過(guò)程

    numpy之多維數(shù)組的創(chuàng)建全過(guò)程

    這篇文章主要介紹了numpy之多維數(shù)組的創(chuàng)建全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • python 寫(xiě)入csv亂碼問(wèn)題解決方法

    python 寫(xiě)入csv亂碼問(wèn)題解決方法

    這篇文章主要介紹了python 寫(xiě)入csv亂碼問(wèn)題解決方法的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • python裝飾器decorator介紹

    python裝飾器decorator介紹

    這篇文章主要介紹了python裝飾器decorator介紹,decorator設(shè)計(jì)模式允許動(dòng)態(tài)地對(duì)現(xiàn)有的對(duì)象或函數(shù)包裝以至于修改現(xiàn)有的職責(zé)和行為,簡(jiǎn)單地講用來(lái)動(dòng)態(tài)地?cái)U(kuò)展現(xiàn)有的功能,需要的朋友可以參考下
    2014-11-11
  • Python Flask全棧項(xiàng)目實(shí)戰(zhàn)構(gòu)建在線書(shū)店流程

    Python Flask全棧項(xiàng)目實(shí)戰(zhàn)構(gòu)建在線書(shū)店流程

    這篇文章主要為大家介紹了Python Flask全流程全棧項(xiàng)目實(shí)戰(zhàn)之在線書(shū)店構(gòu)建實(shí)現(xiàn)過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11

最新評(píng)論

栾城县| 平远县| 蓬莱市| 石门县| 合肥市| 枣阳市| 万年县| 葫芦岛市| 克东县| 台南县| 洛隆县| 英山县| 固镇县| 满洲里市| 台北县| 长顺县| 璧山县| 和林格尔县| 蒲城县| 奉化市| 南投县| 常德市| 土默特右旗| 海淀区| 大埔县| 河北省| 黄梅县| 黄大仙区| 永州市| 德令哈市| 碌曲县| 金平| 奈曼旗| 寻乌县| 南华县| 武陟县| 天全县| 青龙| 永安市| 雷州市| 阿瓦提县|