Python practice-Http Proxy Server

Source: Internet
Author: User
Tags builtin

I plan to study the socket programming of pytho in depth, so I plan to take a look at it and find it difficult to write it well. There are many problems in the middle. It is really easy to read and do.

The source code is as follows:


[Python]
Import socket
Import thread
Import urlparse
Import select
 
BUFLEN = 8192
 
 
Class Proxy (object ):
Def _ init _ (self, conn, addr ):
Self. source = conn
Self. request = ""
Self. headers = {}
Self. destnation = socket. socket (socket. AF_INET, socket. SOCK_STREAM)
Self. run ()
 
Def get_headers (self ):
Header =''
While True:
Header + = self. source. recv (BUFLEN)
Index = header. find ('\ n ')
If index> 0:
Break
# FirstLine, self. request = header. split ('\ r \ n', 1)
FirstLine = header [: index]
Self. request = header [index + 1:]
Self. headers ['method'], self. headers ['path'], self. headers ['protocol'] = firstLine. split ()
 
Def conn_destnation (self ):
Url = urlparse. urlparse (self. headers ['path'])
Hostname = url [1]
Port = "80"
If hostname. find (':')> 0:
Addr, port = hostname. split (':')
Else:
Addr = hostname
Port = int (port)
Ip = socket. gethostbyname (addr)
Print ip, port
Self. destnation. connect (ip, port ))
Data = "% s \ r \ n" % (self. headers ['method'], self. headers ['path'], self. headers ['protocol'])
Self. destnation. send (data + self. request)
Print data + self. request
 
 
Def renderto (self ):
Readsocket = [self. destnation]
While True:
Data =''
(Rlist, wlist, elist) = select. select (readsocket, [], [], 3)
If rlist:
Data = rlist [0]. recv (BUFLEN)
If len (data)> 0:
Self. source. send (data)
Else:
Break
Def run (self ):
Self. get_headers ()
Self. conn_destnation ()
Self. renderto ()
 
 
 
Class Server (object ):
 
Def _ init _ (self, host, port, handler = Proxy ):
Self. host = host
Self. port = port
Self. server = socket. socket (socket. AF_INET, socket. SOCK_STREAM)
Self. server. setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1)
Self. server. bind (host, port ))
Self. server. listen (5)
Self. handler = handler
 
Def start (self ):
While True:
Try:
Conn, addr = self. server. accept ()
Thread. start_new_thread (self. handler, (conn, addr ))
Except t:
Pass
 
 
If _ name __= = '_ main __':
S = Server ('127. 0.0.1 ', 127)
S. start ()

Import socket
Import thread
Import urlparse
Import select

BUFLEN = 8192


Class Proxy (object ):
Def _ init _ (self, conn, addr ):
Self. source = conn
Self. request = ""
Self. headers = {}
Self. destnation = socket. socket (socket. AF_INET, socket. SOCK_STREAM)
Self. run ()

Def get_headers (self ):
Header =''
While True:
Header + = self. source. recv (BUFLEN)
Index = header. find ('\ n ')
If index> 0:
Break
# FirstLine, self. request = header. split ('\ r \ n', 1)
FirstLine = header [: index]
Self. request = header [index + 1:]
Self. headers ['method'], self. headers ['path'], self. headers ['protocol'] = firstLine. split ()

Def conn_destnation (self ):
Url = urlparse. urlparse (self. headers ['path'])
Hostname = url [1]
Port = "80"
If hostname. find (':')> 0:
Addr, port = hostname. split (':')
Else:
Addr = hostname
Port = int (port)
Ip = socket. gethostbyname (addr)
Print ip, port
Self. destnation. connect (ip, port ))
Data = "% s \ r \ n" % (self. headers ['method'], self. headers ['path'], self. headers ['protocol'])
Self. destnation. send (data + self. request)
Print data + self. request


