Project Update Report
My original project and goals involved creating a reverse proxy with the various features that I explain in more detail below. I aimed to deepen my knowledge of this aspect of production web systems at a lower level, focusing on testing and correctness rather than application features.
So far, I haven’t had to make changes to my original goals, and I’d say I’ve made an appropriate amount of progress for the current point in the semester. Looking at the number of goals I have done and those that I have left, I’m right on track if not slightly ahead. However, some of the later goals may end up being more significant than the ones I’ve already achieved, so I’ll need to keep planning thoughtfully. Moving forward, I plan to maintain my pace and finish the semester strong.
More specifically, my original goals, my progress on them, and my plans are as follows:
Core goals
Testing, code quality, and documentation
- Test coverage of all of the project’s functionality
- At the current moment, technically this is not achieved. However, I’m generally taking my intended approach of testing as I go instead of writing all the logic and then testing it all after the fact. I see no problem with continuing to take this approach moving forward. Whether or not this goal is achieved can really only be determined at the end of the project, but I’m definitely on track.
- Strict linting (using Clippy) completely forbidding
unwrap, expect, and unsafe (and not producing any other warnings)
- I’ve been achieving this so far and see no problem continuing. I included this in the goals for clarity and completeness, but I’d be doing it anyway.
- User-friendly documentation in both English and Japanese
- I haven’t done this. While documenting as I go might be theoretically the best practice, I think with the scale and trajectory of this project, doing so would end up being a lot more work total and take time away from the core concepts. Therefore, I will just need to leave some time for this goal at the end.
Features
- TCP listener (start with simple forwarding to/from a single backend)
- Header manipulation (e.g.
X-Forwarded-For, Connection)
- Concurrent client connections (spawning tasks, potentially shared state and/or message passing)
- This is technically done at this point, but it will get more complicated as I add on other features.
- Lifecycle management (graceful shutdown, timeouts, etc.)
- Almost done. This is what I’m currently working on.
- Routing to multiple backends (start with simple prefix matching)
- Not done. This is up next.
- Load balancing (start with simple round robin)
- Health checks (i.e. recognizing and handling unhealthy backends)
- Logging (use the
tracing crate)
- Done. I will continue to use this more as I implement other features, but doing so will not add any significant complexity or time.
- TOML configuration file (addresses, paths, timeouts, etc.)
- Done. Similar to logging, I will use it more moving forward, but the basics are set up, so it will simply be a matter of adding on to the existing struct whenever I need a new config value.
If time allows
None of these are done, but that’s fine because they are “if time allows” goals. I’ll do them at the end if there’s time, but I plan to stay focused on the core goals above.
- TLS termination (encrypted client connections)
- TLS re-encryption (encrypted backend connections)
- Live reloading of the config file
- Multiple load balancing algorithms
- Metrics
- Rate/connection limiting
In terms of my overall reflection on the project, implementing a reverse proxy myself is seeming to be less practically applicable than I expected. I doubt I will write this kind of code in a job. Nevertheless, I’m encountering interesting concepts and building up general abilities and knowledge that I think will end up being relevant later on.