http-server/hyper-src/projects/http-server.html
2024-04-28 18:19:41 -05:00

63 lines
2.8 KiB
HTML

<Container>
<header class="header">
<h1> Rust HTTP Server <GithubIcon href="https://github.com/Xterminate1818/server"/></h1>
<h2> Keywords: Back End - TCP - SSL </h2>
</header>
<div class="content">
<h2 class="distinct"> Motivation </h2>
As a systems programmer, I want to understand the technologies
I use at a very low level. Modern web stacks abstract away the
process of handling TCP connections, serving SSL certificates,
and parsing HTTP requests. The best way to understand a technology
is to implement it from the ground up, I studied the HTTP 1.1
specification and wrote a server to host my website.
<h2 class="distinct"> Approach </h2>
At the most basic level, the server will translate the request URL
into a local file path, and respond with the file matching that path
if it exists. Request URLs are sanitized to prevent accessing files
outside of the server's directory. Two tables are used for rewriting
and routing URLs. This makes handling URLs predictable and robust.
<@code lang="rust">
// Snippet from the request handling code
pub async fn construct_response(&self, request_url: &str) -> Response {
let sanitized_url = rewrite_url(request_url);
if sanitized_url != request_url {
return Self::redirect(&sanitized_url);
}
let routed_url = self.perform_routing(&sanitized_url).await;
if let Some(response) =
self.perform_redirecting(&routed_url).await {
return response;
}
match self.get_resource(&routed_url).await {
Some(bytes) => Response::from_data(bytes),
None => Self::not_found(),
}
}
</@code>
I use Cloudflare to manage my domain name, DNS records, and SSL certificates.
Cloudflare automatically caches resources, rewrites HTTP requests to HTTPS,
and limits request sizes. This allows my server to only listen on port 443
and neglect caching server-side.
<h2 class="distinct"> Dependencies </h2>
My goal with this project was to provide a functional server using as few
libraries as possible. The final project directly depends on four crates:
<@code lang=toml>
// Snippet from Cargo.toml
[dependencies]
log = "0.4"
log4rs = "1.3"
tiny_http = "0.12"
tokio = {version = "1", features = ["full"]}
</@code>
The first two crates, log and log4rs, provide logging functions which aren't critical to the
server's functionality. The tiny_http crate provides a simple wrapper for the standard
library TCP stream, and performs SSL encryption. It is used as the backbone
for many Rust web frameworks. While I could implement these features myself, I
decided against it for security and browser compatibility reasons. Finally there is
tokio, an async runtime. This is necessary because Rust does not provide a runtime
by default, and building one is out of scope.
</div>
</Container>