npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

static-route

v0.2.0

Published

A route for an http server to safely serve static files

Downloads

340

Readme

static-route

A route for an http server to safely serve static files

now supports streaming and ranges

Installation

npm install static-route

Usage

var http = require('http');
var staticroute = require('static-route');

// basic
http.createServer(staticroute());
// => this server will serve static files from `process.cwd()`

Basic Invocation

var http = require('http');
var staticroute = require('static-route');
var callback = staticroute();

var server = http.createServer(callback);
server.listen(8080);

This server will serve static files out of your current directory with correct response codes, headers, and etags. For example:

$ curl -i http://localhost:8080
HTTP/1.1 403 Forbidden
Date: Mon, 29 Apr 2013 19:25:42 GMT
Connection: keep-alive
Transfer-Encoding: chunked

$ curl -i http://localhost:8080/fake
HTTP/1.1 404 Not Found
Date: Mon, 29 Apr 2013 19:25:43 GMT
Connection: keep-alive
Transfer-Encoding: chunked

$ curl -i http://localhost:8080/package.json
HTTP/1.1 200 OK
Last-Modified: Mon, 29 Apr 2013 01:03:28 GMT
Content-Length: 494
Content-Type: application/json
ETag: "494-1367197408000"
Date: Mon, 29 Apr 2013 19:25:45 GMT
Connection: keep-alive

{
  "name": "static-route",
...

You can see a 403 was generated for the first request, as it was for a directory.

The second request generated a 404 as the asset does not exist.

The third request was successful, it generated the proper headers, complete with ETag, Last-Modified, Content-Length, and Content-Type (from the mime module). Files are also served with fs.createReadStream so the entire file contents are not read into memory before being sent to the client.

Advanced Invocations

Using the code above and changing the callback line to:

var callback = staticroute('/');
$ curl -i http://localhost:8080/etc/passwd
HTTP/1.1 200 OK
Last-Modified: Wed, 22 Feb 2012 00:57:33 GMT
Content-Length: 5148
Content-Type: application/octet-stream
ETag: "5148-1329872253000"
Date: Mon, 29 Apr 2013 19:31:20 GMT
Connection: keep-alive

root:*:0:0:root:/root:/bin/sh
...

Static files are being served from /, I wouldn't recommend doing this.

Same thing as a above, modifying the callback line:

var callback = staticroute({dir: process.cwd(), autoindex: true, logger: function() {}})

This will serve out of your current directory (default behavior), with directory indexing enabled, and no logging.

$ curl -i http://localhost:8080/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Date: Mon, 29 Apr 2013 19:37:13 GMT
Connection: keep-alive
Transfer-Encoding: chunked

<ul>
<li><a href="/">.</a></li>
<li><a href="/">..</a></li>
<li><a href="/REAMDE.md">REAMDE.md</a></li>
<li><a href="/examples">examples</a></li>
<li><a href="/node_modules">node_modules</a></li>
<li><a href="/package.json">package.json</a></li>
<li><a href="/static-route.js">static-route.js</a></li>
<li><a href="/test">test</a></li>
</ul>

$ curl -i http://localhost:8080/?json
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 29 Apr 2013 19:37:16 GMT
Connection: keep-alive
Transfer-Encoding: chunked

[".", "..", "REAMDE.md","examples","node_modules","package.json","static-route.js","test"]

Add ?json to directory requests to get JSON instead of HTML if autoindex is enabled

Logging

By default, any and all error messages from filesystem functions are logged with console.error, this behavior can be changed, see below:

Functions

staticroute([opts])

The main export of the module. This function, when called, returns a function suitable for an http server request callback.

opts is an optional object that contains configuration variables. opts can also be set to a string of the path to use to server static files.

opts:

  • dir: The dir to serve static files from, defaults to process.cwd()
  • autoindex: If true, a request to a directory will return an index page for the contents. If false or unset, a request to a directory will return a 403. Defaults to false
  • logger: The function to use to log error messages, defaults to function () {}
  • tryfiles: An array (defaults to []) of files to try first, like NGINX. For example, set opts.tryfiles = ['index.html'] to serve an index page if it exists
  • slice: A prefix to req.url to slice off

function(req, res)

The function returned from the above function. This function takes the req and res object from an http(s) server connection callback, and serves static contents.

Security

Path names are normalized and correctly joined (no regex, string manipulation, etc). The path module and built in decoding functions are used to correctly parse the web addresses supplied.

$ curl -i http://localhost:8080/../../../../../../../etc/passwd
HTTP/1.1 404 Not Found
Date: Mon, 29 Apr 2013 19:39:54 GMT
Connection: keep-alive
Transfer-Encoding: chunked

and on the server

ENOENT, stat '/Users/dave/dev/node-static-route/etc/passwd'

Directory traversal is not possible, this module is stuck inside the directory you supply (or cwd). Go ahead, try it.

$ curl -i http://localhost:8080/%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd
HTTP/1.1 404 Not Found
Date: Mon, 29 Apr 2013 21:50:46 GMT
Connection: keep-alive
Transfer-Encoding: chunked

and on the server

ENOENT, stat '/Users/dave/dev/node-static-route/%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd'

Notes

I take security seriously. If this module has any security holes, then this module has bugs. Please report any and all security holes or bugs you find, or even better pull request a fix.

License

MIT