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

Overview

binserve ⚑ πŸ¦€

A blazingly fast static web server with routing, templating, and security in a single binary you can set up with zero code. πŸ”₯

UPDATE: Next version will be releasing soon with Automatic TLS (HTTPS), More speed, SEO features, and much more! πŸŽ‰

version GitHub license Twitter

Table of Contents


Features

  • Single binary with no dependencies and everything built-in.
  • Blazingly fast! ⚑ - it's built on top of Actix, one of the fastest web frameworks in the world and of course, written in Rust.
  • Everything in a single config file - everything you need to setup is in the binserve.json, just change it, run it!
  • Epic Portability - just carry the binary around and all you have to change is the host and port in the binserve.json.
  • Easiest Routing - you just have to enter the route and the static file to respond in the binserve.json to add a route entry!
  • Handlebars template engine - renders every static file with Handlebars on the first run improving performance!
  • Template Variables in one place - that too in the one and only config file!
  • Secure by design - runs security validation checks on the first run and will only run the server once configuration is confirmed secure! (See Security)
  • Config & Static File Assistance - just running it will create the configuration file and the static directory boilerplate for you!
  • Supports Any Static Files - just give any static file of your choice to routes and response will match it's Content-Type.
  • Straightforward Directory Structure - static files falls under the static directory, you can even change that! And images, css, and js falls under the assets directory which should all be created for you in the first run itself!
  • Custom Error Page Support - you can design your own fancy error pages!
  • Actix Logging Middleware - Logging is powered directly from Actix.

Hello World!

Download the binary for your OS from Releases, then just run it:

$ binserve

That's it. Done! You should see the following output:

         _   _                         
        | |_|_|___ ___ ___ ___ _ _ ___ 
        | . | |   |_ -| -_|  _| | | -_|
        |___|_|_|_|___|___|_|  \_/|___| v0.1.0
    

Your server is up and running at http://example.com:80/

Here is how the directory structure will look like:

β”œβ”€β”€ binserve
β”œβ”€β”€ binserve.json
β”œβ”€β”€ rendered_templates
β”‚   β”œβ”€β”€ 404.html
β”‚   └── index.html
└── static
    β”œβ”€β”€ 404.html
    β”œβ”€β”€ assets
    β”‚   β”œβ”€β”€ css
    β”‚   β”œβ”€β”€ images
    β”‚   └── js
    └── index.html

βš™οΈ Configuration File:

πŸ“„ File: binserve.json

{
  "directory_listing": false,
  "enable_logging": true,
  "error_pages": {
    "404": "404.html"
  },
  "follow_symlinks": false,
  "routes": {
    "/": "index.html",
    "/example": "example.html"
  },
  "server": {
    "host": "127.0.0.1",
    "port": 1337
  },
  "static_directory": "static",
  "template_variables": {
    "load_static": "/static/",
    "name": "Binserve"
  }
}

The whole thing revolves around this configuration file, whatever changes you want to make, just edit the config and run it!

🎨 Templates:

binserve uses Handlebars as the template engine as it perfectly fits our use case.

Here is an example:

<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <h1>My name is {{name}}</h1>
    </body>
</html>

Now add your name in the config file (binserve.json) as a template variable:

"template_variables": {
    "load_static": "/static/",
    "name": "Keanu Reeves"
}

Now run the server!

$ binserve

This would render down to:

<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <h1>My name is Keanu Reeves</h1>
    </body>
</html>

To load static files such as images, css, and javascript, just use {{load_static}}:

load_static is specified in the binserve.json itself.

<img src="{{load_static}}images/rick_roll.gif">
<link rel="stylesheet" href="{{load_static}}css/main.css">
<script src="{{load_static}}js/script.js">

binserve renders all your template at once on the first run itself to improve performance as it wouldn't have to render the template on each request.

Build From Source

For building binserve from source, you need to have these tools installed

  • Git
  • Rust
  • Cargo (Automatically installed when installing Rust)
  • A C linker (Only for Linux, generally comes pre-installed)
$ git clone https://github.com/mufeedvh/binserve.git
$ cd binserve/
$ cargo build --release

The first command clones the binserve repository in your local machine. The next two commands changes into the binserve directory and builds it in release mode

Security

