http-server
Advanced tools
Comparing version 0.11.1 to 0.12.0
@@ -6,5 +6,32 @@ 'use strict'; | ||
ecstatic = require('ecstatic'), | ||
auth = require('basic-auth'), | ||
httpProxy = require('http-proxy'), | ||
corser = require('corser'); | ||
corser = require('corser'), | ||
path = require('path'), | ||
secureCompare = require('secure-compare'); | ||
// a hacky and direct workaround to fix https://github.com/http-party/http-server/issues/525 | ||
function getCaller() { | ||
try { | ||
var stack = new Error().stack; | ||
var stackLines = stack.split('\n'); | ||
var callerStack = stackLines[3]; | ||
return callerStack.match(/at (.+) \(/)[1]; | ||
} | ||
catch (error) { | ||
return ''; | ||
} | ||
} | ||
var _pathNormalize = path.normalize; | ||
path.normalize = function (p) { | ||
var caller = getCaller(); | ||
var result = _pathNormalize(p); | ||
// https://github.com/jfhbrook/node-ecstatic/blob/master/lib/ecstatic.js#L20 | ||
if (caller === 'decodePathname') { | ||
result = result.replace(/\\/g, '/'); | ||
} | ||
return result; | ||
}; | ||
// | ||
@@ -47,3 +74,9 @@ // Remark: backwards compatibility for previous | ||
this.cache = options.cache === undefined ? 3600 : options.cache; // in seconds. | ||
this.cache = ( | ||
options.cache === undefined ? 3600 : | ||
// -1 is a special case to turn off caching. | ||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Preventing_caching | ||
options.cache === -1 ? 'no-cache, no-store, must-revalidate' : | ||
options.cache // in seconds. | ||
); | ||
this.showDir = options.showDir !== 'false'; | ||
@@ -53,2 +86,3 @@ this.autoIndex = options.autoIndex !== 'false'; | ||
this.gzip = options.gzip === true; | ||
this.brotli = options.brotli === true; | ||
this.contentType = options.contentType || 'application/octet-stream'; | ||
@@ -72,2 +106,23 @@ | ||
if (options.username || options.password) { | ||
before.push(function (req, res) { | ||
var credentials = auth(req); | ||
// We perform these outside the if to avoid short-circuiting and giving | ||
// an attacker knowledge of whether the username is correct via a timing | ||
// attack. | ||
if (credentials) { | ||
var usernameEqual = secureCompare(options.username, credentials.name); | ||
var passwordEqual = secureCompare(options.password, credentials.pass); | ||
if (usernameEqual && passwordEqual) { | ||
return res.emit('next'); | ||
} | ||
} | ||
res.statusCode = 401; | ||
res.setHeader('WWW-Authenticate', 'Basic realm=""'); | ||
res.end('Access denied'); | ||
}); | ||
} | ||
if (options.cors) { | ||
@@ -108,2 +163,3 @@ this.headers['Access-Control-Allow-Origin'] = '*'; | ||
gzip: this.gzip, | ||
brotli: this.brotli, | ||
contentType: this.contentType, | ||
@@ -119,2 +175,9 @@ handleError: typeof options.proxy !== 'string' | ||
changeOrigin: true | ||
}, function (err, req, res, target) { | ||
if (options.logFn) { | ||
options.logFn(req, res, { | ||
message: err.message, | ||
status: res.statusCode }); | ||
} | ||
res.emit('next'); | ||
}); | ||
@@ -141,2 +204,5 @@ }); | ||
this.server = union.createServer(serverOptions); | ||
if (options.timeout !== undefined) { | ||
this.server.setTimeout(options.timeout); | ||
} | ||
} | ||
@@ -143,0 +209,0 @@ |
{ | ||
"name": "http-server", | ||
"version": "0.11.1", | ||
"version": "0.12.0", | ||
"description": "A simple zero-configuration command-line http server", | ||
@@ -8,7 +8,9 @@ "main": "./lib/http-server", | ||
"type": "git", | ||
"url": "git://github.com/indexzero/http-server.git" | ||
"url": "git://github.com/http-party/http-server.git" | ||
}, | ||
"keywords": [ | ||
"cli", | ||
"command" | ||
"command", | ||
"http", | ||
"server" | ||
], | ||
@@ -24,2 +26,5 @@ "scripts": { | ||
], | ||
"engines": { | ||
"node": ">=6" | ||
}, | ||
"contributors": [ | ||
@@ -68,24 +73,34 @@ { | ||
"email": "byoung@bigbluehat.com" | ||
}, | ||
{ | ||
"name": "Daniel Dalton", | ||
"email": "daltond2@hawkmail.newpaltz.edu" | ||
}, | ||
{ | ||
"name": "Jade Michael Thornton", | ||
"email": "jade@jmthornton.net" | ||
} | ||
], | ||
"dependencies": { | ||
"colors": "1.0.3", | ||
"corser": "~2.0.0", | ||
"ecstatic": "^3.0.0", | ||
"http-proxy": "^1.8.1", | ||
"opener": "~1.4.0", | ||
"optimist": "0.6.x", | ||
"portfinder": "^1.0.13", | ||
"union": "~0.4.3" | ||
"basic-auth": "^1.0.3", | ||
"colors": "^1.3.3", | ||
"corser": "^2.0.1", | ||
"ecstatic": "^3.3.2", | ||
"http-proxy": "^1.17.0", | ||
"opener": "^1.5.1", | ||
"optimist": "~0.6.1", | ||
"portfinder": "^1.0.20", | ||
"secure-compare": "3.0.1", | ||
"union": "~0.5.0" | ||
}, | ||
"devDependencies": { | ||
"common-style": "^3.0.0", | ||
"request": "2.49.x", | ||
"vows": "0.7.x" | ||
"request": "^2.88.0", | ||
"vows": "~0.8.3" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/nodeapps/http-server/issues" | ||
"url": "https://github.com/http-party/http-server/issues" | ||
}, | ||
"license": "MIT", | ||
"preferGlobal": "true", | ||
"preferGlobal": true, | ||
"bin": { | ||
@@ -92,0 +107,0 @@ "http-server": "./bin/http-server", |
@@ -1,5 +0,5 @@ | ||
[![build status](https://img.shields.io/travis/indexzero/http-server.svg?style=flat-square)](https://travis-ci.org/indexzero/http-server) | ||
[![dependencies status](https://img.shields.io/david/indexzero/http-server.svg?style=flat-square)](https://david-dm.org/indexzero/http-server) | ||
[![build status](https://img.shields.io/travis/http-party/http-server.svg?style=flat-square)](https://travis-ci.org/http-party/http-server) | ||
[![dependencies status](https://img.shields.io/david/http-party/http-server.svg?style=flat-square)](https://david-dm.org/http-party/http-server) | ||
[![npm](https://img.shields.io/npm/v/http-server.svg?style=flat-square)](https://www.npmjs.com/package/http-server) | ||
[![license](https://img.shields.io/github/license/indexzero/http-server.svg?style=flat-square)](https://github.com/indexzero/http-server) | ||
[![license](https://img.shields.io/github/license/http-party/http-server.svg?style=flat-square)](https://github.com/http-party/http-server) | ||
@@ -20,2 +20,8 @@ # http-server: a command-line http server | ||
## Running on-demand: | ||
Using `npx` you can run the script without installing it first: | ||
npx http-server [path] [options] | ||
## Usage: | ||
@@ -29,16 +35,20 @@ | ||
**Note:** Caching is on by default. Add `-c-1` as an option to disable caching. | ||
## Available Options: | ||
`-p` Port to use (defaults to 8080) | ||
`-p` or `--port` Port to use (defaults to 8080) | ||
`-a` Address to use (defaults to 0.0.0.0) | ||
`-d` Show directory listings (defaults to 'True') | ||
`-d` Show directory listings (defaults to `true`) | ||
`-i` Display autoIndex (defaults to 'True') | ||
`-i` Display autoIndex (defaults to `true`) | ||
`-g` or `--gzip` When enabled (defaults to 'False') it will serve `./public/some-file.js.gz` in place of `./public/some-file.js` when a gzipped version of the file exists and the request accepts gzip encoding. | ||
`-g` or `--gzip` When enabled (defaults to `false`) it will serve `./public/some-file.js.gz` in place of `./public/some-file.js` when a gzipped version of the file exists and the request accepts gzip encoding. If brotli is also enabled, it will try to serve brotli first. | ||
`-e` or `--ext` Default file extension if none supplied (defaults to 'html') | ||
`-b` or `--brotli` When enabled (defaults to `false`) it will serve `./public/some-file.js.br` in place of `./public/some-file.js` when a brotli compressed version of the file exists and the request accepts `br` encoding. If gzip is also enabled, it will try to serve brotli first. | ||
`-e` or `--ext` Default file extension if none supplied (defaults to `html`) | ||
`-s` or `--silent` Suppress log messages from output | ||
@@ -48,20 +58,51 @@ | ||
`-o` Open browser window after starting the server | ||
`-o [path]` Open browser window after starting the server. Optionally provide a URL path to open. e.g.: -o /other/dir/ | ||
`-c` Set cache time (in seconds) for cache-control max-age header, e.g. -c10 for 10 seconds (defaults to '3600'). To disable caching, use -c-1. | ||
`-c` Set cache time (in seconds) for cache-control max-age header, e.g. `-c10` for 10 seconds (defaults to `3600`). To disable caching, use `-c-1`. | ||
`-U` or `--utc` Use UTC time format in log messages. | ||
`--log-ip` Enable logging of the client's IP address (default: `false`). | ||
`-P` or `--proxy` Proxies all requests which can't be resolved locally to the given url. e.g.: -P http://someurl.com | ||
`--username` Username for basic authentication [none] | ||
`--password` Password for basic authentication [none] | ||
`-S` or `--ssl` Enable https. | ||
`-C` or `--cert` Path to ssl cert file (default: cert.pem). | ||
`-C` or `--cert` Path to ssl cert file (default: `cert.pem`). | ||
`-K` or `--key` Path to ssl key file (default: key.pem). | ||
`-K` or `--key` Path to ssl key file (default: `key.pem`). | ||
`-r` or `--robots` Provide a /robots.txt (whose content defaults to 'User-agent: *\nDisallow: /') | ||
`-r` or `--robots` Provide a /robots.txt (whose content defaults to `User-agent: *\nDisallow: /`) | ||
`--no-dotfiles` Do not show dotfiles | ||
`-h` or `--help` Print this list and exit. | ||
## Magic Files | ||
- `index.html` will be served as the default file to any directory requests. | ||
- `404.html` will be served if a file is not found. This can be used for Single-Page App (SPA) hosting to serve the entry page. | ||
## Catch-all redirect | ||
To implement a catch-all redirect, use the index page itself as the proxy with: | ||
``` | ||
http-server --proxy http://localhost:8080? | ||
``` | ||
Note the `?` at the end of the proxy URL. Thanks to [@houston3](https://github.com/houston3) for this clever hack! | ||
## Need a self signed SSL Certificate? | ||
Create the `cert.pem` and `key.pem` via the command: | ||
``` | ||
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem | ||
``` | ||
# Development | ||
@@ -79,2 +120,2 @@ | ||
You should see the turtle image in the screenshot above hosted at that URL. See | ||
the `./public` folder for demo content. | ||
the `./public` folder for demo content. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19928
181
117
10
2
+ Addedbasic-auth@^1.0.3
+ Addedsecure-compare@3.0.1
+ Addedbasic-auth@1.1.0(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedcolors@1.4.0(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedobject-inspect@1.13.2(transitive)
+ Addedopener@1.5.2(transitive)
+ Addedqs@6.13.0(transitive)
+ Addedsecure-compare@3.0.1(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedside-channel@1.0.6(transitive)
+ Addedunion@0.5.0(transitive)
- Removedcolors@1.0.3(transitive)
- Removedopener@1.4.3(transitive)
- Removedqs@2.3.3(transitive)
- Removedunion@0.4.6(transitive)
Updatedcolors@^1.3.3
Updatedcorser@^2.0.1
Updatedecstatic@^3.3.2
Updatedhttp-proxy@^1.17.0
Updatedopener@^1.5.1
Updatedoptimist@~0.6.1
Updatedportfinder@^1.0.20
Updatedunion@~0.5.0