Git Product home page Git Product logo

httpserv's Introduction

httpserv

A tiny, zero-dependency HTTP fileserver, meant for local development of HTML. It's not the absolute fastest, it's not the absolute smallest executable, it's not the most featureful, but it's incredibly simple to deploy and does almost nothing but just serve the file you name over HTTP. Specifically, all it does is:

  • Parse the URL to find the local filepath
  • Make sure that URL doesn't contain ..s
  • If that filepath points to a directory, add /index.html
  • Use the extension to figure out the Content-Type
  • Send the file back

Because of its simplicity, it's incredibly quick to install, quick to start, and quick to respond

Planned tasks can be seen in the issues

Planned non-features include:

  • Any dependencies by default (behind a feature gate is fine)
  • Maximizing response speed where it would cost ease of use or setup speed
  • Anything that gives httpserv a noticeable delay
  • Anything targeted at better production suitability

Install

cargo install httpserv

That's it. Assuming the Cargo bin directory is on your path, you can now call httpserv from your command line. For directions on installing Cargo, please see rustup.rs.

On WSL, you may need to call cargo.exe and httpserv.exe instead, depending on if you've got Rust installed on the Windows or WSL side of things.

Usage

All arguments are optional -- if you want to serve your current directory on localhost:8080 with the default mappings, you can just type httpserv and hit enter. Otherwise:

httpserv [directory] [listen] [mappings...]
  • directory: Where to look for files to serve. Defaults to .
  • listen: The host/port to listen on, as expected by the FromStr impl for SocketAddr. Defaults to localhost:8080
  • mappings...: Any additional mappings from file extension to MIME types, besides the defaults. Anything specified here which matches the same extension as a default will override the default MIME type. The format is extension=MIME, with no leading . on the extension.

Known issues

Because this is meant for local development and not production use, there are some issues which I haven't bothered to fix. In general, the reason why boils down to httpserv being meant to aid local development. If you're using it in any situation where you can't restart it at will, you're doing it very, very wrong.

  • Requests with absurdly long URLs or absurd numbers of headers can cause the process to hang or crash
  • Requests are processed serially, so if enough are received at once, some may not get responses for a while; however, the time to parse any single request is so fast that it's not an issue normally
  • If a file is changed between when the HTTP headers are sent and when the rest of the body is sent, the reported Content-Length will be incorrect, so the browser may truncate the content or display an error.
  • A malicious actor could send a partial request (e.g. never ending the header) and lock up the server.

httpserv's People

Contributors

nic-hartley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

httpserv's Issues

Library crate

It seems like it'd be useful for testing to run a lightweight HTTP fileserver. Maybe look into turning this into a library for that purpose? Does not expand the scope to include turning this into an HTTP server framework, though! Specifically for serving files (e.g. to test website generation)

Ensure symlinks work

My current setup behaves oddly around symlinks. I suspect it's because I'm running a Windows executable but passing it a path containing a symlink, but this needs to be investigated and maybe fixed.

TLS support

This doesn't seem particularly useful in my use-case, but others might want to make requests to HTTPS sites. Allowing TLS (by specifying a cert to use) would be useful.

Will need to be feature-gated, as it'll require a dependency on rustls.

Help: directory browsing

Please any instructions on how to enable directory browing? I setup a directory with zip files and successfully started httpsrv listening on that folder, but it seems i can't find a way to download those files.

Better customizable mappings

Specifically, allow for extensions with .s in them and match against the longest suffix. (I know what I mean.)

thread '<unnamed>' panicked at 'attempt to subtract with overflow'

I know this hasn't been updated in two years and it's not meant to be super safe but I figured I'd report this anyway (since it might be used as a starting point for others). Basically, the .len() is not bounds-checked and it just assumes the %'s are well-placed. This causes a panic.

https://github.com/nic-hartley/httpserv/blob/585c020/src/http.rs#L40

https://github.com/sigaloid/vial/blob/81f11e25179b8b7a5a2b8fc2c1b03d8f4be86b5e/src/util.rs#L28 is how I fixed it.

Support for Content-Encoding

Specifically, if the filename isn't found but filename. is, send it with Content-Encoding: <type>. (Respecting Accept-Encoding would be nice.) Probably only worth supporting

This may need to be feature-gated.

Markdown parsing

e.g. if someone requests foo.html and that's not present but foo.md is, automatically parse the Markdown into HTML and send that instead.

Definitely needs to be feature-gated; the parsing will be done by an external crate.

Respect Accept headers

Simple enough. If the file's Content-Type doesn't match the Content-Types the client will Accept, return 406 Not Acceptable. Maybe, to be fancy, get all possible Content-Types and pick one (highest-weighted?) which matches.

Better option syntax

The current option syntax (entirely position-based) is super easy to parse and can be done trivially without external crates, but it'll only get more and more convoluted with e.g. #9 -- it may be useful to have more standard option-parsing as an option (possibly enabled by default with certain features?).

This definitely needs to be feature-gated, as it'll be built on something like clap.

(Feature-gated?) Multithreading/parallel request handling

Useful if e.g. some files are particularly big, and you don't want site loading to entirely stall while they're going. None of the threads are doing a ton, so matching threads-per-CPU doesn't matter; this is just to enable any parallel processing, not to maximize performance.

Should be pretty simple -- the only data accessed by multiple threads is read-only.

Might need to be feature-gated, if it slows down compile times, but it should be possible without external crates. See spmc::channel.

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.