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

file-send

v4.0.3

Published

A http file send.

Downloads

102

Readme

file-send

A http/https file send

NPM Version Download Status Linux Status Windows Status Test Coverage Node Version Dependencies

Installation

$ npm install file-send

API

const url = require('url');
const http = require('http');
const through2 = require('through2');
const FileSend = require('file-send');

http.createServer((request, response) => {
  new FileSend(request, url.parse(request.url).pathname, {
    root: '/',
    etag: true,
    maxAge: '30d'
  })
    .on('dir', function(realpath, next) {
      // dir events
      next('dir');
    })
    .on('error', function(error, next) {
      // error events
      next('error');
    })
    .use(through2()) // Set middleware
    .pipe(response); // Send file to response
});

FileSend(request, path, [options])

Create a new FileSend for the given path and options to initialize. The request is the Node.js HTTP request and the path is a urlencoded path to send (urlencoded, not the actual file-system path).

Options

root - String

Set server root.

ignore - String|Array

Set ignore rules, support glob string. see: micromatch

ignoreAccess - String

Set how "ignore" are treated when encountered.

The default value is 'deny'.

  • 'deny' Send a 403 for any request for ignore matched.
  • 'ignore' Pretend like the ignore matched does not exist and 404.
glob - Object

Set micromatch options. see: micromatch

acceptRanges - Boolean

Enable or disable accepting ranged requests, defaults to true. Disabling this will not send Accept-Ranges and ignore the contents of the Range request header.

charset - String

Set Content-Type charset.

cacheControl - Boolean

Enable or disable setting Cache-Control response header, defaults to true. Disabling this will ignore the immutable and maxAge options.

etag - Boolean

Enable or disable etag generation, defaults to true.

index - String|Array|Boolean

By default send supports "index.html" files, to disable this set false or to supply a new index pass a string or an array in preferred order.

lastModified - Boolean

Enable or disable Last-Modified header, defaults to true. Uses the file system's last modified value.

maxAge - String|Number

Provide a max-age in milliseconds for http caching, defaults to 0. This can also be a string accepted by the ms module.

immutable - Boolean

Enable or diable the immutable directive in the Cache-Control response header, defaults to false. If set to true, the maxAge option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the maxAge option to check if the file has changed.

FileSend(request, path, [options]).pipe(response)

The pipe method is used to pipe the response into the Node.js HTTP response object, typically FileSend(request, path, [options]).pipe(response).

FileSend.mime

The mime export is the global instance of of the mime-types npm module.

Events

The FileSend is an event emitter and will emit the following events:

  • dir a directory was requested(realpath, next)
  • file a file was requested (realpath, stats)
  • error an error occurred (error, next)

Error-handling

By default when no error listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.

Caching

It does not perform internal caching, you should use a reverse proxy cache such as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).

Running tests

$ npm install
$ npm test

Examples

'use strict';

const url = require('url');
const http = require('http');
const chalk = require('chalk');
const cluster = require('cluster');
const FileSend = require('file-send');
const NUMCPUS = require('os').cpus().length;

// create server
function createServer(root, port) {
  http
    .createServer(function(request, response) {
      const send = new FileSend(request, url.parse(request.url).pathname, {
        root: root || process.cwd(),
        maxAge: '3day',
        index: ['index.html'],
        ignore: ['**/.*?(/**)']
      });

      send.pipe(response);
    })
    .listen(port || 8080);
}

if (cluster.isMaster) {
  // fork workers
  for (let i = 0; i < NUMCPUS; i++) {
    const worker = cluster.fork();

    // worker is listening
    if (i === NUMCPUS - 1) {
      worker.on('listening', address => {
        console.log(
          chalk.green.bold('Server run at:'),
          chalk.cyan.bold((address.address || '127.0.0.1') + ':' + address.port),
          '\r\n-----------------------------------------------------------------------------------------'
        );
      });
    }
  }
} else {
  // workers can share any tcp connection
  // in this case it is an http server
  createServer();
}

License

MIT