VRS is a simple, minimal, free and open source static web server written in Rust

Overview

Vanilla RustLang Server (VRS)

Stock index page for VRS

VRS is a simple, minimal, free and open source static web server written in Rust which uses absolutely no dependencies and revolves around Rust's std::net built-in utility.

General Information

VRS features

  • Extremely lightweight binary after compiling due to its no dependency nature
  • Easy-to-understand documentation & manual
  • Multithreading (WIP)
  • Singlethreading
  • CORS (methods only, origins soon)
  • Dockerfiles (Debian & Alpine)
  • Customizable HTTP responses (200, 400 & 404)
  • Guarantee to compile on all platforms (recommended: Linux or BSD)
  • Easy customizability via its configuration file
  • Security headers out of the box (origin attacks, iframe attacks, clickjacking etc.)
  • HTTP/1.1 and HTTP/2 standard protocol versions (during development, it's recommended to use HTTP/1.1 because that's the only one Postman HTTP client supports.)
  • Basic systemd service
  • Logging (singlethread only.)

What is a static web server?

A static web server is a kind of web server which only serves static content. This includes HTML, CSS and JS. Static web servers do not have support for doing back-end business logic or interacting with databases out of the box.

Example use cases of VRS

  • A portfolio which is mostly HTML & CSS and a little bit of JS.
  • A small wikipedia.

Example use cases VRS is NOT suitable for

  • A blog site.
  • A social media website.
  • A bank system.
  • SpaceX clone.

License

VRS is licensed under the MIT License.

When to use VRS?

You may consider using this piece of software if you meet any of the following criteria:

  • You are looking for a simple static web server.
  • You do not like unnecessary bloat for simple stuff.
  • You are trying to repurpose ancient hardware and you do not want to wait for long compilation times.
  • You want to learn the basics of multithreading (spawning threads).

Installation

Read the docs to find out how to install and configure VRS (docs/ folder.)

