Python Tornado framework to implement a simple online proxy tutorial, pythontornado

Source: Internet
Author: User

Python Tornado framework to implement a simple online proxy tutorial, pythontornado

There are many ways to implement proxy, popular web servers also have proxy functions, such as http://www.tornadoweb.cn is the proxy function of nginx tornadoweb official website image.

Recently, I am developing a background program (Server) for mobile applications (hereinafter referred to as Apps). This application needs to call the API of another Platform. For this system, an optional implementation method is that the APP interacts with the Server and Platform at the same time; the other is to encapsulate the Platform API on the Server, the APP only interacts with the Server. Obviously, the system architecture of the latter method will be clearer, and APP programming will be relatively simple. So how can we encapsulate the Platform API on the Server? The first thing I want to consider is to implement it in proxy mode. It happened that someone in the Tornado mail group was discussing using Tornado as a proxy recently. The Application Scenario mentioned by the Post-master is very similar to the scenario I encountered, I have sorted out and simplified the original post code. The source code is as follows:

# -*- 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.httpserverimport tornado.ioloopimport tornado.optionsimport tornado.webimport tornado.httpclientfrom tornado.web import HTTPError, asynchronousfrom tornado.httpclient import HTTPRequestfrom tornado.options import define, optionstry:  from tornado.curl_httpclient import CurlAsyncHTTPClient as AsyncHTTPClientexcept 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()

After running the above Code, accessing http: // localhost: 8888/will display the homepage of the Flying Dragon blog, that is, the proxy accesses the content of http://feilong.me.

I want to use a program as a proxy instead of using Nginx as a proxy. One of them is that the program can easily control which APIs of Platform need proxy, which are to be blocked, and which may be overwritten (for example, the login of the Server may not directly proxy the login of Platform, but must call the login API of Platform ).

The above code is just a simple page content proxy, and does not further parse the page, such as link replacement, and so on. These will be developed by a friend of interest. Based on the above code, you can extend it to implement a complete online proxy program.

This code has been put into my experiment project. For details, see examples.

Reprinted please indicate the source: http://feilong.me/2011/09/tornado-as-a-proxy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.