├── LICENSE ├── README.md ├── proxy.py └── proxy3.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012 Luu Gia Thuy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Web Proxy by Python 2 | ===================== 3 | 4 | A simple web proxy written in Python 5 | 6 | ##Usage 7 | run 8 | ``` 9 | python proxy.py 9876 10 | ``` 11 | where 9876 is the port number of the proxy. 12 | 13 | More details on my blog: http://luugiathuy.com/2011/03/simple-web-proxy-python/ 14 | 15 | ##Contact 16 | [@luugiathuy](http://twitter.com/luugiathuy) 17 | -------------------------------------------------------------------------------- /proxy.py: -------------------------------------------------------------------------------- 1 | #**************************************************** 2 | # * 3 | # HTTP PROXY * 4 | # Version: 1.0 * 5 | # Author: Luu Gia Thuy * 6 | # * 7 | #**************************************************** 8 | 9 | import os,sys,thread,socket 10 | 11 | #********* CONSTANT VARIABLES ********* 12 | BACKLOG = 50 # how many pending connections queue will hold 13 | MAX_DATA_RECV = 999999 # max number of bytes we receive at once 14 | DEBUG = True # set to True to see the debug msgs 15 | BLOCKED = [] # just an example. Remove with [""] for no blocking at all. 16 | 17 | #************************************** 18 | #********* MAIN PROGRAM *************** 19 | #************************************** 20 | def main(): 21 | 22 | # check the length of command running 23 | if (len(sys.argv)<2): 24 | print "No port given, using :8080 (http-alt)" 25 | port = 8080 26 | else: 27 | port = int(sys.argv[1]) # port from argument 28 | 29 | # host and port info. 30 | host = '' # blank for localhost 31 | 32 | print "Proxy Server Running on ",host,":",port 33 | 34 | try: 35 | # create a socket 36 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 37 | 38 | # associate the socket to host and port 39 | s.bind((host, port)) 40 | 41 | # listenning 42 | s.listen(BACKLOG) 43 | 44 | except socket.error, (value, message): 45 | if s: 46 | s.close() 47 | print "Could not open socket:", message 48 | sys.exit(1) 49 | 50 | # get the connection from client 51 | while 1: 52 | conn, client_addr = s.accept() 53 | 54 | # create a thread to handle request 55 | thread.start_new_thread(proxy_thread, (conn, client_addr)) 56 | 57 | s.close() 58 | #************** END MAIN PROGRAM *************** 59 | 60 | def printout(type,request,address): 61 | if "Block" in type or "Blacklist" in type: 62 | colornum = 91 63 | elif "Request" in type: 64 | colornum = 92 65 | elif "Reset" in type: 66 | colornum = 93 67 | 68 | print "\033[",colornum,"m",address[0],"\t",type,"\t",request,"\033[0m" 69 | 70 | #******************************************* 71 | #********* PROXY_THREAD FUNC *************** 72 | # A thread to handle request from browser 73 | #******************************************* 74 | def proxy_thread(conn, client_addr): 75 | 76 | # get the request from browser 77 | request = conn.recv(MAX_DATA_RECV) 78 | 79 | # parse the first line 80 | first_line = request.split('\n')[0] 81 | 82 | # get url 83 | url = first_line.split(' ')[1] 84 | 85 | for i in range(0,len(BLOCKED)): 86 | if BLOCKED[i] in url: 87 | printout("Blacklisted",first_line,client_addr) 88 | conn.close() 89 | sys.exit(1) 90 | 91 | 92 | printout("Request",first_line,client_addr) 93 | # print "URL:",url 94 | # print 95 | 96 | # find the webserver and port 97 | http_pos = url.find("://") # find pos of :// 98 | if (http_pos==-1): 99 | temp = url 100 | else: 101 | temp = url[(http_pos+3):] # get the rest of url 102 | 103 | port_pos = temp.find(":") # find the port pos (if any) 104 | 105 | # find end of web server 106 | webserver_pos = temp.find("/") 107 | if webserver_pos == -1: 108 | webserver_pos = len(temp) 109 | 110 | webserver = "" 111 | port = -1 112 | if (port_pos==-1 or webserver_pos < port_pos): # default port 113 | port = 80 114 | webserver = temp[:webserver_pos] 115 | else: # specific port 116 | port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1]) 117 | webserver = temp[:port_pos] 118 | 119 | try: 120 | # create a socket to connect to the web server 121 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 122 | s.connect((webserver, port)) 123 | s.send(request) # send request to webserver 124 | 125 | while 1: 126 | # receive data from web server 127 | data = s.recv(MAX_DATA_RECV) 128 | 129 | if (len(data) > 0): 130 | # send to browser 131 | conn.send(data) 132 | else: 133 | break 134 | s.close() 135 | conn.close() 136 | except socket.error, (value, message): 137 | if s: 138 | s.close() 139 | if conn: 140 | conn.close() 141 | printout("Peer Reset",first_line,client_addr) 142 | sys.exit(1) 143 | #********** END PROXY_THREAD *********** 144 | 145 | if __name__ == '__main__': 146 | main() 147 | 148 | 149 | -------------------------------------------------------------------------------- /proxy3.py: -------------------------------------------------------------------------------- 1 | #**************************************************** 2 | # * 3 | # HTTP PROXY * 4 | # Version: 1.0 * 5 | # Author: Luu Gia Thuy * 6 | # * 7 | #**************************************************** 8 | 9 | import os,sys,socket,time 10 | import _thread as thread 11 | 12 | #********* CONSTANT VARIABLES ********* 13 | BACKLOG = 50 # how many pending connections queue will hold 14 | MAX_DATA_RECV = 999999 # max number of bytes we receive at once 15 | DEBUG = True # set to True to see the debug msgs 16 | BLOCKED = [] # just an example. Remove with [""] for no blocking at all. 17 | 18 | #************************************** 19 | #********* MAIN PROGRAM *************** 20 | #************************************** 21 | def main(): 22 | 23 | # check the length of command running 24 | if (len(sys.argv)<2): 25 | print ("No port given, using :8080 (http-alt)") 26 | port = 8080 27 | else: 28 | port = int(sys.argv[1]) # port from argument 29 | 30 | # host and port info. 31 | host = '' # blank for localhost 32 | 33 | print ("Proxy Server Running on ",host,":",port) 34 | 35 | try: 36 | # create a socket 37 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 38 | 39 | # associate the socket to host and port 40 | s.bind((host, port)) 41 | 42 | # listenning 43 | s.listen(BACKLOG) 44 | 45 | except (socket.error, (value, message)): 46 | if s: 47 | s.close() 48 | print ("Could not open socket:", message) 49 | sys.exit(1) 50 | 51 | # get the connection from client 52 | while 1: 53 | conn, client_addr = s.accept() 54 | 55 | # create a thread to handle request 56 | thread.start_new_thread(proxy_thread, (conn, client_addr)) 57 | 58 | s.close() 59 | #************** END MAIN PROGRAM *************** 60 | 61 | def printout(type,request,address): 62 | if "Block" in type or "Blacklist" in type: 63 | colornum = 91 64 | elif "Request" in type: 65 | colornum = 92 66 | elif "Reset" in type: 67 | colornum = 93 68 | 69 | print ("\033[",colornum,"m",address[0],"\t",type,"\t",request,"\033[0m") 70 | 71 | #******************************************* 72 | #********* PROXY_THREAD FUNC *************** 73 | # A thread to handle request from browser 74 | #******************************************* 75 | def proxy_thread(conn, client_addr): 76 | 77 | # get the request from browser 78 | request = conn.recv(MAX_DATA_RECV) 79 | 80 | # parse the first line 81 | first_line = request.split(b'\n')[0] 82 | 83 | # get url 84 | url = first_line.split(b' ')[1] 85 | 86 | for i in range(0,len(BLOCKED)): 87 | if BLOCKED[i] in url: 88 | printout("Blacklisted",first_line,client_addr) 89 | conn.close() 90 | sys.exit(1) 91 | 92 | 93 | printout("Request",first_line,client_addr) 94 | # print "URL:",url 95 | # print 96 | 97 | # find the webserver and port 98 | http_pos = url.find(b'://') # find pos of :// 99 | if (http_pos==-1): 100 | temp = url 101 | else: 102 | temp = url[(http_pos+3):] # get the rest of url 103 | 104 | port_pos = temp.find(b':') # find the port pos (if any) 105 | 106 | # find end of web server 107 | webserver_pos = temp.find(b'/') 108 | if webserver_pos == -1: 109 | webserver_pos = len(temp) 110 | 111 | webserver = "" 112 | port = -1 113 | if (port_pos==-1 or webserver_pos < port_pos): # default port 114 | port = 80 115 | webserver = temp[:webserver_pos] 116 | else: # specific port 117 | port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1]) 118 | webserver = temp[:port_pos] 119 | 120 | try: 121 | # create a socket to connect to the web server 122 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 123 | s.connect((webserver, port)) 124 | s.send(request) # send request to webserver 125 | 126 | while 1: 127 | # receive data from web server 128 | data = s.recv(MAX_DATA_RECV) 129 | 130 | if (len(data) > 0): 131 | # send to browser 132 | conn.send(data) 133 | else: 134 | break 135 | s.close() 136 | conn.close() 137 | except (socket.error): 138 | if s: 139 | s.close() 140 | if conn: 141 | conn.close() 142 | printout("Peer Reset",first_line,client_addr) 143 | sys.exit(1) 144 | #********** END PROXY_THREAD *********** 145 | 146 | if __name__ == '__main__': 147 | main() 148 | 149 | 150 | --------------------------------------------------------------------------------