Skip to content

A single-threaded reverse proxy written in C, based on the reactor pattern using Linux's Epoll mechanism. Full asynchronous state handling, supports HTTPS and canonical name redirection for one host.

License

Notifications You must be signed in to change notification settings

navrajkalsi/proxy-c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Proxy-C

Proxy Demo

A single-threaded reverse proxy written in C, based on the reactor pattern using Linux's Epoll mechanism. Full asynchronous state handling, supports HTTPS and canonical name redirection for one host.


Motivation

So my last project was a web server, also made in C. After making it capable of hosting a real website I rented an AWS instance and tried to host my own website with it.

Long story short, just using running my server on port 80 and 443 was not enough. Google was refusing to index the HTTPS version of my website, even after telling it explicitly with meta tags. So I had to resort an Nginx proxy that redirected all traffic to the HTTPS version of the site.

This is where the idea for a reverse proxy originated, which was in some cases more complex and simpler than server-c.


Worth-Mentioning Points

  • Uses a single epoll() instance to monitor all the file descriptors in a true async manner.
  • Only supports a single upstream server.
  • A single upstream removes the need for calling the blocking getaddrinfo() function, after accepting.
  • Upstream info is loaded even before calling the first accept().
  • Canonical host for requests and upstream can be different.
  • Redirects with 301 code, incase canonical host does not match with request header.
  • Regex is used to validate the upstream host and host header of every request.
  • TLS is used to support HTTPS, done using openssl.
  • Timeouts are used for every individual I/O state.
  • A full connection timeout is also used for every connection regardless which state they are in.
  • Custom Error Page is served in case of any error, which changes dynamically based on the response status code.
  • Clean Shutdown is done by handling interrupt and kill signals.

Quick Start

THIS PROXY SERVER ONLY SUPPORTS LINUX SYSTEMS.

Install Dependencies

The following dependencies are required to build and run the program on Linux:

  • gcc: C Compiler
  • make: Project build
  • openssl: TLS handling & HTTPS support

If using a package manager, please check to see the exact names of these programs for your distro.

Download the source
git clone https://github.com/navrajkalsi/proxy-c
cd proxy-c
Build the project

Common Commands

# Building
make

# Installing the binary
make install

# Cleaning build objects
make clean

# Uninstall
make uninstall

Build Options

Variable Default Description
DEFAULT_PORT "1419" Listening port for client side connections.
DEFAULT_CANONCIAL_HOST "https://example.com" Canonical Host to match the value of Host header against.
DEFAULT_UPSTREAM DEFAULT_CANONICAL_HOST URL of the server to contact for response, if request is deemed valid.
DOMAIN_CERT "/etc/ssl/domain/domain.cert" Path to domain certificate for HTTPS.
PRIVATE_KEY "/etc/ssl/domain/private.key" Path to private key for HTTPS.

DOMAIN_CERT & PRIVATE_KEY CAN ONLY BE CHANGED DURING COMPILATION, i.e., during make, and not during runtime with flags.

Usage

If proxy-c command is not found after installation, the directory in which the binary got installed is not on the PATH. ADD THE MAKE INSTALLATION DIRECTORY TO THE PATH AND TRY AGAIN.


Flags

The following flags can be used to alter the behaviour of the program:

Flag Flag Description Required Argument Default
-a Accept Incoming Connections from all IPs. Localhost only
-c Canonical Host to redirect to. Host origin string DEFAULT_CANONICAL_HOST
-h Print usage on command line.
-p Port to listen on. Port number DEFAULT_PORT
-s Use HTTPS for client side. HTTP only
-S Use HTTPS for server side. HTTP only
-u Server URL to contact for response. Upstream origin string DEFAULT_UPSTREAM
-v Print version number.
-w Print all warnings as errors. Warnings are not printed

Default Usage

proxy-c

By default:

  • Loads address information for DEFAULT_UPSTREAM.
  • Starts listening for clients on DEFAULT_PORT.
  • Listens to only localhost requests.
  • Uses HTTP only for client side operations.
  • Matches the host header of each request against DEFAULT_CANONICAL_HOST.
  • Uses HTTP only for server side operations.

Additional Usage Example

proxy-c -a -c localhost:8080 -p 8080 -S -u https://example.com
  • Loads address information for https://example.com.
  • Starts listening for clients on port 8080.
  • Listens to request from all IPs.
  • Uses HTTP only for client side operations.
  • Matches the host header of each request against localhost:8080.
  • Uses HTTPS only for server side operations.

Demo

Proxy Demo

About

A single-threaded reverse proxy written in C, based on the reactor pattern using Linux's Epoll mechanism. Full asynchronous state handling, supports HTTPS and canonical name redirection for one host.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published