激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - 在Python的Tornado框架中實現(xiàn)簡單的在線代理的教程

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

2020-06-20 10:21腳本之家 Python

這篇文章主要介紹了在Python的Tornado框架中實現(xiàn)簡單的在線代理的教程,代理功能是一個常見的網(wǎng)絡(luò)編程實現(xiàn),需要的朋友可以參考下

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# -*- 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()

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

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

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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲91在线 | 亚洲免费看片网站 | 成人黄色小视频在线观看 | 意大利av在线 | 欧美精品一区二区久久 | 日本一级特级 | 草逼一区| 欧美成年视频 | 久久久国产电影 | 久久亚洲综合色 | 国产免费小视频在线观看 | 狠狠干伊人网 | 久久久久国产成人免费精品免费 | 国产手机在线视频 | 斗破苍穹在线观看免费完整观看 | 久久一级| 视频一区二区三区在线观看 | 色猫av| 欧美成人免费电影 | 91精品最新国内在线播放 | 日韩色电影 | 亚洲一区二区三区精品在线观看 | 精品国产一区二区三区在线 | 空姐毛片| 香蕉视频网站在线观看 | 全黄性性激高免费视频 | 黄网站免费入口 | 欧美大逼网 | 亚洲影院在线 | 日本在线视 | gogo全球大胆高清人露出91 | 免费看污视频在线观看 | 九九色网站 | 欧美四级在线观看 | 草久视频在线观看 | 日韩黄色影视 | 欧美视频一区二区三区四区 | 末成年女av片一区二区 | 欧美在线观看视频一区二区 | 青草久久网 | 欧美综合成人 |