Giter Club home page Giter Club logo

miniserve's Introduction

miniserve - a CLI tool to serve files and dirs over HTTP

miniserve - a CLI tool to serve files and dirs over HTTP

CI Docker Hub Crates.io license Stars Downloads Lines of Code

For when you really just want to serve some files over HTTP right now!

miniserve is a small, self-contained cross-platform CLI tool that allows you to just grab the binary and serve some file(s) via HTTP. Sometimes this is just a more practical and quick way than doing things properly.

Screenshot

Screenshot

How to use

Serve a directory:

miniserve linux-distro-collection/

Serve a single file:

miniserve linux-distro.iso

Set a custom index file to serve instead of a file listing:

miniserve --index test.html

Serve an SPA (Single Page Application) so that non-existent paths are forwarded to the SPA's router instead

miniserve --spa --index index.html

Require username/password:

miniserve --auth joe:123 unreleased-linux-distros/

Require username/password as hash:

pw=$(echo -n "123" | sha256sum | cut -f 1 -d ' ')
miniserve --auth joe:sha256:$pw unreleased-linux-distros/

Require username/password from file (separate logins with new lines):

miniserve --auth-file auth.txt unreleased-linux-distros/

Generate random 6-hexdigit URL:

miniserve -i 192.168.0.1 --random-route /tmp
# Serving path /private/tmp at http://192.168.0.1/c789b6

Bind to multiple interfaces:

miniserve -i 192.168.0.1 -i 10.13.37.10 -i ::1 /tmp/myshare

Start with TLS:

miniserve --tls-cert my.cert --tls-key my.key /tmp/myshare

Upload a file using curl:

# in one terminal
miniserve -u -- .
# in another terminal
curl -F "path=@$FILE" http://localhost:8080/upload\?path\=/

