Proxy Webserver in Python

0
7كيلو بايت

Socket programming in python is very user friendly as compared to c. The programmer need not worry about minute details regarding sockets. In python, the user has more chance of focusing on the application layer rather than the network layer. In this tutorial we would be developing a simple multi-threaded proxy server capable of handling HTTP traffic. It would be mostly based on the basic socket programming ideas. If you are not sure about the basics then i would recommend that you brush them up before going through this tutorial.

This is a naive implementation of a proxy server. We would be gradually developing it into a quite useful server in the upcoming tutorials.

To begin with, we would achieve the process in 3 easy steps

1. Creating an incoming socket We create a socket serverSocket in the __init__ method of the Server Class. This creates a socket for the incoming connections. We then bind the socket and then wait for the clients to connect.

def __init__(self, config):
    # Shutdown on Ctrl+C
    signal.signal(signal.SIGINT, self.shutdown) 

    # Create a TCP socket
    self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Re-use the socket
    self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # bind the socket to a public host, and a port   
    self.serverSocket.bind((config['HOST_NAME'], config['BIND_PORT']))
    
    self.serverSocket.listen(10) # become a server socket
    self.__clients = {}

2. Accept client and process This is the easiest yet the most important of all the steps. We wait for the client’s connection request and once a successful connection is made, we dispatch the request in a separate thread, making ourselves available for the next request. This allows us to handle multiple requests simultaneously which boosts the performance of the server multifold times.

while True:

    # Establish the connection
    (clientSocket, client_address) = self.serverSocket.accept() 
    
    d = threading.Thread(name=self._getClientName(client_address), 
    target = self.proxy_thread, args=(clientSocket, client_address))
    d.setDaemon(True)
    d.start()

3. Redirecting the traffic The main feature of a proxy server is to act as an intermediate between source and destination. Here, we would be fetching data from source and then pass it to the client.

  • First, we extract the URL from the received request data.
# get the request from browser
request = conn.recv(config['MAX_REQUEST_LEN']) 

# parse the first line
first_line = request.split('\n')[0]

# get url
url = first_line.split(' ')[1]
  • Then, we find the destination address of the request. Address is a tuple of (destination_ip_address, destination_port_no). We will be receiving data from this address.
http_pos = url.find("://") # find pos of ://
if (http_pos==-1):
    temp = url
else:
    temp = url[(http_pos+3):] # get the rest of url

port_pos = temp.find(":") # find the port pos (if any)

# find end of web server
webserver_pos = temp.find("/")
if webserver_pos == -1:
    webserver_pos = len(temp)

webserver = ""
port = -1
if (port_pos==-1 or webserver_pos < port_pos): 

    # default port 
    port = 80 
    webserver = temp[:webserver_pos] 

else: # specific port 
    port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1])
    webserver = temp[:port_pos] 
  • Now, we setup a new connection to the destination server (or remote server), and then send a copy of the original request to the server. The server will then respond with a response. All the response messages use the generic message format of RFC 822.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.settimeout(config['CONNECTION_TIMEOUT'])
s.connect((webserver, port))
s.sendall(request)
  • We then redirect the server’s response to the client. conn is the original connection to the client. The response may be bigger than MAX_REQUEST_LEN that we are receiving in one call, so, a null response marks the end of the response.
while 1:
    # receive data from web server
    data = s.recv(config['MAX_REQUEST_LEN'])

    if (len(data) > 0):
        conn.send(data) # send to browser/client
    else:
        break
البحث
الأقسام
إقرأ المزيد
История
Телохранитель. Yojimbo. (1961)
В некий японский городок приходит самурай. Самурай выглядит совершенно не по-самурайски: плохо...
بواسطة Nikolai Pokryshkin 2023-02-19 14:43:31 0 17كيلو بايت
Телевидение
6ТВ прямая трансляция, г. Горловка.
Телеканал «6ТВ» г. Горловка - первооткрыватель ТВ-пространства в Горловке. За годы...
بواسطة Nikolai Pokryshkin 2022-11-14 19:10:38 0 31كيلو بايت
Business
Marketing plan - types, development, examples
What is a marketing plan, what types does it include, how to develop and use it? In this article,...
بواسطة Dacey Rankins 2024-09-05 17:23:09 0 7كيلو بايت
Financial Services
How the AD/AS model incorporates growth, unemployment, and inflation
Key points The aggregate demand/aggregate supply, or AD/AS, model is one of the...
بواسطة Mark Lorenzo 2023-03-31 19:57:02 0 9كيلو بايت
Телевидение
Прямая трансляция телеканала Ю
«Ю» - молодёжный, женский телеканал. Любовь и романтические отношения, семейная жизнь...
بواسطة Nikolai Pokryshkin 2022-10-01 13:08:51 0 26كيلو بايت
image/svg+xml


BigMoney.VIP Powered by Hosting Pokrov