Proxying HTTPS
Table of Contents
Rambling about making an HTTP proxy for debugging and security testing.
Networking
The first objective if you decide to make such a tool, is build a server that you can point your browser at and will forward messages to their destination, while recording the info.
First attempt
A basic HTTP proxy is trivial to write, if you aren't concerned with preserving the literal message, you can simply glue existing server and client together.
My first attempt I tried this using Hunchentoot as a server and Dexador as a client.
This is not a very good strategy, as it gives no guarantee that the message you send is the same as the one you recieved. These things might not be preserved, for example:
- Header order
- Whitespace
- Case
You will also have to do a lot of work to smooth out the differential between the server and client.
Second attempt
Create an HTTP reader and writer that preserves raw messages.
I used http for reading and writing HTTP messages, as well as providing a basic multithreaded TCP server. This works better for my intended goal but it is not easy to completely implement a reader for messages.
Issues arise when encodings are used (see Accept-Encoding header) as a normal char stream cannot handle everything it might recieve. I have yet to solve this but I believe the solution is to use a binary stream and the functions provided by chunga to read from it. For now I am working around this issue by stripping the `Accept-Encoding` header from requests before forwarding them.
Other issues I forsee will be the completeness of my HTTP reader when handling different types of messages where the body size is not determined by the normal `Content-Length` header.
Future attempt
If my second strategy doesn't work out, I will probably decide to modify existing HTTP libraries to preserve raw messages. fast-http by Fukamachi seems like a good candidate as long as I am comfortable with part of the program being in C.
Issues
I need to be able to handle SSL messages, since in practical use, almost every message is encrypted. This should not add much complexity to the program but I need to figure out how to properly handle the HTTP `Connect` method.
User interface
One of the biggest challenges of making a popular app is having a good UI. This is challenging because UI design seems to be a conflict between mass appeal and efficiency.
My preference
The optimal UI, (in my opinion), is Emacs-style, where every aspect of the program is introspectable and modifiable to the user. Commands are defined and then bound to keys for the user to invoke.
Popular preference
In contrast, most popular apps right now are QT/GTK/React apps where actions are done by clicking and navigating menus. I believe this is very slow and inefficient if you already know what you want to accomplish, but it is a good interface for exploring new things and being able to see some of what is available to use.
Comprimise
The solution to this conflict would be to build the program Emacs-style, and then create an optional facade to give users who want it a "clicky" interface.
First attempt
For now, I am going to write the UI as a Lem "plugin". Lem has all the functionality for Emacs-style interfaces built-in, and since it is an interactive Lisp program, I can run the proxy server directly in Lem.