Security is one of the most crucial elements in a web server, binserve is secure by design. Here is how it's secure:

  • Routes are specified in the configuration file not directly accepted from the user.
  • Runs a check for Path Traversal attempts in routes in the configuration file on each run.
  • Runs a check for Symlink Files which might point to sensitive files on each run.
  • Only Follows Symlinks when explicitly allowed in the configuration file which is disabled by default.
  • Only enables Directory Listing when explicitly allowed in the configuration file which is disabled by default.

Contribution

Ways to contribute

  • Suggest a feature
  • Report a bug
  • Fix something and open a pull request
  • Help me document the code
  • Spread the word
  • Create an example with binserve and you will be featured here!

License

Licensed under the MIT License, see LICENSE for more information.

Liked the project?

Support the author by buying him a coffee!

Buy Me A Coffee


Support this project by starring ⭐ , sharing πŸ“² , and contributing πŸ‘©β€πŸ’» ! ❀️


Comments
  • Writing API docs

    Writing API docs

    As exploring through your project, I found that it does not have API documentation. It is very necessary, especially for new contributors that they are provided with it so it is easier for them. It is also helpful for people like us who sometimes need reference to a function or a struct

    It seems you haven't written binserve simultaneously writing code and docs, feel free to tell me if you need help while writing the docs

    documentation 
    opened by arijit79 5
  • Move the ASCII art to a separate file

    Move the ASCII art to a separate file

    I was inspecting your sources, The ASCII art didn't looked good in the middle of the source code. It would be better if you move it to a separate file or maybe make it a const. Also the line that tells about the host and port could be put along with the ASCII art. You should use the include_str! macro to include it into the source code during compilation and use it in the println! also specifying the host and port

    enhancement 
    opened by arijit79 5
  • Feature request: optional HTTPS support with automatically generated self-signed certificate

    Feature request: optional HTTPS support with automatically generated self-signed certificate

    Hi,

    I'd be much interested in having binserve provide HTTPS support with both automatically generated self-signed certificate or cert/key file as input.

    As far as I know it cannot be found within the Rust command-line tools. For instance, Miniserve has yet to implement it.

    Cheers, and thanks for your work and dedication !

    enhancement 
    opened by ngirard 4
  • Panic when a config file is incomplete

    Panic when a config file is incomplete

    When a config file is incomplete binserve should use secure defaults instead of panicing. When a config file is malformed there should be an understandable error message and an exit with a non-zero status code.

    Ran in alpine:latest container:

    # ./binserve-v0.1.0-x86_64-unknown-linux-musl
    thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/security.rs:109:47
    stack backtrace:
       0:           0x65daaa - std::backtrace_rs::backtrace::libunwind::trace::hf222ece681d618dd
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
       1:           0x65daaa - std::backtrace_rs::backtrace::trace_unsynchronized::h7bfcf0be2fa82989
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/../../backtrace/src/backtrace/mod.rs:66
       2:           0x65daaa - std::sys_common::backtrace::_print_fmt::h236d9b171ad18828
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:79
       3:           0x65daaa - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h4b36b828e94cdbaa
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:58
       4:           0x54eb3c - core::fmt::write::h0dd4368b249898df
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/fmt/mod.rs:1080
       5:           0x65d1b1 - std::io::Write::write_fmt::hc892ee261e6ddf46
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/io/mod.rs:1516
       6:           0x65cb9d - std::sys_common::backtrace::_print::h8b2bc12d86f6d6ce
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:61
       7:           0x65cb9d - std::sys_common::backtrace::print::ha0d71e055133e020
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:48
       8:           0x65cb9d - std::panicking::default_hook::{{closure}}::h1db1a3550f89322b
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:208
       9:           0x65c222 - std::panicking::default_hook::hfe146431cb18e73a
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:227
      10:           0x65c222 - std::panicking::rust_panic_with_hook::hef9392580f57df9b
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:577
      11:           0x65bf08 - std::panicking::begin_panic_handler::{{closure}}::hc22f01b65500c5e4
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:484
      12:           0x65bed4 - std::sys_common::backtrace::__rust_end_short_backtrace::h23c7f1d7574039e8
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:153
      13:           0x65be8d - rust_begin_unwind
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:483
      14:           0x54d360 - core::panicking::panic_fmt::h5f46bd9f58c47694
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/panicking.rs:85
      15:           0x54d17c - core::panicking::panic::hfc8a9856fb2eca80
                                   at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/panicking.rs:50
      16:           0x4130aa - binserve::binserve_init::hc5b7ef2db614b4b6
      17:           0x522db2 - std::thread::local::LocalKey<T>::with::h16e9249519e7350b
      18:           0x522ab6 - std::thread::local::LocalKey<T>::with::h14c0541cdbdc56bc
      19:           0x414810 - binserve::main::h5a440c368087745b
      20:           0x522943 - std::sys_common::backtrace::__rust_begin_short_backtrace::h413f99a6607c1379
      21:           0x415a58 - main
    Panic in Arbiter thread.
    

    Content of the config file:

    {}
    
    bug 
    opened by danmx 4
  • Emojis are not getting Rendered Properly

    Emojis are not getting Rendered Properly

    Hey, Unicoded Emojies like πŸ˜‹ πŸ“™ are not Getting Rendered Properly.

    Eg: If I edit my "template_variables" in binserve.json to

    "template_variables": { "load_static": "/static/", "name": "This is test πŸ˜‹" }

    The Index page get rendered as πŸ‘‡

    SS

    And I believe this is something that should be fixed! Right?

    OS:Windows 10 64Bit Binserve used : binserve-v0.1.0-x86_64-pc-windows-gnu.exe

    good first issue 
    opened by Tibinsunny 4
  • Support for handlebars partials

    Support for handlebars partials

    It would be great if we could define partials and reference them in our templates. Ideally, I'd like to define a single layout template with a content block which could be filled in by a number of other templates.

    I'd be happy to implement this if that would help, but I would like some guidance on how you'd like it integrated if I were to create a PR.

    Thanks for the awesome project BTW :100:

    enhancement 
    opened by dscottboggs 3
  • Add some CLI flags for typical config options

    Add some CLI flags for typical config options

    E.g., the port, whether to have dir listings, whether to follow symlinks, etc.

    Writing a config file is kind of overkill for firing up a throwaway HTTP server.

    PS: Adding some screenshots of the directory listings will also help adoption.

    enhancement 
    opened by NightMachinery 2
  • Feature: Handlebars partials

    Feature: Handlebars partials

    This PR implements handlebars partials, as well as an opinionated layout/content separation. Since there are so many changes, and unit tests are not implemented, I'm leaving it as a draft for now while I run it through its paces in a website I'm developing. I'll convert this to a finalized PR once I feel a little more confident it's ready to merge.

    Resolves #23. Closes #24, #25, #26.

    opened by dscottboggs 2
  • Add GitHub-Actions (GHA) CICD workflow

    Add GitHub-Actions (GHA) CICD workflow

    The PR adds a complete GHA CICD workflow:

    • includes multiple linux, macos, and windows platform builds (and testing if/when implemented)
    • includes automated packaging and publishing/deployment to GitHub Releases when commit is version tagged
    • includes Style testing (both cargo fmt and cargo clippy warnings); note: warnings add notations but don't break the workflow build
    • includes test for minimum rust supported version (aka, MinSRV, MSRV, MinRustV); easily removed if not desired
    • includes automatic CodeCov coverage reporting (if/when testing is included); also, easily removed if not desired

    I've been doing some initial experimentation with your project, and I wanted to contribute some automation that might be helpful to you going forward. This contributed workflow is a slightly modified form based on other GHA CICD workflows that I've designed (and are in current use) for uutils/coreutils, bootandy/dust, Peltoche/lsd, sharkdp/bat, sharkdp/pastel.

    I'm happy to make any changes that you would find useful as improvements.

    enhancement 
    opened by rivy 2
  • Unable to cargo build on MacOS

    Unable to cargo build on MacOS

    I'm unable to build the binary on my mac.

    Build:

    $ cargo build
        Updating crates.io index
     Downloading actix-web v3.0.2
    error: unable to get packages from source
    
    Caused by:
      failed to parse manifest at `/Users/xxx/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-3.0.2/Cargo.toml`
    
    Caused by:
      feature `rename-dependency` is required
    
    this Cargo does not support nightly features, but if you
    switch to nightly channel you can add
    `cargo-features = ["rename-dependency"]` to enable this feature
    

    System:

    $ uname -a
    Darwin xxx 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64
    

    Cargo version:

    $ cargo --version
    cargo 1.30.0 (a1a4ad372 2018-11-02)
    
    bug 
    opened by danmx 2
  • docker: add a minimalistic Dockerfile

    docker: add a minimalistic Dockerfile

    This pull request adds a minimalistic Dockerfile that contains only the binserve binary, a copy of glibc and other essential data files. This limits the attack surface to a minimum (the attacker can only compromise binserve at best and nothing more).

    Note that if you use this image, you won't be able to use docker exec to examine the running container (since no shell program is provided).

    This may fix #39.

    opened by liushuyu 1
  • Custom config location

    Custom config location

    Thanks for the project, it is really awesome!

    Right now, the configuration file is hardcoded to be read from the current directory. Sometimes it becomes necessary to run binserve from a directory which does not have a binserve.json. In this case, it would be great if we have the option to specify the location of the configuration file.

    enhancement 
    opened by IgnisDa 1
  • `TcpListener` should implement `SO_REUSEPORT`

    `TcpListener` should implement `SO_REUSEPORT`

    • https://lwn.net/Articles/542629/
    • Ref: https://github.com/actix/actix-web/issues/91
    • Ref: https://actix.rs/actix-web/actix_web/struct.HttpServer.html#method.listen
    enhancement 
    opened by mufeedvh 0
  • Implement rules for static files: custom index file & exclude specific files

    Implement rules for static files: custom index file & exclude specific files

    Currently index files are assumed to be files starting with index and ends with .html or .htm, this should be configurable. Along with that, there should be an option to exclude specific files from being served.

    enhancement 
    opened by mufeedvh 0
  • Write a dedicated documentation page (`DOCUMENTATION.md`)

    Write a dedicated documentation page (`DOCUMENTATION.md`)

    Every function in the configuration file should be documented in detail as to what it does and how it works, currently it's just a dump of the JSON file and doesn't go into detail on any of the options.

    A file called DOCUMENTATION.md should be created for this outside of the README.

    documentation 
    opened by mufeedvh 0
  • Configuration file should be taken as an argument

    Configuration file should be taken as an argument

    Currently for convenience, a configuration file is generated on the first run and is always consumed from the same working directory as the binary is executed. This implementation was to make project separation easier but comes with an overlooked issue where the executable file could/should be placed outside of a project directory.

    This is a tracking issue alongside #32 to implement override for every configuration functions.

    enhancement 
    opened by mufeedvh 0