Comments
  • Server allows path traversal

    Server allows path traversal

    Describe the bug vrs serves files that are outside /var/www/static by using .. in path. This allows potentially sensistive files to be read from the server, for example /etc/passwd

    To Reproduce

    > sudo ./setup.sh
    > cargo build
    > sudo ./target/debug/vrs &
    > echo "GET /../../../etc/passwd HTTP/1.1" | nc localhost 80
    HTTP/1.1 200 OK
    Content-Type: text/html
    Content-Length: 1322
    
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
    backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
    list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
    irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
    gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
    nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
    _apt:x:100:65534::/nonexistent:/usr/sbin/nologin
    vscode:x:1000:1000::/home/vscode:/bin/bash
    systemd-timesync:x:101:103:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
    systemd-network:x:102:104:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
    systemd-resolve:x:103:105:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
    messagebus:x:104:106::/nonexistent:/usr/sbin/nologin
    sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
    

    Expected behavior 404 or 400 error

    opened by tibordp 13
  • Various Test Improvements

    Various Test Improvements

    Type of pull request

    This PR makes changes to the test structure and introduces a basic fuzz test harness, as well as fixing a few panics that were tripped while writing the tests.

    Overview of pull request

    This PR follows through on the majority of https://github.com/PeterPierinakos/vanilla-rustlang-server/issues/5#issuecomment-1164972312. In particular, it moves the integration tests to become unit tests, completely removes the TestServer struct, adds a fuzz harness to detect panics that can be reached from outside, changes the hardcoded buffer sizes to be dynamically sized, and makes a few changes from what I assume to be the correct non-panicking behavior. In particular, I embedded the default media/ error pages into the binary, rather than simply panicking when they are not present- they are still possible to override (though there isn't a test case for that yet.) I decided to remove one of the existing test cases, because I don't think there's anything to do server-side for CORS checks, and I believe it would be easier to remove it than to reimplement the checks (another case where a future test would be good.) The base unit tests now cover roughly 65% of the codebase by the same metric as earlier, almost doubling previous coverage. As far as fuzzing, I ran it for roughly an hour with no crashes, and am currently reasonably confident that it is difficult for external requests to cause a panic at this point. I'm leaving this as separate commits right now to simplify reviewing it in parts, but would be happy to squash the changes into a single commit or multiple smaller commits if desired.

    Future possibilities

    I did not end up writing any integration tests for this PR. After making the changes I did, I think that going forward, the best course of action would be to move most of the server's unit tests back to being integration tests, but using a third party HTTP client over a socket rather than attempting to create a request by hand. The tests that remain as unit tests should be the ones that e.g. test an empty body and providing broken unicode. I've spent long enough not submitting this PR that I decided to leave it as is, but there are also some additional tests that would be good to write:

    • Check for specific headers (i.e. CORS)
    • Check that only the configured verbs are accepted
    • With a multithreaded server, send two requests, then read them in reverse order (the first shouldn't prevent the second from finishing) If desired, I can redo the hack in the server unit tests to use once_cell, or even just replace it with a static junk path (I don't think it's ever used, so it would be fine to hardcode it to "nonexistent").
    opened by zombiepigdragon 10
  • There should be a test suite for this program

    There should be a test suite for this program

    What is the feature you want to improve or implement? When looking running an informal audit of this codebase, I noticed there are zero test cases at all. Considering VRS attempts to parse (even a subset of) HTTP on its own, I find this extremely surprising. Ideally, there should be a decent range of request-response pairs, as well as some form of fuzzing to catch parsing errors.

    Additional information: As currently structured, I don't think the implementation of the server is particularly testable. It uses a hardcoded address+port (as well as requiring root/admin to run), and there is no other way for code to send the core of the server a request. Reorganizing the server to have some form of fn serve_request(configuration: Configuration, input: impl Read, output: impl Write) (note that this signature is infallible- errors should be written to the output here [HTTP status code] and/or a configured logger) would drastically increase the testability of the server and build confidence in its correctness.

    If a refactor that introduces these features occurs, I'm willing to help build a test suite to run on them.

    opened by zombiepigdragon 7
  • It's fairly easy to crash the server in single threaded mode

    It's fairly easy to crash the server in single threaded mode

    There is a lot of unwraps that should be ?s with error handling, ideally returning appropriate HTTP error status code in server response. The most egregious are unwraps on reading from socket, and on parsing utf8, both are trivially exploitable for DOS attacks:

    1. Open a connection, send no data, close connection: read will error, unwrap will panic, server will crash.
    2. Send a request with malformed (non-utf8 URI): from_utf8 will error, unwrap will panic, server will crash.

    Multi-threading is safer since panics only kill the thread they occur on, but they should still be avoided.

    opened by maciejhirsz 6
  • `.unwrap()`s and `.expect()`s should be replaced with proper error handling and `?`

    `.unwrap()`s and `.expect()`s should be replaced with proper error handling and `?`

    What is the feature you want to improve or implement? Error-handling in the codebase.

    Additional information: Currently, the project heavily relies on the excessive usage of unwraps in the main logic of the code. I believe that we could replace all possible panics in the server with more graceful errors and decrease the use of unwraps.

    I'm going to implement this change myself, submitting this issue in order to track the changes happening.

    opened by PeterPierinakos 3
  • Fix Clippy lints

    Fix Clippy lints

    This PR cleans up multiple Clippy lints that trigger on the current main branch. One of these lints in particular, clippy::unused_io_amount, can lead to transient errors that fail to write a complete response body and randomly. The remaining lints are for the most part stylistic choices that are considered idiomatic in the Rust world, and/or switching usage of owned types to borrowed types when the owned type isn't needed in function arguments (e.g. String -> &str).

    opened by zombiepigdragon 3
  • CORS origin blocking support

    CORS origin blocking support

    Is your feature request related to a problem? Please describe. No.

    Describe the solution you'd like Implement origin blocking via the Cors struct.

    Describe alternatives you've considered

    Additional context This feature request is open just in case if any new contributor would like to try and implement it. In the meantime, I just implemented an algorithm to find all the headers from a plain String in the utils directory and now I will read more about how CORS works.

    opened by PeterPierinakos 3
  • Built-in interpreter for markdown syntax to HTML

    Built-in interpreter for markdown syntax to HTML

    What is the feature you want to improve or implement?

    It would be nice to implement a way for the host to just be able to write their documents in markdown syntax and when an end user tries to access that document it gets interpreted into HTML before being sent to the browser.

    Additional information:

    I want to implement this because it's more convenient for some people to write documents in markdown than in HTML.

    The way this would work is, for example, the server host creates a helloworld.md file in /var/www/static and when a user tries to access http://localhost:80/helloworld.html the server finds a file with the same name but in the markdown extension (.md), it interprets it to HTML and then it sends back the HTML it generated.

    This could add some overhead on the server-side because in the worst case scenario the markdown document could be very large and hundreds of lines, so parsing and interpreting the document before sending it back could take a long time. In the future this could be improved by implementing caching for the documents, but this is only going to be considered if I decide that this idea is worth implementing into the final product.

    Would love to hear feedback for this idea from anyone passing by. This is probably going to be considered for v1.2.0.

    Improvement Feature Request 
    opened by PeterPierinakos 1
  • Make CI and tests a little more useful

    Make CI and tests a little more useful

    This PR adds running the Clippy checks to CI and changes the matches! invocations in the unit tests for assert_eq!, causing failing tests to automatically print the expected and received values. On my machine, both Clippy and tests fail, but I think it's worth the time to mark the failures in CI rather than only seeing them locally.

    opened by zombiepigdragon 1
  • Remove unwraps and expect

    Remove unwraps and expect

    Type of pull request

    Code enhancement

    Overview of pull request

    This PR will replace most .unwrap()s and .expect()s in the code with ? and introduce proper error handling by propagating the errors through the Server's methods and more.

    opened by PeterPierinakos 0
Releases(v1.3.0)
  • v1.3.0(Nov 17, 2022)

    This release is mostly to improve the codebase.

    Changelog:

    • Rewrote the entire codebase to use more procedural style instead of object-oriented.
    • Moved configuration docs to src/configuration.rs
    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Sep 18, 2022)

    Re-drafted due to a previous issue relating to code refactoring.

    Yet another stable release which adds a few new features.

    New features:

    • Add ability to format directory listings as either JSON (new) or HTML
    • Add a global state for the application which is passed through the server's core functions and the response's utilities
    • Add file caching (read documentation for configuration for more information)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Jul 27, 2022)

    Emergency patch update to fix some problems with the test suite.

    Changelog:

    • Fix errors in the requests test suite.
    • Refactor the entire source directory to make it easier to maintain.
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Jul 13, 2022)

    From now on, the releases on GitHub will follow the Semantic Versioning 2.0.0 for software version numbers incrementing (MAJOR.MINOR.PATCH).

    This stable release adds a few small features.

    Changelog:

    • Add "EXTRA_HEADERS" feature for headers you wish to append to the HTTP request's responses regardless of whether it errors or not (disabled by default).
    • Add "ALLOW_DIRECTORY_LISTING" in case for some reason the end user wishes to disable listing directories (folders) when a user tries to access something that is a directory (enabled by default).
    • Deprecate fuzz tests in favor of a possibly improved integrated testing suite for the web server (tests still exist.)
    • Documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Jun 30, 2022)

    (Redrafted for version number increment)

    Yet another stable release which adds some extra features for improved security and convenience. This is probably one of the last medium-large updates to VRS because most of the wanted features have been implemented.

    Changelog:

    • Finally add proper unit testing (thanks to https://github.com/PeterPierinakos/vanilla-rustlang-server/pull/8)
    • Add directory listing for when a user tries to access a directory inside the server instead of a file. It will basically list all files (and sub-directories) inside the requested directory.
    • Improve error-handling and propagate the errors throughout the Server.
    • Move cargo test to build Makefile's instruction instead of run.
    • Bug fixes.
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Jun 20, 2022)

    Emergency update because I forgot to push something to the main branch before release.

    Changelog:

    • Add MIME type support (HTML / CSS / JS)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Jun 20, 2022)

    After lots of rewriting and new features added, the first stable release of VRS is finally out!

    Changelog:

    • Proper multithreading has finally been added
    • Security headers for common attacks such as clickjacking added
    • Fixed many bugs from the old Beta releases
    • Improve performance by a few milliseconds
    • Rewrite server to use a structural pattern instead of pure functions in order to improve code reusability
    • Add ALLOWED_METHODS in order to block disallowed methods
    • Create a separate bin and lib
    • Improve some code comments
    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Jun 16, 2022)

    Third and possibly the last beta release of VRS. This release adds many new features and code improvements comparable to how the codebase previously looked.

    • Finally implemented Cross Origin Resource Sharing (CORS) support :)
    • Replaced many of the lines where it overused match statement and replaced them with the ? Rust operator
    • Remove the manual which used to be an HTML document in favor of a proper markdown documentation in the future
    • Finally fix the path traversal exploit once and for all (https://github.com/PeterPierinakos/vanilla-rustlang-server/issues/3, thanks mcronce)
    • Change many status codes in order to make them more appropriate
    • Overall improvements
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Jun 13, 2022)

    Second beta release of VRS! This one is mostly going to be to fix bugs and vulnerabilities.

    Changelog:

    • Fix a critical vulnerability regarding path traversal exploit which allowed getting access to any file outside of the static directory.
    • Fixed server crashing by panicing when socket connects by opening a connection and sending no data.

    Beta 3 will contain Cross Origin Resource Sharing (CORS) and origins.

    Source code(tar.gz)
    Source code(zip)
  • v1.0(Jun 12, 2022)