(where $FILE is the path to the file. This uses miniserve's default port of 8080)

Note that for uploading, we have to use -- to disambiguate the argument to -u. This is because -u can also take a path (or multiple). If a path argument to -u is given, uploading will only be possible to the provided paths as opposed to every path.

Another effect of this is that you can't just combine flags like this -uv when -u is used. In this example, you'd need to use -u -v.

Create a directory using curl:

# in one terminal
miniserve --upload-files --mkdir .
# in another terminal
curl -F "mkdir=$DIR_NAME" http://localhost:8080/upload\?path=\/

(where $DIR_NAME is the name of the directory. This uses miniserve's default port of 8080.)

Take pictures and upload them from smartphones:

miniserve -u -m image -q

This uses the --media-type option, which sends a hint for the expected media type to the browser. Some mobile browsers like Firefox on Android will offer to open the camera app when seeing this.

Features

  • Easy to use
  • Just works: Correct MIME types handling out of the box
  • Single binary drop-in with no extra dependencies required
  • Authentication support with username and password (and hashed password)
  • Mega fast and highly parallel (thanks to Rust and Actix)
  • Folder download (compressed on the fly as .tar.gz or .zip)
  • File uploading
  • Directory creation
  • Pretty themes (with light and dark theme support)
  • Scan QR code for quick access
  • Shell completions
  • Sane and secure defaults
  • TLS (for supported architectures)
  • Supports README.md rendering like on GitHub
  • Range requests

Usage

For when you really just want to serve some files over HTTP right now!

Usage: miniserve [OPTIONS] [PATH]

Arguments:
  [PATH]
          Which path to serve

          [env: MINISERVE_PATH=]

Options:
  -v, --verbose
          Be verbose, includes emitting access logs

          [env: MINISERVE_VERBOSE=]

      --index <INDEX>
          The name of a directory index file to serve, like "index.html"

          Normally, when miniserve serves a directory, it creates a listing for that directory. However, if a directory
          contains this file, miniserve will serve that file instead.

          [env: MINISERVE_INDEX=]

      --spa
          Activate SPA (Single Page Application) mode

          This will cause the file given by --index to be served for all non-existing file paths. In effect, this will serve
          the index file whenever a 404 would otherwise occur in order to allow the SPA router to handle the request instead.

          [env: MINISERVE_SPA=]

      --pretty-urls
          Activate Pretty URLs mode

          This will cause the server to serve the equivalent `.html` file indicated by the path.

          `/about` will try to find `about.html` and serve it.

          [env: MINISERVE_PRETTY_URLS=]

  -p, --port <PORT>
          Port to use

          [env: MINISERVE_PORT=]
          [default: 8080]

  -i, --interfaces <INTERFACES>
          Interface to listen on

          [env: MINISERVE_INTERFACE=]

  -a, --auth <AUTH>
          Set authentication

          Currently supported formats:
          username:password, username:sha256:hash, username:sha512:hash
          (e.g. joe:123, joe:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3)

          [env: MINISERVE_AUTH=]

      --auth-file <AUTH_FILE>
          Read authentication values from a file

          Example file content:

          joe:123
          bob:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
          bill:

          [env: MINISERVE_AUTH_FILE=]

      --route-prefix <ROUTE_PREFIX>
          Use a specific route prefix

          [env: MINISERVE_ROUTE_PREFIX=]

      --random-route
          Generate a random 6-hexdigit route

          [env: MINISERVE_RANDOM_ROUTE=]

  -P, --no-symlinks
          Hide symlinks in listing and prevent them from being followed

          [env: MINISERVE_NO_SYMLINKS=]

  -H, --hidden
          Show hidden files

          [env: MINISERVE_HIDDEN=]

  -S, --default-sorting-method <DEFAULT_SORTING_METHOD>
          Default sorting method for file list

          [env: MINISERVE_DEFAULT_SORTING_METHOD=]
          [default: name]

          Possible values:
          - name: Sort by name
          - size: Sort by size
          - date: Sort by last modification date (natural sort: follows alphanumerical order)

  -O, --default-sorting-order <DEFAULT_SORTING_ORDER>
          Default sorting order for file list

          [env: MINISERVE_DEFAULT_SORTING_ORDER=]
          [default: desc]

          Possible values:
          - asc:  Ascending order
          - desc: Descending order

  -c, --color-scheme <COLOR_SCHEME>
          Default color scheme

          [env: MINISERVE_COLOR_SCHEME=]
          [default: squirrel]
          [possible values: squirrel, archlinux, zenburn, monokai]

  -d, --color-scheme-dark <COLOR_SCHEME_DARK>
          Default color scheme

          [env: MINISERVE_COLOR_SCHEME_DARK=]
          [default: archlinux]
          [possible values: squirrel, archlinux, zenburn, monokai]

  -q, --qrcode
          Enable QR code display

          [env: MINISERVE_QRCODE=]

  -u, --upload-files [<ALLOWED_UPLOAD_DIR>]
          Enable file uploading (and optionally specify for which directory)

          [env: MINISERVE_ALLOWED_UPLOAD_DIR=]

  -U, --mkdir
          Enable creating directories

          [env: MINISERVE_MKDIR_ENABLED=]

  -m, --media-type <MEDIA_TYPE>
          Specify uploadable media types

          [env: MINISERVE_MEDIA_TYPE=]
          [possible values: image, audio, video]

  -M, --raw-media-type <MEDIA_TYPE_RAW>
          Directly specify the uploadable media type expression

          [env: MINISERVE_RAW_MEDIA_TYPE=]

  -o, --overwrite-files
          Enable overriding existing files during file upload

          [env: OVERWRITE_FILES=]

  -r, --enable-tar
          Enable uncompressed tar archive generation

          [env: MINISERVE_ENABLE_TAR=]

  -g, --enable-tar-gz
          Enable gz-compressed tar archive generation

          [env: MINISERVE_ENABLE_TAR_GZ=]

  -z, --enable-zip
          Enable zip archive generation

          WARNING: Zipping large directories can result in out-of-memory exception because zip generation is done in memory
          and cannot be sent on the fly

          [env: MINISERVE_ENABLE_ZIP=]

  -C, --compress-response
          Compress response

          WARNING: Enabling this option may slow down transfers due to CPU overhead, so it is disabled by default.

          Only enable this option if you know that your users have slow connections or if you want to minimize your server's bandwidth usage.

          [env: MINISERVE_COMPRESS_RESPONSE=]

  -D, --dirs-first
          List directories first

          [env: MINISERVE_DIRS_FIRST=]

  -t, --title <TITLE>
          Shown instead of host in page title and heading

          [env: MINISERVE_TITLE=]

      --header <HEADER>
          Set custom header for responses

          [env: MINISERVE_HEADER=]

  -l, --show-symlink-info
          Visualize symlinks in directory listing

          [env: MINISERVE_SHOW_SYMLINK_INFO=]

  -F, --hide-version-footer
          Hide version footer

          [env: MINISERVE_HIDE_VERSION_FOOTER=]

      --hide-theme-selector
          Hide theme selector

          [env: MINISERVE_HIDE_THEME_SELECTOR=]

  -W, --show-wget-footer
          If enabled, display a wget command to recursively download the current directory

          [env: MINISERVE_SHOW_WGET_FOOTER=]

      --print-completions <shell>
          Generate completion file for a shell

          [possible values: bash, elvish, fish, powershell, zsh]

      --print-manpage
          Generate man page

      --tls-cert <TLS_CERT>
          TLS certificate to use

          [env: MINISERVE_TLS_CERT=]

      --tls-key <TLS_KEY>
          TLS private key to use

          [env: MINISERVE_TLS_KEY=]

      --readme
          Enable README.md rendering in directories

          [env: MINISERVE_README=]

  -I, --disable-indexing
          Disable indexing

          This will prevent directory listings from being generated and return an error instead.

          [env: MINISERVE_DISABLE_INDEXING=]

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

How to install

Packaging status

On Linux: Download miniserve-linux from the releases page and run

chmod +x miniserve-linux
./miniserve-linux

Alternatively, if you are on Arch Linux, you can do

pacman -S miniserve

On Termux

pkg install miniserve

On OSX: Download miniserve-osx from the releases page and run

chmod +x miniserve-osx
./miniserve-osx

Alternatively install with Homebrew:

brew install miniserve
miniserve

On Windows: Download miniserve-win.exe from the releases page and run

miniserve-win.exe

Alternatively install with Scoop:

scoop install miniserve

With Cargo: Make sure you have a recent version of Rust. Then you can run

cargo install --locked miniserve
miniserve

With Docker: Make sure the Docker daemon is running and then run

docker run -v /tmp:/tmp -p 8080:8080 --rm -it docker.io/svenstaro/miniserve /tmp

With Podman: Just run

podman run -v /tmp:/tmp -p 8080:8080 --rm -it docker.io/svenstaro/miniserve /tmp

With Helm: See this third-party Helm chart by @wrenix.

Shell completions

If you'd like to make use of the built-in shell completion support, you need to run miniserve --print-completions <your-shell> and put the completions in the correct place for your shell. A few examples with common paths are provided below:

# For bash
miniserve --print-completions bash > ~/.local/share/bash-completion/completions/miniserve
# For zsh
miniserve --print-completions zsh > /usr/local/share/zsh/site-functions/_miniserve
# For fish
miniserve --print-completions fish > ~/.config/fish/completions/miniserve.fish

systemd

A hardened systemd-compatible unit file can be found in packaging/[email protected]. You could install this to /etc/systemd/system/[email protected] and start and enable miniserve as a daemon on a specific serve path /my/serve/path like this:

systemctl enable --now miniserve@-my-serve-path

Keep in mind that you'll have to use systemd-escape to properly escape a path for this usage.

In case you want to customize the particular flags that miniserve launches with, you can use

systemctl edit miniserve@-my-serve-path

and set the [Service] part in the resulting override.conf file. For instance:

[Service]
ExecStart=/usr/bin/miniserve --enable-tar --enable-zip --no-symlinks --verbose -i ::1 -p 1234 --title hello --color-scheme monokai --color-scheme-dark monokai -- %I

Make sure to leave the %I at the very end in place or the wrong path might be served. You might additionally have to override IPAddressAllow and IPAddressDeny if you plan on making miniserve directly available on a public interface.

Binding behavior

For convenience reasons, miniserve will try to bind on all interfaces by default (if no -i is provided). It will also do that if explicitly provided with -i 0.0.0.0 or -i ::. In all of the aforementioned cases, it will bind on both IPv4 and IPv6. If provided with an explicit non-default interface, it will ONLY bind to that interface. You can provide -i multiple times to bind to multiple interfaces at the same time.

Why use this over alternatives?

  • darkhttpd: Not easily available on Windows and it's not as easy as download-and-go.
  • Python built-in webserver: Need to have Python installed, it's low performance, and also doesn't do correct MIME type handling in some cases.
  • netcat: Not as convenient to use and sending directories is somewhat involved.

Releasing

This is mostly a note for me on how to release this thing:

  • Make sure CHANGELOG.md is up to date.
  • cargo release <version>
  • cargo release --execute <version>
  • Releases will automatically be deployed by GitHub Actions.
  • Update Arch package.

miniserve's People

Contributors

ahti avatar aliemjay avatar atreyagaurav avatar baod-rate avatar colindean avatar cyqsimon avatar d-air1 avatar damianx avatar deantvv avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dyc3 avatar equal-l2 avatar gyscos avatar ivkinstanislav avatar jikstra avatar jonasdiemer avatar kevcui avatar ksxgithub avatar levaitamas avatar marawan31 avatar mayjs avatar parrotmac avatar proudmuslim-dev avatar rouge8 avatar sinking-point avatar svenstaro avatar vojta7 avatar zuofuhong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miniserve's Issues

Remove unwrap()'s

We have some places in the code where we call unwrap() (4 to be precise).

Maybe we could replace those with unwrap_or* (default value, actual error, etc, depending on the case) for unwrap()'s happening outside the main() method, and as for the ones happening in the main(), printing a nice error message with the logger + exiting instead of panicking.

This has been suggested in Reddit's "what's everyone working on this week": https://www.reddit.com/r/rust/comments/bapows/whats_everyone_working_on_this_week_152019/ekdt4ls

Miniserve cutting ends of files off.

Most of the times I use miniserve it will cut the ends of files off. No idea what causes it but it happens regularly.

Miniserve version: 0.1.5
OS: Fedora 28

Uploading files and writing with specific permissions and user/group

I have the same folder shared via Samba which requires specific user and file/directory permissions. If I upload through miniserve, it uses current user and creates file with 644 permissions. Anyway to change this behaviour to use "nobody.nogroup" and file permissions to 775?

The error/warning logs that appear in integration test is pretty annoying

The test logs does not show them before due to miniserve's logs being disabled by default. But now they are shown alongside normal test logs makes it hard to read the logs that actually matters.

Screenshot of my terminal

Suggestion

Do not redirect stderr output of subprocess to parent's stderr.


P.S. I am not familiar with std::process so I am going to waiting for someone else to do it.

Makefile default should build for my platform

When I ran make, it started running a release build for Linux on my Mac ⁉️

It's because that task is simply the first in the Makefile.

I'd expect make alone to build whatever is appropriate for my system.

Hide theme in URL if it's the default

We're hiding all the other parameters if they are the default but the default theme slipped by somehow and is now always visible in the URL which leads to untidy URLs. It should be hidden like the other parameters.

Configuration file

Summary

Right now, the only way to "configure" miniserve is via command-line arguments

miniserve --interfaces ::1 --port 8080 --auth user:sha256:hash $@

But it would be more convenient to have a global configuration file for recurring command-line options

# manifest version, it allows us to warn users when a breaking change is introduced
version: 0

# configuration values, almost identical to command-line arguments
config:
  interfaces: ['::1']
  port: 8080
  auth: 'user:sha256:hash'

Discussion

  • Which format should we use? RON, TOML or YAML?
  • Where to locate configuration files? ~/.miniserverc.$ext, ~/.miniserve/config.$ext, ~/.config/miniserve/config.$ext?
  • What to do when configuration file is invalid? Ignore, Warn, Error?
  • Which library should we use? (For now, I recommend serde)

Architecture not specified for release binaries

The three release binaries are all for x86-64, but this is not specified anywhere. With the increasing prevalence of ARM-based systems even in the Windows world (e.g. various Snapdragon-based laptops) the releases page should at least list architecture (e.g., miniserve-linux-x86_64). Long-term, using a platform like trust on Travis to test and generate releases for multiple architectures seems wise.

Serve cwd by default?

It'd be great if running miniserve without any arguments served the current working directory.

I'd be happy to make this change, by giving the PATH argument a default of ., if this is amenable.

Cargo.lock is missing

I am rather new to the Cargo build system but shouldn't there be a Cargo.lock file?

I guess it is not needed as it could be generated from Cargo.toml but it makes porting things much easier.

Cheers!

Streaming zip/tar of directories

It would be cool and convenient to be able to stream directories on the host as archives on the fly if you want to offer many individual files for download.

self-serve?

This is a single-binary-download server. A convenience option to serve its own binary might fit well.

Perhaps it could serve it under a name that includes appropriate target and version information, and have a 302 redirect from a simpler self URL?

ARM64/AARCH64 Binaries

It shall be nice and time saver for many if precompiled binaries are available for ARM64/AARCH64 platforms.

Handle --port=0

The current behaviour of miniserve if set to --port=0 is to accept it (valid u16). However, this is not a "valid" port (actually, it is valid, but shouldn't be used as such), an address like 127.0.0.1:0 is not valid .

Chrome's message:

This site can’t be reached
The web page at http://127.0.0.1:0/ might be temporarily down or it may have moved permanently to a new web address.
ERR_ADDRESS_INVALID

By convention (I don't know if there's a spec for it ?), addressing a system on port 0 means "give me whatever port you want", usually from 49152 to 65535.

So, we have 2 solutions here:

  • either we make the port 0 invalid, exception caught at startup, no big deal
  • or we implement such a feature if you think that's worth it: generate a random port from 49152 to 65535 and use it. Note that Python's http.server implements this feature

In short, either a bug fix, or a new feature :)

Cleaner error handling

The auth error handling right now is quite verbose. I'm sure it can be done better and more neatly.

Build of miniserv 0.3.1 fails on all macOS versions

Build of miniserv 0.3.1 fails on all macOS versions (Homebrew/homebrew-core#38306) with:

   Compiling literalext v0.1.1
error[E0554]: #![feature] may not be used on the stable release channel
  --> /Users/brew/Library/Caches/Homebrew/cargo_cache/registry/src/github.com-1ecc6299db9ec823/literalext-0.1.1/src/lib.rs:19:37
   |
19 | #![cfg_attr(feature = "proc-macro", feature(proc_macro))]
   |                                     ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
error: Could not compile `literalext`.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `miniserve v0.3.1 (/private/tmp/miniserve-20190326-39556-106jom/miniserve-0.3.1)`, intermediate artifacts can be found at `/private/tmp/miniserve-20190326-39556-106jom/miniserve-0.3.1/target`

Caused by:
  build failed

404 when file names in served directory contain spaces

Trying to download a file with spaces in its name from a served directory yields a 404 HTTP error. Reproducible via

$ touch "filename with spaces"
$ miniserve. &
$ wget http://localhost:8080/filename%20with%20spaces
--2019-01-03 01:33:52--  http://localhost:8080/filename%20with%20spaces
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 404 Not Found
2019-01-03 01:33:52 ERROR 404: Not Found.

File downloads without issue if that specific file is instead served, i.e. miniserve file\ with\ spaces.

Using miniserve v0.2.1.

Error while installation with cargo

cargo install miniserve

    Updating crates.io index
  Installing miniserve v0.4.1
   Compiling semver-parser v0.7.0
   Compiling libc v0.2.55
   Compiling autocfg v0.1.2
   Compiling proc-macro2 v0.4.30
   Compiling rand_core v0.4.0
   Compiling byteorder v1.3.1
   Compiling unicode-xid v0.1.0
   Compiling arrayvec v0.4.10
   Compiling cc v1.0.37
   Compiling syn v0.15.34
   Compiling lazy_static v1.3.0
   Compiling cfg-if v0.1.9
   Compiling version_check v0.1.5
   Compiling stable_deref_trait v1.1.1
   Compiling nodrop v0.1.13
   Compiling memchr v2.2.0
   Compiling smallvec v0.6.9
   Compiling scopeguard v0.3.3
   Compiling memoffset v0.2.1
   Compiling fnv v1.0.6
   Compiling failure_derive v0.1.5
   Compiling encoding_index_tests v0.1.4
   Compiling futures v0.1.27
   Compiling slab v0.4.2
   Compiling matches v0.1.8
   Compiling rustc-demangle v0.1.14
   Compiling siphasher v0.2.3
   Compiling percent-encoding v1.0.1
   Compiling arc-swap v0.3.11
   Compiling quick-error v1.2.2
   Compiling linked-hash-map v0.5.2
   Compiling serde v1.0.91
   Compiling crc32fast v1.2.0
   Compiling ryu v0.2.8
   Compiling num-traits v0.2.6
   Compiling itoa v0.4.4
   Compiling safemem v0.3.0
   Compiling untrusted v0.6.2
   Compiling num-integer v0.1.39
   Compiling regex v1.1.6
   Compiling bitflags v1.0.4
   Compiling ucd-util v0.1.3
   Compiling httparse v1.3.3
   Compiling string v0.1.3
   Compiling unicode-width v0.1.5
   Compiling indexmap v1.0.2
   Compiling utf8-ranges v1.0.2
   Compiling dtoa v0.4.4
   Compiling unicode-segmentation v1.3.0
   Compiling ansi_term v0.11.0
   Compiling language-tags v0.2.2
   Compiling vec_map v0.8.1
   Compiling sha1 v0.6.0
   Compiling strsim v0.8.0
   Compiling lazycell v1.2.1
   Compiling literalext v0.1.1
   Compiling maud_htmlescape v0.17.0
error[E0554]: #![feature] may not be used on the stable release channel
  --> /home/simon/.cargo/registry/src/github.com-1ecc6299db9ec823/literalext-0.1.1/src/lib.rs:19:37
   |
19 | #![cfg_attr(feature = "proc-macro", feature(proc_macro))]
   |                                     ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
error: Could not compile `literalext`.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `miniserve v0.4.1`, intermediate artifacts can be found at `/tmp/cargo-installR6Shb6`

Caused by:
  build failed```

Allow different sort modes for file listing

It would be nice to be able to sort the files differently. Currently, the ordering feels kind of wrong as the dirs are usually followed by the files but currently everything is only ordered alphabetically. It would be nice to get different order types. Maybe these order modes:

dirsfiles

dir1/
dir2/
dir3/
file1
file2
file3

alpha

A/
a
B
b/
C
c

natural

A/
B
C
a
b
c

SSL support?

It'd be great if miniserve has SSL support.
(Since SSL is a complex stuff, maybe it's against the simplicity policy of miniserve, though)

Add formula to homebrew

Miniserve is great but it takes a long time to install when having to compile it. It'd be awesome if I could install it through Homebrew as a part of my development team's standard workstation configuration.

I can do up the formula if no one else gets to it first. I think miniserve meets the notability requirements now (age and number of GitHub stars).

Add constant time password comparison

We're currently attackable using timing attacks. We might want to add a constant time password comparison. There is one in ring that's easy to use.

Proposal: Password Hashing

Problem

miniserve already has an --auth feature, the problem is, the password is publicly visible. This makes it impossible to expose the command line to the public.

Solution

Support --auth username:sha256:password_hash syntax in addition to the old syntax.


P.S. I am trying to learn Rust by contributing to this repository, so don't implement this feature just yet.

Nice UI to see activity

Perhaps it would be cool for the host to see what's going on in a somewhat interactive interface.

Search bar ?

What would you think about having a search bar to search for files in the listing ? I think that would be pretty useful for mobiles, when you can't easily CTRL+F. If that's an idea you like, I think we should make it compatible with both Javascript and no-Javascript users.

I was thinking:

The search bar has a "Search" button. When clicking on it, the searched term is put as query parameter ?search=foobar, then the server generates a page corresponding to that filtering. That would be compatible with no-javascript user. If Javascript is enabled, we simply hide the search button, and the filtering is performed in live using Javascript.

Rework colors

Currently I'm not super happy with how everything looks. It has a pale color palette without good contrast. It should have better contrast.

Ipv6

You are currently only allow Ipv4 access to the host, but no IPv6.
I would like to see either a command line argument to enable one/both or make dual stack the default :)

Use clippy to improve code quality

Clippy is a linter for Rust. It prevents us from making common mistakes. I've recently tried running cargo clippy for main.rs and this is what I got:

Clippy warnings
    Checking miniserve v0.4.1 (/home/khai/programming/miniserve)
warning: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
  --> src/auth.rs:78:56
   |
78 | pub fn compare_hash<T: Digest>(password: String, hash: &Vec<u8>) -> bool {
   |                                                        ^^^^^^^^ help: change this to: `&[u8]`
   |
   = note: #[warn(clippy::ptr_arg)] on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg

warning: identical conversion
   --> src/listing.rs:159:18
    |
159 |     for entry in dir.path.read_dir()? {
    |                  ^^^^^^^^^^^^^^^^^^^^ help: consider removing `dir.path.read_dir()?()`: `dir.path.read_dir()?`
    |
    = note: #[warn(clippy::identity_conversion)] on by default
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion

warning: this function has too many arguments (11/7)
  --> src/renderer.rs:12:1
   |
12 | / pub fn page(
13 | |     serve_path: &str,
14 | |     entries: Vec<Entry>,
15 | |     is_root: bool,
...  |
86 | |     }
87 | | }
   | |_^
   |
   = note: #[warn(clippy::too_many_arguments)] on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments

warning: in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let'
  --> src/main.rs:86:26
   |
86 |               .map_err(|e| {
   |  __________________________^
87 | |                 ContextualError::IOError(
88 | |                     "Failed to retrieve symlink's metadata".to_string(),
89 | |                     e,
90 | |                 )
91 | |             })?
   | |_____________^
   |
   = note: #[warn(clippy::block_in_if_condition_stmt)] on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_stmt

    Finished dev [unoptimized + debuginfo] target(s) in 2.81s

Proposal

  • Integrate clippy into CI
  • Create a rls.toml that enables clippy

Output access logs

I'm actively using miniserve for something and realizing that I can't tell from the miniserve side that anything is happening. It'd be nice if, upon request, a log line was emitted, perhaps in Common Log Format.

host ident authuser date request status bytes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.