Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- import time
- import socket
- import sys
- import select
- import threading
- import zlib,gzip
- #
- # manual input for necessary options/args
- #
- max_conn=200
- buffer_size=4096
- delay=0.001
- #
- try:
- port=input('Enter port to listen: ')
- except KeyboardInterrupt:
- print("User Interrupted the process execution")
- sys.exit(0)
- ##
- # data forward class
- ##
- class Forward:
- def __init__(self):
- self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- #self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- ##
- # function for forwarding connections to it's desired target
- ##
- def forward(self,clientsock,clientdata,clientaddr):
- try:
- data=clientdata.decode('utf-8')
- #print("Data: ",data)
- first_line=clientdata.split('\n')[0]
- url=first_line.split(' ')[1]
- #print("url: ",url)
- http_pos=url.find("://")# finding positonn of http tag
- #print("http_pos",http_pos)#########
- if (http_pos==-1):
- temp=url
- else:
- temp =url[(http_pos+3):]# concating rest url
- #print("temp",temp)
- port_pos=temp.find(':')# find the position of posrt if any
- webserver_pos=temp.find("/")#end of web server
- #print("port_pos",port_pos,"webserver_pos",webserver_pos)
- if webserver_pos== -1:
- webserver_pos=len(temp)-(len(temp)-port_pos)
- #webserver_pos=""
- port=temp[port_pos+1:]
- else:
- port= -1
- #print("port_pos1",port_pos,"webserver_pos1",webserver_pos,"port: ",port)
- if (port == -1 or webserver_pos<port_pos):
- port=80
- webserver=temp[:webserver_pos]
- # print("Web and port 1 : ",webserver,port)
- else:
- #specific port
- #port=int((temp[(port_pos+1):])[:(webserver-port_pos-1)])
- webserver=temp[:port_pos]
- data=bytes(data.encode('utf-8'))
- #print("Webserver and port : ",webserver,port)
- #print("Web and port 3 : ",webserver,port)
- #
- #
- try:
- print("webserver: ",webserver," Port: ",port)
- port=int(float(port))
- self.s.connect((webserver,port))
- print("client: %s and frwd data to: %s "%(clientaddr,webserver),self.s.getpeername())
- #print(self.s.getpeername())
- #print("connected Sucessfully server:port ",webserver,port)
- #clientdata=self.s.recv(4096)
- self.s.sendall(clientdata)
- return self.s
- except Exception, e:
- print (e,"Error in frwding request to target server/client")
- #
- #
- except Exception as e:
- print("\nException in connection_string\n")
- print(e,'\n')
- ##
- #
- # preparing proxy server class and it's methods
- #
- ##
- class proxy_server:
- current_input_list=[]
- active_channels={}
- client_sockobj_addr={}
- #
- # Prepared server socket for listening connections
- #
- def __init__(self, host, 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(max_conn)
- ##
- # decompressing func for content
- ##
- def decompress(self,compressed_data):
- return zlib.decompress(compressed_data, -15)
- ##
- # Defining continous loop for detecting
- # new clients and requests to proxy server.
- ##
- def loop(self):
- self.current_input_list.append(self.server) # server socket appended as initial
- count_on_rcv =0
- count_on_accept=0
- count_on_disconnect=0
- while True:
- time.sleep(delay)
- ss=select.select
- inputready, outputready, exceptready = ss(self.current_input_list, [], [])
- for self.s in inputready: # it's a new connection or client
- #self.data = self.s.recv(buffer_size).decode('utf-8')
- if self.s == self.server:
- #self.on_accept()
- count_on_accept+=1
- #print
- #print("*"*50)
- print
- print("# on_accept ",count_on_accept)
- t_accept=threading.Thread(target=self.on_accept)
- t_accept.start()
- t_accept.join()
- break
- self.data = self.recv_timeout(self.s)
- if not self.data:
- break
- #
- # disconnects if recv data is 0 Bytes
- #
- if len(self.data) == 0:
- #self.on_close()
- count_on_disconnect+=1
- print
- print("# on_close ",count_on_disconnect)
- t_disconnect=threading.Thread(target=self.on_close)
- t_disconnect.start()
- t_disconnect.join()
- #print
- #print("*"*50)
- print
- break
- else: # Recieve data fron end side
- #self.on_recv()
- count_on_rcv+=1
- print
- print("# on_rcv ",count_on_rcv)
- t_recv=threading.Thread(target=self.on_recv)
- t_recv.start()
- t_recv.join()
- ##
- # DEFINING FUNCTION BLOCKS on_accept(), on_close(), and on_recieve()
- ##
- def on_accept(self):
- clientsock, clientaddr = self.server.accept()
- clientdata = self.recv_timeout(clientsock)
- print clientdata.decode('utf-8')
- #clientdata=clientsock.recv(buffer_size).decode('utf-8')
- #
- # client sock is current socket state for specific client
- # client addr is like complete socket addr (127.0.0.1, 47523)
- #
- #print(clientsock,clientaddr)
- #t_frwd=threading.Thread(target=Forward().forward,args=(clientsock,clientdata,clientaddr))
- #t_frwd.start()
- #forward=t_frwd.join()
- forward = Forward().forward(clientsock,clientdata,clientaddr)
- if forward:
- print clientaddr, "has connected (on_accept)"
- #print("forward",forward)
- self.current_input_list.append(clientsock)
- self.current_input_list.append(forward)
- self.active_channels[clientsock] = forward
- self.active_channels[forward] = clientsock
- else:
- print "Can't establish connection with remote server.(on_accept exception)",
- print "Closing connection with client side (on_accept exception)", clientaddr
- clientsock.close()
- def on_close(self):
- print self.s.getpeername(), " disconnected (on_close)"
- #remove objects from current_input_list
- self.current_input_list.remove(self.s)
- self.current_input_list.remove(self.active_channels[self.s])
- out = self.active_channels[self.s]
- # close the connection with client
- self.active_channels[out].close() # equivalent to do self.s.close()
- # close the connection with remote server
- self.active_channels[self.s].close()
- # delete both objects from channel dict
- del self.active_channels[out]
- del self.active_channels[self.s]
- def on_recv(self):
- print self.s.getpeername()," recieved data from here (on_recv)"
- data = self.data
- # here we can parse and/or modify the data before send forward
- print data
- self.active_channels[self.s].send(data)
- ##
- # data recieving function for complete data fetch from socket
- ##
- def recv_timeout(self,the_socket,timeout=0.1):
- #make socket non blocking
- the_socket.setblocking(0)
- #total data partwise in an array
- total_data=[];
- data='';
- #beginning time
- begin=time.time()
- while 1:
- #if you got some data, then break after timeout
- if total_data and time.time()-begin > timeout:
- break
- #if you got no data at all, wait a little longer, twice the timeout
- elif time.time()-begin > timeout*2:
- break
- #recv something
- try:
- data = the_socket.recv(buffer_size)
- if data:
- total_data.append(data)
- #change the beginning time for measurement
- begin = time.time()
- else:
- #sleep for sometime to indicate a gap
- time.sleep(0.1)
- except:
- pass
- #join all parts to make final string
- #Send notification to proxy server#
- data_recieved=float(len(str(''.join(total_data))))
- data_recieved=float(data_recieved/1024)
- data_recieved="%.3s"%str(data_recieved)
- data_size="%s KB "%(data_recieved)
- if data_recieved == "0.0":
- pass
- else:
- print("[+]%s Data Recieved. "%(str(data_size)))
- #
- total_data=''.join(total_data)
- #self.decompress(total_data)
- return total_data
- if __name__ == '__main__':
- server = proxy_server('0.0.0.0',port)
- try:
- server.loop()
- except KeyboardInterrupt:
- print "Ctrl C - Stopping server"
- sys.exit(1)
Add Comment
Please, Sign In to add comment