Concurrent HTTP Web Proxy

Apr 29, 2022

Creating the Proxy

My first task was to implement the core functionality of the proxy. To do this, I needed to create a server that listened to incoming requests and parsed the URI. Once parsed, the proxy would forward the request to the appropriate server and return the response to the client.

Doing this in C allowed me to have full control over memory management, ultimately improving the performance of the proxy.

Handling Concurrent Connections

My proxy was functional, but it had a glaring issue: it was single-threaded, lacking the ability to service multiple clients simultaneously. To tackle this problem, I introduced multithreading, allowing my proxy to be more concurrent and resilient.

Mutexes and Semaphores

Once I'd implemented multithreading, I needed to ensure that the shared resources of the proxy were accessed in a thread-safe manner. This is where mutexes and semaphores came in.

I used mutexes to lock and unlock shared resources, guaranteeing that only one thread could access a resource at a time. Semaphores, on the other hand, allowed me to limit the number of threads competing for a limited set of resources, making the entire system more efficient.

By combining mutexes, semaphores, and preemptive multithreading, my proxy was well-equipped to handle numerous requests concurrently - a significant upgrade from its single-threaded roots.

Testing

After implementing my HTTP proxy, I needed to test its capabilities. I used HTTP clients like Postman and browser-based clients to see if my proxy was forwarding requests correctly. I also tested it with telnet and OpenSSL command-line tools to check how it dealt with SSL/TLS connections, ensuring that it could handle secure connections.

The Result

In the end, I successfully developed a fully-functional, concurrent HTTP web proxy, capable of handling multiple requests in parallel. It was an educational and fulfilling experience. By building this proxy from scratch and in C, I gained a deeper understanding of internet protocols (HTTP, HTTPS, SSL), synchronization mechanisms (mutexes, semaphores), and preemptive multithreading.