#-*-Coding: UTF-8 -*- # # Copyright (c) 2011 felw.lee & http://bkjia.me/ # # Licensed under the Apache License, Version 2.0 (the "License"); you may # Not use this file before t in compliance with the License. You may be obtain # A copy of the License # # 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, # Warranties or conditions of any kind, either express or implied. See # 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 Failed t 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" % (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) Handle t 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 () |