Tutorial on implementing simple online proxy in Python Tornado framework

Source: Internet
Author: User

Tutorial on implementing simple online proxy in Python Tornado framework

This article mainly introduces how to implement simple online proxy in the Python Tornado framework. The proxy function is a common network programming implementation. If you need it, refer

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:

?

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 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 ()

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.

Note <>: For more exciting tutorials, please pay attention to the help house programming

Related Article

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.