Owner
null
A blazingly fast static web server with routing, templating, and security in a single binary you can set up with zero code. :zap::crab:

binserve ⚡ ?? A blazingly fast static web server with routing, templating, and security in a single binary you can set up with zero code. ?? UPDATE: N

Mufeed VH 722 Dec 27, 2022
simple static file server written in Rust based on axum framework

static-server simple static file server written in Rust based on axum framework I'm learning Rust and axum. My thought is simple. axum has a static-fi

null 27 Jan 1, 2023
Live Server - Launch a local network server with live reload feature for static pages

Live Server - Launch a local network server with live reload feature for static pages

Lomirus 18 Nov 30, 2022
A fast, boilerplate free, web framework for Rust

Tower Web A web framework for Rust with a focus on removing boilerplate. API Documentation Tower Web is: Fast: Fully asynchronous, built on Tokio and

Carl Lerche 969 Dec 22, 2022
Simple and fast web server

see Overview Simple and fast web server as a single executable with no extra dependencies required. Features Built with Tokio and Hyper TLS encryption

null 174 Dec 9, 2022
Source Code for 'Practical Rust Web Projects' by Shing Lyu

Apress Source Code This repository accompanies Practical Rust Web Projects by Shing Lyu (Apress, 2021). Download the files as a zip using the green bu

