Http Web Proxy Server Python

What is an HTTP Web Proxy Server?

Before diving into the details of an HTTP web proxy server in Python, let’s understand what a proxy server is. A proxy server acts as an intermediary between a client and a server. It forwards client requests to the server and then returns the server’s response to the client.

An HTTP web proxy server specifically handles HTTP requests and responses. It can be used for various purposes, such as caching, filtering, logging, and security. In this article, we will explore how to create an HTTP web proxy server using Python.

Setting up the Environment

To begin with, make sure you have Python installed on your system. You can download and install the latest version of Python from the official website. Once Python is installed, you are ready to proceed with creating an HTTP web proxy server.

Open your favorite text editor or integrated development environment (IDE) and create a new Python file. Save it with a meaningful name, such as “proxy_server.py”. Now, let’s dive into the implementation details.

Importing Required Libraries

To create an HTTP web proxy server in Python, we need to import certain libraries. Two essential libraries for our task are socket and threading. The socket library provides low-level network communication capabilities, while the threading library allows us to handle multiple client connections concurrently.

Open your Python file and import the required libraries as follows:

import socket import threading

Defining Constants and Variables

Next, let’s define some constants and variables that we will use throughout the implementation. These include the IP address and port number of the proxy server, as well as the buffer size for receiving data.

Define the following constants and variables at the top of your Python file:

HOST ='localhost' PORT = 8080 BUFFER_SIZE = 4096

Creating a Socket

Now, let’s create a socket to listen for client connections. We will use the socket.socket() method to create a socket object. Then, we will bind it to the specified IP address and port number using the bind() method.

Add the following code to create and bind the socket:

def create_socket(): try: global HOST global PORT global BUFFER_SIZE # Create a socket object proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind the socket to the specified IP address and port number proxy_socket.bind((HOST, PORT)) # Listen for incoming client connections proxy_socket.listen(10) print(f"Proxy server started on {HOST}:{PORT}") # Accept client connections and handle them in separate threads while True: client_socket, client_address = proxy_socket.accept() # Start a new thread to handle the client connection threading.Thread(target=handle_client, args=(client_socket,)).start() except Exception as e: print(f"Error occurred: {str(e)}") proxy_socket.close()

Handling Client Connections

Now, let’s define the handle_client() function to handle client connections. This function will be executed in a separate thread for each client connection.

Add the following code to handle client connections:

def handle_client(client_socket): try: request_data = client_socket.recv(BUFFER_SIZE).decode() print(f"Received request:\n{request_data}") # Extract the requested URL from the request data requested_url = extract_url(request_data) # Check if the requested URL is blocked if is_blocked(requested_url): response_data ="HTTP/1.1 403 Forbidden\r\n\r\n" else: # Forward the request to the server and receive the response response_data = forward_request(request_data) # Send the response back to the client client_socket.sendall(response_data.encode()) client_socket.close() except Exception as e: print(f"Error occurred: {str(e)}") client_socket.close()

Extracting the Requested URL

Inside the handle_client() function, we need to extract the requested URL from the client’s request data. This can be done by parsing the request headers.

Add the following code to extract the requested URL:

def extract_url(request_data): lines = request_data.split('\r\n') first_line = lines[0] url = first_line.split(' ')[1] return url

Blocking Certain URLs

In some cases, you may want to block certain URLs from being accessed through the proxy server. To achieve this, you can maintain a list of blocked URLs and check if the requested URL is in the list.

Add the following code to define the is_blocked() function:

def is_blocked(url): blocked_urls = [ "example.com", "google.com", "facebook.com" ] return url in blocked_urls

Forwarding the Request

Now, let’s implement the forward_request() function to forward the client’s request to the server and receive the server’s response.

Add the following code to forward the request:

def forward_request(request_data): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.connect(('remote-server.com', 80)) server_socket.sendall(request_data.encode()) response_data = server_socket.recv(BUFFER_SIZE).decode() server_socket.close() return response_data

Starting the Proxy Server

Finally, let’s start the proxy server by calling the create_socket() function.

Add the following code at the bottom of your Python file:

if __name__ =='__main__': create_socket()

Conclusion

Congratulations! You have successfully implemented an HTTP web proxy server in Python. This proxy server can handle client connections, extract requested URLs, block certain URLs, and forward requests to the server. Feel free to explore further and add more functionality to enhance your proxy server.

Remember to test your proxy server thoroughly and ensure that it meets your specific requirements before deploying it in a production environment. Happy coding!