Chinaunix首页 | 论坛 | 博客
  • 博客访问: 140615
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 309
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-06 11:27
个人简介

开启暴走模式。

文章分类

全部博文(31)

文章存档

2017年(19)

2016年(1)

2015年(11)

我的朋友

分类: Python/Ruby

2017-03-01 09:34:04


点击(此处)折叠或打开

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Author: Dily
  4. # Email:312797697@qq.com
  5. """实现API代理服务"""

  1. import logging
  2.   
  3. import tornado.httpserver
  4. import tornado.ioloop
  5. import tornado.options
  6. import tornado.web
  7. import tornado.httpclient
  8. from tornado.web import HTTPError, asynchronous
  9. from tornado.httpclient import HTTPRequest
  10. from tornado.options import define, options
  11. try:
  12.   from tornado.curl_httpclient import CurlAsyncHTTPClient as AsyncHTTPClient
  13. except ImportError:
  14.   from tornado.simple_httpclient import SimpleAsyncHTTPClient as AsyncHTTPClient
  15.   
  16. define("port", default=38888, help="run on the given port", type=int)
  17. define("api_protocol", default="https")
  18. define("api_host", default="DOMAIN")
  19. define("api_port", default="443")
  20. define("api_url", default="URI")
  21. define("debug", default=True, type=bool)
  22.   
  23. class ProxyHandler(tornado.web.RequestHandler):
  24.   @asynchronous
  25.   def get(self):
  26.     # enable API GET request when debugging
  27.     if options.debug:
  28.       return self.post()
  29.     else:
  30.       raise HTTPError(405)
  31.   
  32.   @asynchronous
  33.   def post(self):
  34.     protocol = options.api_protocol
  35.     host = options.api_host
  36.     port = options.api_port
  37.     murl = options.api_url
  38.  
  39.     # port suffix
  40.     port = "" if port == "443" else ":%s" % port
  41.   
  42.     uri = self.request.uri
  43.     url = "%s://%s%s%s%s" % (protocol, host, port, uri, murl)
  44.   
  45.     # update host to destination host
  46.     headers = dict(self.request.headers)
  47.     headers["Host"] = host
  48.   
  49.     try:
  50.       AsyncHTTPClient().fetch(
  51.         HTTPRequest(url=url,
  52.               method="POST",
  53.               body=self.request.body,
  54.               headers=headers,
  55.               follow_redirects=False),
  56.         self._on_proxy)
  57.     except tornado.httpclient.HTTPError, x:
  58.       if hasattr(x, "response") and x.response:
  59.         self._on_proxy(x.response)
  60.       else:
  61.         logging.error("Tornado signalled HTTPError %s", x)
  62.   
  63.   def _on_proxy(self, response):
  64.     if response.error and not isinstance(response.error,
  65.                        tornado.httpclient.HTTPError):
  66.       raise HTTPError(500)
  67.     else:
  68.       self.set_status(response.code)
  69.       for header in ("Date", "Cache-Control", "Server", "Content-Type", "Location"):
  70.         v = response.headers.get(header)
  71.         if v:
  72.           self.set_header(header, v)
  73.       if response.body:
  74.         self.write(response.body)
  75.       self.finish()
  76.   
  77. def main():
  78.   tornado.options.parse_command_line()
  79.   application = tornado.web.Application([
  80.     (r"/.*", ProxyHandler),
  81.   ])
  82.   http_server = tornado.httpserver.HTTPServer(application)
  83.   http_server.listen(options.port)
  84.   tornado.ioloop.IOLoop.instance().start()
  85.   
  86. if __name__ == "__main__":
  87.   main()

阅读(2210) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~