Apress 44 Nov 17, 2022
Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

Actix Web Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust Features Supports HTTP/1.x and HTTP/2 Streaming and pipelining

Actix 16.3k Jan 8, 2023
Archibald is my attempt at learning Rust and writing a HTTP 1.1 web server.

Archibald To be a butler, is to be able to maintain an even-temper, at all times. One must have exceptional personal hygiene and look sharp and profes

Daniel Cuthbert 4 Jun 20, 2022
Salvo is a powerful and simplest web server framework in Rust world

Salvo is an extremely simple and powerful Rust web backend framework. Only basic Rust knowledge is required to develop backend services.

Salvo 1.2k Jan 5, 2023
🚀Memory safe, blazing fast, configurable, minimal hello world written in rust(🚀) in a few lines of code with few(1092🚀) dependencies🚀

?? hello-world.rs ?? ?? Memory safe, blazing fast, minimal and configurable hello world project written in the rust( ?? ) programming language ?? ?? W

mTvare 2.7k Jan 7, 2023
Operator is a web server. You provide a directory and Operator serves it over HTTP.

Operator Operator is a web server. You provide a directory and Operator serves it over HTTP. It serves static files the way you'd expect, but it can a

Matt Kantor 6 Jun 6, 2022
Web Server made with Rust - for learning purposes

Web Server made with Rust - for learning purposes

Lílian 2 Apr 25, 2022
web browser as a language server

web-browser-lsp A toy program that implements a text-based web browser as a language server. Motivation My favorite progrmming tools are neovim, tmux

octaltree 17 Nov 24, 2022
OxHTTP is a very simple synchronous HTTP client and server

OxHTTP is a very simple synchronous implementation of HTTP 1.1 in Rust. It provides both a client and a server.

Oxigraph 13 Nov 29, 2022
Simple http server in Rust (Windows/Mac/Linux)

How it looks like? Screenshot Command Line Arguments Simple HTTP(s) Server 0.6.1 USAGE: simple-http-server [FLAGS] [OPTIONS] [--] [root] FLAGS:

LinFeng Qian 788 Dec 28, 2022
Akasio is a simple HTTP server that redirects traffic based on a JSON redirect table. This is its Rust implementation.

This page is inaccurate and is pending updates. Akasio (Rust) Description Akasio is a simple HTTP server that redirects traffic based on a JSON redire

K4YT3X 5 May 2, 2022
A web application completely written in Rust. 🌍

WebApp.rs A web application completely written in Rust Target of this project is to write a complete web application including backend and frontend wi

Sascha Grunert 2.1k Dec 30, 2022
Create, share, fetch and model Atomic Data! This project consists of a graph database + server, a CLI and a rust library.

Create, share, fetch and model Atomic Data! This repo consists of three components: A library, a server and a CLI. atomic-server Status: Beta. Breakin

Joep Meindertsma 195 Dec 28, 2022
Sincere is a micro web framework for Rust(stable) based on hyper and multithreading

The project is no longer maintained! Sincere Sincere is a micro web framework for Rust(stable) based on hyper and multithreading. Style like koa. The

null 94 Oct 26, 2022