Def renderto (self ):
Readsocket = [self. destnation]
While True:
Data =''
(Rlist, wlist, elist) = select. select (readsocket, [], [], 3)
If rlist:
Data = rlist [0]. recv (BUFLEN)
If len (data)> 0:
Self. source. send (data)
Else:
Break
Def run (self ):
Self. get_headers ()
Self. conn_destnation ()
Self. renderto ()

 

Class Server (object ):

Def _ init _ (self, host, port, handler = Proxy ):
Self. host = host
Self. port = port
Self. server = socket. socket (socket. AF_INET, socket. SOCK_STREAM)
Self. server. setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1)
Self. server. bind (host, port ))
Self. server. listen (5)
Self. handler = handler

Def start (self ):
While True:
Try:
Conn, addr = self. server. accept ()
Thread. start_new_thread (self. handler, (conn, addr ))
Except t:
Pass


If _ name __= = '_ main __':
S = Server ('127. 0.0.1 ', 127)
S. start ()
In fact, the Http Proxy server itself is not difficult, but it still takes a lot of trouble to write it out. Here we will not elaborate on the source code, it is very simple. I have encountered some problems.

 

I: I only knew that thread. the first parameter of start_new_thread is a function object. But when I saw the previous blog post, I felt a sigh of relief. This is also acceptable, so I quickly tested it:


[Python]
Import thread
 
Class Hello:
Def _ init _ (self, content ):
Print content
 
Def cs ():
Thread. start_new_thread (Hello, ("Hello World ",))
 
If _ name __= = '_ main __':
Cs ()

Import thread

Class Hello:
Def _ init _ (self, content ):
Print content

Def cs ():
Thread. start_new_thread (Hello, ("Hello World ",))

If _ name __= = '_ main __':
Cs ()

I was disappointed to find that an exception was reported.


[Python]
Unhandled exception in thread started
Error in sys. mongothook:
 
Original exception was:

Unhandled exception in thread started
Error in sys. mongothook:

Original exception was:
A look, I said, how can the first parameter be an object? I smiled and despised the author a little. So I went to bed, and the next day, I still don't give up, so I went down the code and tried it locally. Yes, I realized I was 2, so I immediately Baidu.

In the original thread module, if the main thread ends before the sub-thread, this exception will be thrown. Therefore, we must end the sub-thread first, the simplest way is to let the main thread sleep for a long enough time. As to how long it will take, it seems that I don't know. How can this problem be solved?

A better solution is that the main thread adds a lock to each sub-thread, the sub-thread releases the lock before the end, and the main thread continuously checks the lock status. The Code is as follows:


[Python]
Import thread
 
Class Hello:
Def _ init _ (self, content, lock ):
Print content
"""
Do something
....
At the end, release the lock
"""
Lock. release ()
 
Def cs ():
Lock = thread. allocate_lock ()
Lock. acquire ()
Thread. start_new_thread (Hello, ("Hello World", lock ))
While True:
If not lock. locked ():
Break
Print "lock release"
 
If _ name __= = '_ main __':
Cs ()

Import thread

Class Hello:
Def _ init _ (self, content, lock ):
Print content
"""
Do something
....
At the end, release the lock
"""
Lock. release ()

Def cs ():
Lock = thread. allocate_lock ()
Lock. acquire ()
Thread. start_new_thread (Hello, ("Hello World", lock ))
While True:
If not lock. locked ():
Break
Print "lock release"

If _ name __= = '_ main __':
Cs ()

The result is as follows: [python] view plaincopyprint? Hello World
Lock release

Hello World
Lock release

 

2. The second error is compared to 2.


[Python]
Self. source. send [data]
PeError: 'builtin _ function_or_method 'object is unsubscriptable

Self. source. send [data]
TypeError: 'builtin _ function_or_method 'object is unsubscriptable
I don't know the word unsubscriptable.

The main meaning is that built-in functions or methods cannot have subscripts. You know, the error is very good.

 


 

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.