Releases(v0.2.0)
Owner
Mufeed VH
18. web. open-source. browsers. kernel. security.
Mufeed VH
:zap: fast http framework for rust

zap ⚑ The mission of zap is, to deliver a basic, but fast rust web server library. Documentation About This code is based on tokio's minihttp project,

Daniel Oltmanns 51 Jun 7, 2022
VRS is a simple, minimal, free and open source static web server written in Rust

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.

null 36 Nov 8, 2022
Rust templating with Handlebars

handlebars-rust Handlebars templating language implemented in Rust and for Rust. Handlebars-rust is the template engine that renders the official Rust

Ning Sun 923 Dec 29, 2022
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 flexible web framework that promotes stability, safety, security and speed.

A flexible web framework that promotes stability, safety, security and speed. Features Stability focused. All releases target stable Rust. This will n

Gotham 2.1k Jan 3, 2023
Dynamic routing system for Rocket

rocket_router Dynamic routing system for Rocket Caveats Each file should export only one route, named the same as the file itself. After adding a new

David Arsene 1 Oct 27, 2021
An implementation of request routing via a singular grouped regex (with support for path parameter extraction).

rs-regex-router An implementation of request routing via a singular grouped regex (with support for path parameter extraction). Features Design approa

Harry 1 Nov 25, 2021
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
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
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
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
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
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
Web Server made with Rust - for learning purposes

Web Server made with Rust - for learning purposes

LΓ­lian 2 Apr 25, 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
Host These Things Please - a basic http server for hosting a folder fast and simply

http Host These Things Please - a basic HTTP server for hosting a folder fast and simply Selected features See the manpage for full list. Symlinks fol

thecoshman 367 Dec 23, 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
πŸš€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