mirror of
https://github.com/arnaucube/socketioMEANseed.git
synced 2026-02-07 03:36:47 +01:00
init
This commit is contained in:
19
www/node_modules/ecstatic/.npmignore
generated
vendored
Normal file
19
www/node_modules/ecstatic/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
# Unicode filenames cause jenkins to barf when cleaning up workspaces
|
||||
# See: https://github.com/jfhbrook/node-ecstatic/issues/128
|
||||
test
|
||||
8
www/node_modules/ecstatic/.travis.yml
generated
vendored
Normal file
8
www/node_modules/ecstatic/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- 0.12
|
||||
- 0.10
|
||||
- 4.0
|
||||
- 4.1
|
||||
- 4.2
|
||||
84
www/node_modules/ecstatic/CHANGELOG.md
generated
vendored
Normal file
84
www/node_modules/ecstatic/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
2015/05/10 Version 1.4.1
|
||||
- Compare if-modified-since header against server-generated last-modified header rather than raw mtime
|
||||
|
||||
2015/12/22 Version 1.4.0
|
||||
- Add ability to specify custom mimetypes via a JSON blob (on the CLI)
|
||||
- Started test suite around CLI options parsing
|
||||
- Workaround for egregious v8 bug around date parsing throwing during modified-since checks
|
||||
|
||||
2015/11/15 Version 1.3.1
|
||||
- Add recent contributors to CONTRIBUTORS.md
|
||||
- Document showDotFiles in main options example
|
||||
|
||||
2015/11/14 Version 1.3.0
|
||||
- opts.showDotFiles allows hiding dot files
|
||||
|
||||
2015/11/03 Version 1.2.0
|
||||
- opts.cache supports function argument
|
||||
|
||||
2015/10/03 Version 1.1.3
|
||||
- Add CORS=false to defaults
|
||||
|
||||
2015/10/02 Version 1.1.2
|
||||
- Properly handle defaults in CLI args
|
||||
|
||||
2015/10/02 Version 1.1.1
|
||||
- Properly handle boolean CLI args
|
||||
|
||||
2015/10/01 Version 1.1.0
|
||||
- Adds support for responding to OPTIONS headers
|
||||
- Adds support for setting custom headers
|
||||
- Adds cors convenience setting
|
||||
|
||||
2015/09/22 Version 1.0.1
|
||||
- Use encodeURIComponent when creating links in showdir
|
||||
|
||||
2015/09/14 Version 1.0.0
|
||||
- Optional support for weak Etags and weak Etag *comparison*, useful for cases
|
||||
where one is running ecstatic with gzip behind an nginx proxy (these will
|
||||
likely be turned ON by default in a following major version)
|
||||
- As a bin, respects process.env.PORT when binding to a port
|
||||
- Directory listings encode pathnames, etc
|
||||
- Default status pages return html instead of text/plain
|
||||
- Contributors are listed in CONTRIBUTORS.md, referenced by LICENSE.txt
|
||||
|
||||
2015/05/22 Version 0.8.0
|
||||
- Add ability to define custom mime-types, inline or with Apache .types file
|
||||
- Test against express ^4.12.3 and union ^0.4.4
|
||||
- Run tests with tap ^1.0.3
|
||||
- Fix newline asserts to work with windows
|
||||
- Add license attribute to package.json
|
||||
- Elaborate contribution guidelines
|
||||
|
||||
2015/05/09 Version 0.7.6
|
||||
- Fix double encoding in directory listings
|
||||
|
||||
2015/05/07 Version 0.7.5
|
||||
- Fix HTML reflection vulnerability in certain error handlers
|
||||
|
||||
2015/04/17 Version 0.7.4
|
||||
- Fix sort ordering in directory listings
|
||||
|
||||
2015/04/13 Version 0.7.3
|
||||
- Close fstream if/when res closes, fixes potential fd leak
|
||||
|
||||
2015/04/05 Version 0.7.2
|
||||
- Correctly handle req.statusCode in recursive calls; do not inherit upstream res.statusCode
|
||||
|
||||
2015/03/27 Version 0.7.1
|
||||
- Treat ENOTDIR as 404 (same as ENOENT)
|
||||
|
||||
2015/03/18 Version 0.7.0
|
||||
- Add support for specifying default content-type (as an alternative to application/octet-stream)
|
||||
- Use url-join for autoIndex route, fixes windows problems
|
||||
|
||||
2015/03/01 Version 0.6.1
|
||||
- Fix handleError fall-through with directory listings
|
||||
|
||||
2015/02/16 Version 0.6.0
|
||||
- Fix for pathname decoding in windows
|
||||
- Fix for hrefs in directory listings
|
||||
- Add ability to turn off setting of Server header
|
||||
- Remove extraneous call to res.end (handled by stream pipe)
|
||||
- Remove tests from npm package due to jenkins bug
|
||||
- Start a ChangeLog.md
|
||||
86
www/node_modules/ecstatic/CONTRIBUTING.md
generated
vendored
Normal file
86
www/node_modules/ecstatic/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This is probably way overkill, but this is by far my most active project in
|
||||
terms of contributions, and somewhere along the way I was convinced that it
|
||||
was a good idea to have this in place sooner rather than later:
|
||||
|
||||
I want to provide a safe, healthy environment for all contributors/participants
|
||||
regardless of gender, sexual orientation, disability, race, religion, etc.
|
||||
As such, I don't tolerate harassment of participants in any form. In particular
|
||||
this applies to my issues tracker, but also to any other means of communication
|
||||
associated with this project that might come up. Anyone who violates these
|
||||
basic rules may be sanctioned/banned/have-their-comments-deleted/etc by my
|
||||
discretion.
|
||||
|
||||
Glad we cleared that up.
|
||||
|
||||
## Branching
|
||||
|
||||
Before working on your fix/feature/whatever, you should create a new branch to
|
||||
work on. Do something like:
|
||||
|
||||
```sh
|
||||
$ git checkout -b 'my-sweet-new-pull-request'
|
||||
```
|
||||
|
||||
## Please Please Please Start With A Test
|
||||
|
||||
ecstatic has some pretty gnarly branching/logic underneath. Tests are extremely
|
||||
important because they (a) prove that your feature/fix works, and (b) avoid
|
||||
regressions in the future. Even if your patch is problematic enough to not be
|
||||
merged, a test will still be very helpful for confirming any future fix.
|
||||
|
||||
I won't reject your patch outright if it's missing new tests, but it sure
|
||||
helps!
|
||||
|
||||
## Code Style
|
||||
|
||||
Ecstatic's code base follows a relatively consistent style. The closer your
|
||||
patch blends in with the status quo, the better.
|
||||
|
||||
A few PROTIPS off the top of my head:
|
||||
|
||||
1. Variables don't need to all be declared at the top, BUT variable *blocks*
|
||||
should do the whole one-var, tons-of-commas thing.
|
||||
2. Look at how spacing is done around conditionals and functions. Do it like
|
||||
that.
|
||||
3. `else`'s and similar should be on the line *after* the preceding bracket.
|
||||
|
||||
We can refine this as the need arises.
|
||||
|
||||
## A Few Other Minor Guidelines
|
||||
|
||||
1. Keep your pull requests on-topic. A pull request purporting to tackle A
|
||||
shouldn't also have commits changing B and C. Feel free to make separate pull
|
||||
requests. For instance: A pull request should generally only update
|
||||
dependencies when doing so is required to add the feature or fix the bug. This
|
||||
feature can, of course, consist of updating dependencies.
|
||||
2. I prefer maintaining the changelog and package.json version myself. This is
|
||||
because I try to make a single commit for a tagged release contain all
|
||||
changelog additions and the version bump, and this breaks down when there are
|
||||
interstitial commits making updates to either.
|
||||
3. In case you were wondering about dependencies, you may find this helpful:
|
||||
[](https://david-dm.org/jfhbrook/node-ecstatic)
|
||||
4. Please add yourself to CONTRIBUTORS.md if you haven't done so! Fill in as
|
||||
much as makes you comfortable.
|
||||
|
||||
## Pull Request
|
||||
|
||||
Make a pull request against master with your new branch. Explain briefly what
|
||||
the patch does to the code, along with any concerns.
|
||||
|
||||
(If you don't have a description, it's hard for me to put the changes in
|
||||
context. That makes it more difficult for me to merge!)
|
||||
|
||||
## Keep It Moving
|
||||
|
||||
I don't always notice new PRs, and sometimes I will forget to follow up on
|
||||
them. If this happens to you, you can bump the PR thread or find me on
|
||||
IRC or twitter.
|
||||
|
||||
## LAST RULE
|
||||
|
||||
HAVE FUN :v :v
|
||||
|
||||
57
www/node_modules/ecstatic/CONTRIBUTORS.md
generated
vendored
Normal file
57
www/node_modules/ecstatic/CONTRIBUTORS.md
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
General format is: contributor, github handle, email. In some cases, the
|
||||
contributor field is an organization instead of an actual person---this is for
|
||||
cases where the work was done on behalf of the organization, ie as part of
|
||||
their job. In others, no contributor field and/or email is shown---this is
|
||||
because this list was partially (mostly) reconstructed from github commit
|
||||
information and the person's real life name and email are unknown.
|
||||
|
||||
Listed in no particular order:
|
||||
|
||||
* Joshua Holbrook @jfhbrook <josh.holbrook@gmail.com>
|
||||
* Jon Ege Ronnenberg @dotnetCarpenter <jon.ronnenberg@gmail.com>
|
||||
* James Halliday @substack <substack@gmail.com>
|
||||
* Jonah Ruiz @jonahoffline <jonah@pixelhipsters.com>
|
||||
* Jacob Burden @jekrb <Jacob.JW.Burden@gmail.com>
|
||||
* @leesei
|
||||
* @SirAnthony
|
||||
* Frank Mecklenburg @yfr <mecklenburg@ubilabs.net>
|
||||
* @curimit <curimit@gmail.com>
|
||||
* Dominic Tarr @dominictarr
|
||||
* Chew Choon Keat @choonkeat <choonkeat@gmail.com>
|
||||
* Lars Kappert @webpro <lars@webpro.nl>
|
||||
* Alan Reyes @KuttKatrea <kutt@katrea.net>
|
||||
* Colin Fallon @colinf
|
||||
* Charlie Robbins @indexzero
|
||||
* Ville Salonen @VilleSalonen
|
||||
* Tom Steele @tomsteele <thomasjsteele@gmail.com>
|
||||
* Maciej Małecki @mmalecki <me@mmalecki.com>
|
||||
* Chris Bannister @Zariel <c.bannister@gmail.com>
|
||||
* Shinnosuke Watanabe @shinnn <snnskwtnb@gmail.com>
|
||||
* Adam Brady @SomeoneWeird <adam@boxxen.org>
|
||||
* Christian Howe @coderarity
|
||||
* Arnaud @amelon
|
||||
* Gilad Peleg @pgilad <giladp007@gmail.com>
|
||||
* Brad Dunbar @braddunbar <dunbarb2@gmail.com>
|
||||
* Google Inc. via Jeremy Banks @jre-g <jre@google.com>
|
||||
* @sundippatel
|
||||
* Arjan van Wijk @ThaNarie <thanarie@gmail.com>
|
||||
* Mathias Buus @mafintosh <mathiasbuus@gmail.com>
|
||||
* Farrin Reid @blakmatrix <blakmatrix@gmail.com>
|
||||
* Tõnis Tiigi @tonistiigi <tonistiigi@gmail.com>
|
||||
* Maksim Lin @maks <maks@manichord.com>
|
||||
* Jan Nicklas @jantimon
|
||||
* David Cox @losttime <losttime.shuffle@gmail.com>
|
||||
* Bill Ticehurst @billti <billti@hotmail.com>
|
||||
* Vincent Voyer @vvo <vincent.voyer@gmail.com>
|
||||
* @helloyou2012 <helloyou2012@gmail.com>
|
||||
* Domenic Denicola @domenic <d@domenic.me>
|
||||
* Maxim Ivanov @redbaron <ivanov.maxim@gmail.com>
|
||||
* Oliver Joseph Ash @OliverJAsh <oliverjash@gmail.com>
|
||||
* Benjamin Tan @d10 <demoneaux@gmail.com>
|
||||
* D Scott Boyce @scobo
|
||||
* Zach Bruggerman @remixz <mail@bruggie.com>
|
||||
* Mathias Bynens @mathiasbynens
|
||||
* Chris Lee @clee <clee@mg8.org>
|
||||
* Josh Duff @TehShrike
|
||||
* Cam Wiegert @camwiegert <cam@camwiegert.com>
|
||||
* Josh Gillies @joshgillies <github@joshgilli.es>
|
||||
22
www/node_modules/ecstatic/LICENSE.txt
generated
vendored
Normal file
22
www/node_modules/ecstatic/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2015 Joshua Holbrook and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
220
www/node_modules/ecstatic/README.md
generated
vendored
Normal file
220
www/node_modules/ecstatic/README.md
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
# Ecstatic [](http://travis-ci.org/jfhbrook/node-ecstatic)
|
||||
|
||||

|
||||
|
||||
A simple static file server middleware. Use it with a raw http server or
|
||||
express/connect!
|
||||
|
||||
# Examples:
|
||||
|
||||
## express 3.0.x
|
||||
|
||||
``` js
|
||||
var http = require('http');
|
||||
var express = require('express');
|
||||
var ecstatic = require('ecstatic');
|
||||
|
||||
var app = express();
|
||||
app.use(ecstatic({ root: __dirname + '/public' }));
|
||||
http.createServer(app).listen(8080);
|
||||
|
||||
console.log('Listening on :8080');
|
||||
```
|
||||
|
||||
## stock http server
|
||||
|
||||
``` js
|
||||
var http = require('http');
|
||||
var ecstatic = require('ecstatic');
|
||||
|
||||
http.createServer(
|
||||
ecstatic({ root: __dirname + '/public' })
|
||||
).listen(8080);
|
||||
|
||||
console.log('Listening on :8080');
|
||||
```
|
||||
### fall through
|
||||
To allow fall through to your custom routes:
|
||||
|
||||
```js
|
||||
ecstatic({ root: __dirname + '/public', handleError: false })
|
||||
```
|
||||
|
||||
# API:
|
||||
|
||||
## ecstatic(opts);
|
||||
|
||||
Pass ecstatic an options hash, and it will return your middleware!
|
||||
|
||||
```js
|
||||
var opts = {
|
||||
root : __dirname + '/public',
|
||||
port : 8000,
|
||||
baseDir : '/',
|
||||
cache : 3600,
|
||||
showDir : true,
|
||||
showDotfiles : true,
|
||||
autoIndex : false,
|
||||
humanReadable : true,
|
||||
headers : {},
|
||||
si : false,
|
||||
defaultExt : 'html',
|
||||
gzip : false,
|
||||
serverHeader : true,
|
||||
contentType : 'application/octet-stream',
|
||||
mimeTypes : undefined,
|
||||
handleOptionsMethod: false
|
||||
}
|
||||
```
|
||||
|
||||
If `opts` is a string, the string is assigned to the root folder and all other
|
||||
options are set to their defaults.
|
||||
|
||||
### `opts.root`
|
||||
|
||||
`opts.root` is the directory you want to serve up.
|
||||
|
||||
### `opts.port`
|
||||
|
||||
`opts.port` is the port you want ecstatic to listen to. Defaults to 8000.
|
||||
|
||||
### `opts.baseDir`
|
||||
|
||||
`opts.baseDir` is `/` by default, but can be changed to allow your static files
|
||||
to be served off a specific route. For example, if `opts.baseDir === "blog"`
|
||||
and `opts.root = "./public"`, requests for `localhost:8080/blog/index.html` will
|
||||
resolve to `./public/index.html`.
|
||||
|
||||
### `opts.cache`
|
||||
|
||||
Customize cache control with `opts.cache` , if it is a number then it will set max-age in seconds.
|
||||
Other wise it will pass through directly to cache-control. Time defaults to 3600 s (ie, 1 hour).
|
||||
|
||||
If it is a function, it will be executed on every request, and passed the pathname. Whatever it returns, string or number, will be used as the cache control header like above.
|
||||
|
||||
### `opts.showDir`
|
||||
|
||||
Turn **off** directory listings with `opts.showDir === false`. Defaults to **true**.
|
||||
|
||||
### `opts.showDotfiles`
|
||||
|
||||
Exclude dotfiles from directory listings with `opts.showDotfiles === false`. Defaults to **true**.
|
||||
|
||||
### `opts.humanReadable`
|
||||
|
||||
If showDir is enabled, add human-readable file sizes. Defaults to **true**.
|
||||
Aliases are `humanreadable` and `human-readable`.
|
||||
|
||||
### `opts.headers`
|
||||
|
||||
Set headers on every response. `opts.headers` can be an object mapping string
|
||||
header names to string header values, a colon (:) separated string, or an array
|
||||
of colon separated strings.
|
||||
|
||||
`opts.H` and `opts.header` are aliased to `opts.headers` so that you can use
|
||||
`-H` and `--header` options to set headers on the command-line like curl:
|
||||
|
||||
``` sh
|
||||
$ ecstatic ./public -p 5000 -H 'Access-Control-Allow-Origin: *'
|
||||
```
|
||||
|
||||
### `opts.si`
|
||||
|
||||
If showDir and humanReadable are enabled, print file sizes with base 1000 instead
|
||||
of base 1024. Name is inferred from cli options for `ls`. Aliased to `index`, the
|
||||
equivalent option in Apache.
|
||||
|
||||
### `opts.autoIndex`
|
||||
|
||||
Serve `/path/index.html` when `/path/` is requested.
|
||||
Turn **off** autoIndexing with `opts.autoIndex === false`. Defaults to **true**.
|
||||
|
||||
### `opts.defaultExt`
|
||||
|
||||
Turn on default file extensions with `opts.defaultExt`. If `opts.defaultExt` is
|
||||
true, it will default to `html`. For example if you want a request to `/a-file`
|
||||
to resolve to `./public/a-file.html`, set this to `true`. If you want
|
||||
`/a-file` to resolve to `./public/a-file.json` instead, set `opts.defaultExt` to
|
||||
`json`.
|
||||
|
||||
### `opts.gzip`
|
||||
|
||||
Set `opts.gzip === true` in order to turn on "gzip mode," wherein ecstatic will
|
||||
serve `./public/some-file.js.gz` in place of `./public/some-file.js` when the
|
||||
gzipped version exists and ecstatic determines that the behavior is appropriate.
|
||||
|
||||
### `opts.serverHeader`
|
||||
|
||||
Set `opts.serverHeader` to false in order to turn off setting the `Server` header
|
||||
on all responses served by ecstatic.
|
||||
|
||||
### `opts.contentType`
|
||||
|
||||
Set `opts.contentType` in order to change default Content-Type header value.
|
||||
Defaults to **application/octet-stream**.
|
||||
|
||||
### `opts.mimeTypes`
|
||||
|
||||
Add new or override one or more mime-types. This affects the HTTP Content-Type header.
|
||||
Can either be a path to a [`.types`](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) file or an object hash of type(s).
|
||||
|
||||
ecstatic({ mimeType: { 'mime-type': ['file_extension', 'file_extension'] } })
|
||||
|
||||
### `opts.handleError`
|
||||
|
||||
Turn **off** handleErrors to allow fall-through with `opts.handleError === false`, Defaults to **true**.
|
||||
|
||||
### `opts.weakEtags`
|
||||
|
||||
Set `opts.weakEtags` to true in order to generate weak etags instead of strong etags. Defaults to **false**. See `opts.weakCompare` as well.
|
||||
|
||||
### `opts.weakCompare`
|
||||
|
||||
Turn **on** weakCompare to allow the weak comparison function for etag validation. Defaults to **false**.
|
||||
See https://www.ietf.org/rfc/rfc2616.txt Section 13.3.3 for more details.
|
||||
|
||||
### `opts.handleOptionsMethod`
|
||||
|
||||
Set handleOptionsMethod to true in order to respond to 'OPTIONS' calls with any standard/set headers. Defaults to **false**. Useful for hacking up CORS support.
|
||||
|
||||
### `opts.cors`
|
||||
|
||||
This is a **convenience** setting which turns on `handleOptionsMethod` and sets the headers **Access-Control-Allow-Origin: \*** and **Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since**. This *should* be enough to quickly make cross-origin resource sharing work between development APIs. More advanced usage can come either from overriding these headers with the headers argument, or by using the `handleOptionsMethod` flag and then setting headers "manually." Alternately, just do it in your app using separate middlewares/abstractions.
|
||||
|
||||
Defaults to **false**.
|
||||
|
||||
## middleware(req, res, next);
|
||||
|
||||
This works more or less as you'd expect.
|
||||
|
||||
### ecstatic.showDir(folder);
|
||||
|
||||
This returns another middleware which will attempt to show a directory view. Turning on auto-indexing is roughly equivalent to adding this middleware after an ecstatic middleware with autoindexing disabled.
|
||||
|
||||
### `ecstatic` command
|
||||
|
||||
to start a standalone static http server,
|
||||
run `npm install -g ecstatic` and then run `ecstatic [dir?] [options] --port PORT`
|
||||
all options work as above, passed in [optimist](https://github.com/substack/node-optimist) style.
|
||||
`port` defaults to `8000`. If a `dir` or `--root dir` argument is not passed, ecsatic will
|
||||
serve the current dir. Ecstatic also respects the PORT environment variable.
|
||||
|
||||
# Tests:
|
||||
|
||||
Ecstatic has a fairly extensive test suite. You can run it with:
|
||||
|
||||
```sh
|
||||
$ npm test
|
||||
```
|
||||
|
||||
# Contribute:
|
||||
|
||||
Without outside contributions, ecstatic would wither and die! Before
|
||||
contributing, take a quick look at the contributing guidelines in
|
||||
[./CONTRIBUTING.md](./CONTRIBUTING.md) . They're relatively painless, I promise.
|
||||
For Windows users, it is especially important to read the [./CONTRIBUTING.md](./CONTRIBUTING.md)
|
||||
section as you can **not** clone ecstatic without changing some settings in git.
|
||||
|
||||
# License:
|
||||
|
||||
MIT. See LICENSE.txt. For contributors, see CONTRIBUTORS.md
|
||||
10
www/node_modules/ecstatic/example/core.js
generated
vendored
Normal file
10
www/node_modules/ecstatic/example/core.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
var http = require('http');
|
||||
var ecstatic = require('../lib/ecstatic')({
|
||||
root: __dirname + '/public',
|
||||
showDir: true,
|
||||
autoIndex: true
|
||||
});
|
||||
|
||||
http.createServer(ecstatic).listen(8080);
|
||||
|
||||
console.log('Listening on :8080');
|
||||
12
www/node_modules/ecstatic/example/express.js
generated
vendored
Normal file
12
www/node_modules/ecstatic/example/express.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
var express = require('express');
|
||||
var ecstatic = require('../lib/ecstatic');
|
||||
var http = require('http');
|
||||
|
||||
var app = express();
|
||||
app.use(ecstatic({
|
||||
root: __dirname + '/public',
|
||||
showdir : true
|
||||
}));
|
||||
http.createServer(app).listen(8080);
|
||||
|
||||
console.log('Listening on :8080');
|
||||
1
www/node_modules/ecstatic/example/public/beep/index.html
generated
vendored
Normal file
1
www/node_modules/ecstatic/example/public/beep/index.html
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<b>boop!</b>
|
||||
1
www/node_modules/ecstatic/example/public/hello.txt
generated
vendored
Normal file
1
www/node_modules/ecstatic/example/public/hello.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello world!
|
||||
1
www/node_modules/ecstatic/example/public/subdir/world.txt
generated
vendored
Normal file
1
www/node_modules/ecstatic/example/public/subdir/world.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
hello cruel world!
|
||||
BIN
www/node_modules/ecstatic/example/public/turtle.png
generated
vendored
Normal file
BIN
www/node_modules/ecstatic/example/public/turtle.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
10
www/node_modules/ecstatic/example/union.js
generated
vendored
Normal file
10
www/node_modules/ecstatic/example/union.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
var union = require('union');
|
||||
var ecstatic = require('../');
|
||||
|
||||
union.createServer({
|
||||
before: [
|
||||
ecstatic(__dirname + '/public')
|
||||
]
|
||||
}).listen(8080);
|
||||
|
||||
console.log('Listening on :8080');
|
||||
371
www/node_modules/ecstatic/lib/ecstatic.js
generated
vendored
Executable file
371
www/node_modules/ecstatic/lib/ecstatic.js
generated
vendored
Executable file
@@ -0,0 +1,371 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs'),
|
||||
url = require('url'),
|
||||
mime = require('mime'),
|
||||
urlJoin = require('url-join'),
|
||||
showDir = require('./ecstatic/showdir'),
|
||||
version = JSON.parse(
|
||||
fs.readFileSync(__dirname + '/../package.json').toString()
|
||||
).version,
|
||||
status = require('./ecstatic/status-handlers'),
|
||||
generateEtag = require('./ecstatic/etag'),
|
||||
optsParser = require('./ecstatic/opts');
|
||||
|
||||
var ecstatic = module.exports = function (dir, options) {
|
||||
if (typeof dir !== 'string') {
|
||||
options = dir;
|
||||
dir = options.root;
|
||||
}
|
||||
|
||||
var root = path.join(path.resolve(dir), '/'),
|
||||
opts = optsParser(options),
|
||||
cache = opts.cache,
|
||||
autoIndex = opts.autoIndex,
|
||||
baseDir = opts.baseDir,
|
||||
defaultExt = opts.defaultExt,
|
||||
handleError = opts.handleError,
|
||||
headers = opts.headers,
|
||||
serverHeader = opts.serverHeader,
|
||||
weakEtags = opts.weakEtags,
|
||||
handleOptionsMethod = opts.handleOptionsMethod;
|
||||
|
||||
opts.root = dir;
|
||||
if (defaultExt && /^\./.test(defaultExt)) defaultExt = defaultExt.replace(/^\./, '');
|
||||
|
||||
// Support hashes and .types files in mimeTypes @since 0.8
|
||||
if (opts.mimeTypes) {
|
||||
try {
|
||||
// You can pass a JSON blob here---useful for CLI use
|
||||
opts.mimeTypes = JSON.parse(opts.mimeTypes);
|
||||
} catch (e) {}
|
||||
if (typeof opts.mimeTypes === 'string') {
|
||||
mime.load(opts.mimeTypes);
|
||||
}
|
||||
else if (typeof opts.mimeTypes === 'object') {
|
||||
mime.define(opts.mimeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return function middleware (req, res, next) {
|
||||
|
||||
// Strip any null bytes from the url
|
||||
while(req.url.indexOf('%00') !== -1) {
|
||||
req.url = req.url.replace(/\%00/g, '');
|
||||
}
|
||||
// Figure out the path for the file from the given url
|
||||
var parsed = url.parse(req.url);
|
||||
try {
|
||||
decodeURIComponent(req.url); // check validity of url
|
||||
var pathname = decodePathname(parsed.pathname);
|
||||
}
|
||||
catch (err) {
|
||||
return status[400](res, next, { error: err });
|
||||
}
|
||||
|
||||
var file = path.normalize(
|
||||
path.join(root,
|
||||
path.relative(
|
||||
path.join('/', baseDir),
|
||||
pathname
|
||||
)
|
||||
)
|
||||
),
|
||||
gzipped = file + '.gz';
|
||||
|
||||
if(serverHeader !== false) {
|
||||
// Set common headers.
|
||||
res.setHeader('server', 'ecstatic-'+version);
|
||||
}
|
||||
Object.keys(headers).forEach(function (key) {
|
||||
res.setHeader(key, headers[key])
|
||||
})
|
||||
|
||||
if (req.method === 'OPTIONS' && handleOptionsMethod) {
|
||||
return res.end();
|
||||
}
|
||||
|
||||
// TODO: This check is broken, which causes the 403 on the
|
||||
// expected 404.
|
||||
if (file.slice(0, root.length) !== root) {
|
||||
return status[403](res, next);
|
||||
}
|
||||
|
||||
if (req.method && (req.method !== 'GET' && req.method !== 'HEAD' )) {
|
||||
return status[405](res, next);
|
||||
}
|
||||
|
||||
function statFile() {
|
||||
fs.stat(file, function (err, stat) {
|
||||
if (err && (err.code === 'ENOENT' || err.code === 'ENOTDIR')) {
|
||||
if (req.statusCode == 404) {
|
||||
// This means we're already trying ./404.html and can not find it.
|
||||
// So send plain text response with 404 status code
|
||||
status[404](res, next);
|
||||
}
|
||||
else if (!path.extname(parsed.pathname).length && defaultExt) {
|
||||
// If there is no file extension in the path and we have a default
|
||||
// extension try filename and default extension combination before rendering 404.html.
|
||||
middleware({
|
||||
url: parsed.pathname + '.' + defaultExt + ((parsed.search)? parsed.search:'')
|
||||
}, res, next);
|
||||
}
|
||||
else {
|
||||
// Try to serve default ./404.html
|
||||
middleware({
|
||||
url: (handleError ? ('/' + path.join(baseDir, '404.' + defaultExt)) : req.url),
|
||||
statusCode: 404
|
||||
}, res, next);
|
||||
}
|
||||
}
|
||||
else if (err) {
|
||||
status[500](res, next, { error: err });
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
// 302 to / if necessary
|
||||
if (!parsed.pathname.match(/\/$/)) {
|
||||
res.statusCode = 302;
|
||||
res.setHeader('location', parsed.pathname + '/' +
|
||||
(parsed.query? ('?' + parsed.query):'')
|
||||
);
|
||||
return res.end();
|
||||
}
|
||||
|
||||
if (autoIndex) {
|
||||
return middleware({
|
||||
url: urlJoin(encodeURIComponent(pathname), '/index.' + defaultExt)
|
||||
}, res, function (err) {
|
||||
if (err) {
|
||||
return status[500](res, next, { error: err });
|
||||
}
|
||||
if (opts.showDir) {
|
||||
return showDir(opts, stat)(req, res);
|
||||
}
|
||||
|
||||
return status[403](res, next);
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.showDir) {
|
||||
return showDir(opts, stat)(req, res);
|
||||
}
|
||||
|
||||
status[404](res, next);
|
||||
|
||||
}
|
||||
else {
|
||||
serve(stat);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Look for a gzipped file if this is turned on
|
||||
if (opts.gzip && shouldCompress(req)) {
|
||||
fs.stat(gzipped, function (err, stat) {
|
||||
if (!err && stat.isFile()) {
|
||||
file = gzipped;
|
||||
return serve(stat);
|
||||
} else {
|
||||
statFile();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
statFile();
|
||||
}
|
||||
|
||||
function serve(stat) {
|
||||
// Do a MIME lookup, fall back to octet-stream and handle gzip
|
||||
// special case.
|
||||
var defaultType = opts.contentType || 'application/octet-stream',
|
||||
contentType = mime.lookup(file, defaultType),
|
||||
charSet;
|
||||
|
||||
if (contentType) {
|
||||
charSet = mime.charsets.lookup(contentType, 'utf-8');
|
||||
if (charSet) {
|
||||
contentType += '; charset=' + charSet;
|
||||
}
|
||||
}
|
||||
|
||||
if (path.extname(file) === '.gz') {
|
||||
res.setHeader('Content-Encoding', 'gzip');
|
||||
|
||||
// strip gz ending and lookup mime type
|
||||
contentType = mime.lookup(path.basename(file, ".gz"), defaultType);
|
||||
}
|
||||
|
||||
var range = (req.headers && req.headers['range']);
|
||||
if (range) {
|
||||
var total = stat.size;
|
||||
var parts = range.replace(/bytes=/, "").split("-");
|
||||
var partialstart = parts[0];
|
||||
var partialend = parts[1];
|
||||
var start = parseInt(partialstart, 10);
|
||||
var end = Math.min(total-1, partialend ? parseInt(partialend, 10) : total-1);
|
||||
var chunksize = (end-start)+1;
|
||||
if (start > end || isNaN(start) || isNaN(end)) {
|
||||
return status['416'](res, next);
|
||||
}
|
||||
var fstream = fs.createReadStream(file, {start: start, end: end});
|
||||
fstream.on('error', function (err) {
|
||||
status['500'](res, next, { error: err });
|
||||
});
|
||||
res.on('close', function () {
|
||||
fstream.destroy();
|
||||
});
|
||||
res.writeHead(206, {
|
||||
'Content-Range': 'bytes ' + start + '-' + end + '/' + total,
|
||||
'Accept-Ranges': 'bytes',
|
||||
'Content-Length': chunksize,
|
||||
'Content-Type': contentType
|
||||
});
|
||||
fstream.pipe(res);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Helper for this, with default headers.
|
||||
var lastModified = (new Date(stat.mtime)).toUTCString(),
|
||||
etag = generateEtag(stat, weakEtags);
|
||||
res.setHeader('last-modified', lastModified);
|
||||
res.setHeader('etag', etag);
|
||||
|
||||
if (typeof cache === 'function') {
|
||||
var requestSpecificCache = cache(pathname);
|
||||
if (typeof requestSpecificCache === 'number') {
|
||||
requestSpecificCache = 'max-age=' + requestSpecificCache;
|
||||
}
|
||||
res.setHeader('cache-control', requestSpecificCache);
|
||||
} else {
|
||||
res.setHeader('cache-control', cache);
|
||||
}
|
||||
|
||||
// Return a 304 if necessary
|
||||
if (shouldReturn304(req, lastModified, etag)) {
|
||||
return status[304](res, next);
|
||||
}
|
||||
|
||||
res.setHeader('content-length', stat.size);
|
||||
res.setHeader('content-type', contentType);
|
||||
|
||||
// set the response statusCode if we have a request statusCode.
|
||||
// This only can happen if we have a 404 with some kind of 404.html
|
||||
// In all other cases where we have a file we serve the 200
|
||||
res.statusCode = req.statusCode || 200;
|
||||
|
||||
if (req.method === "HEAD") {
|
||||
return res.end();
|
||||
}
|
||||
|
||||
var stream = fs.createReadStream(file);
|
||||
|
||||
stream.pipe(res);
|
||||
stream.on('error', function (err) {
|
||||
status['500'](res, next, { error: err });
|
||||
});
|
||||
}
|
||||
|
||||
function shouldReturn304(req, serverLastModified, serverEtag) {
|
||||
if (!req || !req.headers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var clientModifiedSince = req.headers['if-modified-since'],
|
||||
clientEtag = req.headers['if-none-match'];
|
||||
|
||||
if (!clientModifiedSince && !clientEtag) {
|
||||
// Client did not provide any conditional caching headers
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clientModifiedSince) {
|
||||
// Catch "illegal access" dates that will crash v8
|
||||
// https://github.com/jfhbrook/node-ecstatic/pull/179
|
||||
try {
|
||||
var clientModifiedDate = new Date(Date.parse(clientModifiedSince));
|
||||
}
|
||||
catch (err) { return false }
|
||||
|
||||
if (clientModifiedDate.toString() === 'Invalid Date') {
|
||||
return false;
|
||||
}
|
||||
// If the client's copy is older than the server's, don't return 304
|
||||
if (clientModifiedDate < new Date(serverLastModified)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (clientEtag) {
|
||||
// Do a strong or weak etag comparison based on setting
|
||||
// https://www.ietf.org/rfc/rfc2616.txt Section 13.3.3
|
||||
if (opts.weakCompare && clientEtag !== serverEtag
|
||||
&& clientEtag !== ('W/' + serverEtag) && ('W/' + clientEtag) !== serverEtag) {
|
||||
return false;
|
||||
} else if (!opts.weakCompare && (clientEtag !== serverEtag || clientEtag.indexOf('W/') === 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ecstatic.version = version;
|
||||
ecstatic.showDir = showDir;
|
||||
|
||||
// Check to see if we should try to compress a file with gzip.
|
||||
function shouldCompress(req) {
|
||||
var headers = req.headers;
|
||||
|
||||
return headers && headers['accept-encoding'] &&
|
||||
headers['accept-encoding']
|
||||
.split(",")
|
||||
.some(function (el) {
|
||||
return ['*','compress', 'gzip', 'deflate'].indexOf(el) != -1;
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
// See: https://github.com/jesusabdullah/node-ecstatic/issues/109
|
||||
function decodePathname(pathname) {
|
||||
var pieces = pathname.replace(/\\/g,"/").split('/');
|
||||
|
||||
return pieces.map(function (piece) {
|
||||
piece = decodeURIComponent(piece);
|
||||
|
||||
if (process.platform === 'win32' && /\\/.test(piece)) {
|
||||
throw new Error('Invalid forward slash character');
|
||||
}
|
||||
|
||||
return piece;
|
||||
}).join('/');
|
||||
}
|
||||
|
||||
if (!module.parent) {
|
||||
var defaults = require('./ecstatic/defaults.json')
|
||||
var http = require('http'),
|
||||
opts = require('minimist')(process.argv.slice(2), {
|
||||
alias: require('./ecstatic/aliases.json'),
|
||||
default: defaults,
|
||||
boolean: Object.keys(defaults).filter(function (key) {
|
||||
return typeof defaults[key] === 'boolean'
|
||||
})
|
||||
}),
|
||||
envPORT = parseInt(process.env.PORT, 10),
|
||||
port = envPORT > 1024 && envPORT <= 65536 ? envPORT : opts.port || opts.p || 8000,
|
||||
dir = opts.root || opts._[0] || process.cwd();
|
||||
|
||||
if (opts.help || opts.h) {
|
||||
var u = console.error;
|
||||
u('usage: ecstatic [dir] {options} --port PORT');
|
||||
u('see https://npm.im/ecstatic for more docs');
|
||||
return;
|
||||
}
|
||||
|
||||
http.createServer(ecstatic(dir, opts))
|
||||
.listen(port, function () {
|
||||
console.log('ecstatic serving ' + dir + ' at http://0.0.0.0:' + port);
|
||||
});
|
||||
}
|
||||
34
www/node_modules/ecstatic/lib/ecstatic/aliases.json
generated
vendored
Normal file
34
www/node_modules/ecstatic/lib/ecstatic/aliases.json
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"autoIndex": [ "autoIndex", "autoindex" ],
|
||||
"showDir": [ "showDir", "showdir" ],
|
||||
"showDotfiles": ["showDotfiles", "showdotfiles"],
|
||||
"humanReadable": [ "humanReadable", "humanreadable", "human-readable" ],
|
||||
"si": [ "si", "index" ],
|
||||
"handleError": [ "handleError", "handleerror" ],
|
||||
"cors": [ "cors", "CORS" ],
|
||||
"headers": [ "H", "header", "headers" ],
|
||||
"serverHeader": [ "serverHeader", "serverheader", "server-header" ],
|
||||
"contentType": [ "contentType", "contenttype", "content-type" ],
|
||||
"mimeType": [
|
||||
"mimetype",
|
||||
"mimetypes",
|
||||
"mimeType",
|
||||
"mimeTypes",
|
||||
"mime-type",
|
||||
"mime-types",
|
||||
"mime-Type",
|
||||
"mime-Types"
|
||||
],
|
||||
"weakEtags": [ "weakEtags", "weaketags", "weak-etags" ],
|
||||
"weakCompare": [
|
||||
"weakcompare",
|
||||
"weakCompare",
|
||||
"weak-compare",
|
||||
"weak-Compare"
|
||||
],
|
||||
"handleOptionsMethod": [
|
||||
"handleOptionsMethod",
|
||||
"handleoptionsmethod",
|
||||
"handle-options-method"
|
||||
]
|
||||
}
|
||||
17
www/node_modules/ecstatic/lib/ecstatic/defaults.json
generated
vendored
Normal file
17
www/node_modules/ecstatic/lib/ecstatic/defaults.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"autoIndex": true,
|
||||
"showDir": true,
|
||||
"showDotfiles": true,
|
||||
"humanReadable": true,
|
||||
"si": false,
|
||||
"cache": "max-age=3600",
|
||||
"cors": false,
|
||||
"gzip": false,
|
||||
"defaultExt": ".html",
|
||||
"handleError": true,
|
||||
"serverHeader": true,
|
||||
"contentType": "application/octet-stream",
|
||||
"weakEtags": false,
|
||||
"weakCompare": false,
|
||||
"handleOptionsMethod": false
|
||||
}
|
||||
7
www/node_modules/ecstatic/lib/ecstatic/etag.js
generated
vendored
Normal file
7
www/node_modules/ecstatic/lib/ecstatic/etag.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = function (stat, weakEtag) {
|
||||
var etag = '"' + [stat.ino, stat.size, JSON.stringify(stat.mtime)].join('-') + '"';
|
||||
if (weakEtag) {
|
||||
etag = 'W/' + etag;
|
||||
}
|
||||
return etag;
|
||||
}
|
||||
180
www/node_modules/ecstatic/lib/ecstatic/opts.js
generated
vendored
Normal file
180
www/node_modules/ecstatic/lib/ecstatic/opts.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
// This is so you can have options aliasing and defaults in one place.
|
||||
|
||||
var defaults = require('./defaults.json');
|
||||
var aliases = require('./aliases.json')
|
||||
|
||||
module.exports = function (opts) {
|
||||
var autoIndex = defaults.autoIndex,
|
||||
showDir = defaults.showDir,
|
||||
showDotfiles = defaults.showDotfiles,
|
||||
humanReadable = defaults.humanReadable,
|
||||
si = defaults.si,
|
||||
cache = defaults.cache,
|
||||
gzip = defaults.gzip,
|
||||
defaultExt = defaults.defaultExt,
|
||||
handleError = defaults.handleError,
|
||||
headers = {},
|
||||
serverHeader = defaults.serverHeader,
|
||||
contentType = defaults.contentType,
|
||||
mimeTypes,
|
||||
weakEtags = defaults.weakEtags,
|
||||
weakCompare = defaults.weakCompare,
|
||||
handleOptionsMethod = defaults.handleOptionsMethod;
|
||||
|
||||
function isDeclared(k) {
|
||||
return typeof opts[k] !== 'undefined' && opts[k] !== null;
|
||||
}
|
||||
|
||||
if (opts) {
|
||||
aliases.autoIndex.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
autoIndex = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.showDir.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
showDir = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.showDotfiles.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
showDotfiles = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.humanReadable.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
humanReadable = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.si.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
si = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (opts.defaultExt && typeof opts.defaultExt === 'string') {
|
||||
defaultExt = opts.defaultExt;
|
||||
}
|
||||
|
||||
if (typeof opts.cache !== 'undefined' && opts.cache !== null) {
|
||||
if (typeof opts.cache === 'string') {
|
||||
cache = opts.cache;
|
||||
}
|
||||
else if (typeof opts.cache === 'number') {
|
||||
cache = 'max-age=' + opts.cache;
|
||||
}
|
||||
else if (typeof opts.cache === 'function') {
|
||||
cache = opts.cache
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof opts.gzip !== 'undefined' && opts.gzip !== null) {
|
||||
gzip = opts.gzip;
|
||||
}
|
||||
|
||||
aliases.handleError.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
handleError = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.cors.forEach(function(k) {
|
||||
if (isDeclared(k) && k) {
|
||||
handleOptionsMethod = true;
|
||||
headers['Access-Control-Allow-Origin'] = '*';
|
||||
headers['Access-Control-Allow-Headers'] = 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since';
|
||||
}
|
||||
});
|
||||
|
||||
aliases.headers.forEach(function (k) {
|
||||
if (!isDeclared(k)) return;
|
||||
if (Array.isArray(opts[k])) {
|
||||
opts[k].forEach(setHeader);
|
||||
}
|
||||
else if (opts[k] && typeof opts[k] === 'object') {
|
||||
Object.keys(opts[k]).forEach(function (key) {
|
||||
headers[key] = opts[k][key];
|
||||
});
|
||||
}
|
||||
else setHeader(opts[k]);
|
||||
|
||||
function setHeader (str) {
|
||||
var m = /^(.+?)\s*:\s*(.*)$/.exec(str)
|
||||
if (!m) headers[str] = true
|
||||
else headers[m[1]] = m[2]
|
||||
}
|
||||
});
|
||||
|
||||
aliases.serverHeader.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
serverHeader = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.contentType.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
contentType = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.mimeType.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
mimeTypes = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.weakEtags.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
weakEtags = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.weakCompare.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
weakCompare = opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
aliases.handleOptionsMethod.some(function (k) {
|
||||
if (isDeclared(k)) {
|
||||
handleOptionsMethod = handleOptionsMethod || opts[k];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
cache: cache,
|
||||
autoIndex: autoIndex,
|
||||
showDir: showDir,
|
||||
showDotfiles: showDotfiles,
|
||||
humanReadable: humanReadable,
|
||||
si: si,
|
||||
defaultExt: defaultExt,
|
||||
baseDir: (opts && opts.baseDir) || '/',
|
||||
gzip: gzip,
|
||||
handleError: handleError,
|
||||
headers: headers,
|
||||
serverHeader: serverHeader,
|
||||
contentType: contentType,
|
||||
mimeTypes: mimeTypes,
|
||||
weakEtags: weakEtags,
|
||||
weakCompare: weakCompare,
|
||||
handleOptionsMethod: handleOptionsMethod
|
||||
};
|
||||
};
|
||||
224
www/node_modules/ecstatic/lib/ecstatic/showdir.js
generated
vendored
Normal file
224
www/node_modules/ecstatic/lib/ecstatic/showdir.js
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
var ecstatic = require('../ecstatic'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
he = require('he'),
|
||||
etag = require('./etag'),
|
||||
url = require('url'),
|
||||
status = require('./status-handlers');
|
||||
|
||||
module.exports = function (opts, stat) {
|
||||
// opts are parsed by opts.js, defaults already applied
|
||||
var cache = opts.cache,
|
||||
root = path.resolve(opts.root),
|
||||
baseDir = opts.baseDir,
|
||||
humanReadable = opts.humanReadable,
|
||||
handleError = opts.handleError,
|
||||
showDotfiles = opts.showDotfiles,
|
||||
si = opts.si,
|
||||
weakEtags = opts.weakEtags;
|
||||
|
||||
return function middleware (req, res, next) {
|
||||
|
||||
// Figure out the path for the file from the given url
|
||||
var parsed = url.parse(req.url),
|
||||
pathname = decodeURIComponent(parsed.pathname),
|
||||
dir = path.normalize(
|
||||
path.join(root,
|
||||
path.relative(
|
||||
path.join('/', baseDir),
|
||||
pathname
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
fs.stat(dir, function (err, stat) {
|
||||
if (err) {
|
||||
return handleError ? status[500](res, next, { error: err }) : next();
|
||||
}
|
||||
|
||||
// files are the listing of dir
|
||||
fs.readdir(dir, function (err, files) {
|
||||
if (err) {
|
||||
return handleError ? status[500](res, next, { error: err }) : next();
|
||||
}
|
||||
|
||||
// Optionally exclude dotfiles from directory listing.
|
||||
if (!showDotfiles) {
|
||||
files = files.filter(function(filename){
|
||||
return filename.slice(0,1) !== '.';
|
||||
});
|
||||
}
|
||||
|
||||
res.setHeader('content-type', 'text/html');
|
||||
res.setHeader('etag', etag(stat, weakEtags));
|
||||
res.setHeader('last-modified', (new Date(stat.mtime)).toUTCString());
|
||||
res.setHeader('cache-control', cache);
|
||||
|
||||
sortByIsDirectory(files, function (lolwuts, dirs, files) {
|
||||
// It's possible to get stat errors for all sorts of reasons here.
|
||||
// Unfortunately, our two choices are to either bail completely,
|
||||
// or just truck along as though everything's cool. In this case,
|
||||
// I decided to just tack them on as "??!?" items along with dirs
|
||||
// and files.
|
||||
//
|
||||
// Whatever.
|
||||
|
||||
// if it makes sense to, add a .. link
|
||||
if (path.resolve(dir, '..').slice(0, root.length) == root) {
|
||||
return fs.stat(path.join(dir, '..'), function (err, s) {
|
||||
if (err) {
|
||||
return handleError ? status[500](res, next, { error: err }) : next();
|
||||
}
|
||||
dirs.unshift([ '..', s ]);
|
||||
render(dirs, files, lolwuts);
|
||||
});
|
||||
}
|
||||
render(dirs, files, lolwuts);
|
||||
});
|
||||
|
||||
function sortByIsDirectory(paths, cb) {
|
||||
// take the listing file names in `dir`
|
||||
// returns directory and file array, each entry is
|
||||
// of the array a [name, stat] tuple
|
||||
var pending = paths.length,
|
||||
errs = [],
|
||||
dirs = [],
|
||||
files = [];
|
||||
|
||||
if (!pending) {
|
||||
return cb(errs, dirs, files);
|
||||
}
|
||||
|
||||
paths.forEach(function (file) {
|
||||
fs.stat(path.join(dir, file), function (err, s) {
|
||||
if (err) {
|
||||
errs.push([file, err]);
|
||||
}
|
||||
else if (s.isDirectory()) {
|
||||
dirs.push([file, s]);
|
||||
}
|
||||
else {
|
||||
files.push([file, s]);
|
||||
}
|
||||
|
||||
if (--pending === 0) {
|
||||
cb(errs, dirs, files);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function render(dirs, files, lolwuts) {
|
||||
// each entry in the array is a [name, stat] tuple
|
||||
|
||||
// TODO: use stylessheets?
|
||||
var html = [
|
||||
'<!doctype html>',
|
||||
'<html>',
|
||||
' <head>',
|
||||
' <meta charset="utf-8">',
|
||||
' <meta name="viewport" content="width=device-width">',
|
||||
' <title>Index of ' + he.encode(pathname) +'</title>',
|
||||
' </head>',
|
||||
' <body>',
|
||||
'<h1>Index of ' + he.encode(pathname) + '</h1>'
|
||||
].join('\n') + '\n';
|
||||
|
||||
html += '<table>';
|
||||
|
||||
var failed = false;
|
||||
var writeRow = function (file, i) {
|
||||
// render a row given a [name, stat] tuple
|
||||
var isDir = file[1].isDirectory && file[1].isDirectory();
|
||||
var href = parsed.pathname.replace(/\/$/, '') + '/' + encodeURIComponent(file[0]);
|
||||
|
||||
// append trailing slash and query for dir entry
|
||||
if (isDir) {
|
||||
href += '/' + he.encode((parsed.search)? parsed.search:'');
|
||||
}
|
||||
|
||||
var displayName = he.encode(file[0]) + ((isDir)? '/':'');
|
||||
|
||||
// TODO: use stylessheets?
|
||||
html += '<tr>' +
|
||||
'<td><code>(' + permsToString(file[1]) + ')</code></td>' +
|
||||
'<td style="text-align: right; padding-left: 1em"><code>' + sizeToString(file[1], humanReadable, si) + '</code></td>' +
|
||||
'<td style="padding-left: 1em"><a href="' + href + '">' + displayName + '</a></td>' +
|
||||
'</tr>\n';
|
||||
};
|
||||
|
||||
dirs.sort(function (a, b) { return a[0].toString().localeCompare(b[0].toString()); }).forEach(writeRow);
|
||||
files.sort(function (a, b) { return a.toString().localeCompare(b.toString()); }).forEach(writeRow);
|
||||
lolwuts.sort(function (a, b) { return a[0].toString().localeCompare(b[0].toString()); }).forEach(writeRow);
|
||||
|
||||
html += '</table>\n';
|
||||
html += '<br><address>Node.js ' +
|
||||
process.version +
|
||||
'/ <a href="https://github.com/jfhbrook/node-ecstatic">ecstatic</a> ' +
|
||||
'server running @ ' +
|
||||
he.encode(req.headers.host || '') + '</address>\n' +
|
||||
'</body></html>'
|
||||
;
|
||||
|
||||
if (!failed) {
|
||||
res.writeHead(200, { "Content-Type": "text/html" });
|
||||
res.end(html);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
function permsToString(stat) {
|
||||
|
||||
if (!stat.isDirectory || !stat.mode) {
|
||||
return '???!!!???';
|
||||
}
|
||||
|
||||
var dir = stat.isDirectory() ? 'd' : '-',
|
||||
mode = stat.mode.toString(8);
|
||||
|
||||
return dir + mode.slice(-3).split('').map(function (n) {
|
||||
return [
|
||||
'---',
|
||||
'--x',
|
||||
'-w-',
|
||||
'-wx',
|
||||
'r--',
|
||||
'r-x',
|
||||
'rw-',
|
||||
'rwx'
|
||||
][parseInt(n, 10)];
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// given a file's stat, return the size of it in string
|
||||
// humanReadable: (boolean) whether to result is human readable
|
||||
// si: (boolean) whether to use si (1k = 1000), otherwise 1k = 1024
|
||||
// adopted from http://stackoverflow.com/a/14919494/665507
|
||||
function sizeToString(stat, humanReadable, si) {
|
||||
if (stat.isDirectory && stat.isDirectory()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var sizeString = '';
|
||||
var bytes = stat.size;
|
||||
var threshold = si ? 1000 : 1024;
|
||||
|
||||
if (!humanReadable || bytes < threshold) {
|
||||
return bytes + 'B';
|
||||
}
|
||||
|
||||
var units = [ 'k','M','G','T','P','E','Z','Y' ];
|
||||
var u = -1;
|
||||
do {
|
||||
bytes /= threshold;
|
||||
++u;
|
||||
} while (bytes >= threshold);
|
||||
|
||||
var b = bytes.toFixed(1);
|
||||
if (isNaN(b)) b = '??';
|
||||
|
||||
return b + units[u];
|
||||
}
|
||||
104
www/node_modules/ecstatic/lib/ecstatic/status-handlers.js
generated
vendored
Normal file
104
www/node_modules/ecstatic/lib/ecstatic/status-handlers.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
var he = require('he');
|
||||
|
||||
// not modified
|
||||
exports['304'] = function (res, next) {
|
||||
res.statusCode = 304;
|
||||
res.end();
|
||||
};
|
||||
|
||||
// access denied
|
||||
exports['403'] = function (res, next) {
|
||||
res.statusCode = 403;
|
||||
if (typeof next === "function") {
|
||||
next();
|
||||
}
|
||||
else {
|
||||
if (res.writable) {
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
res.end('ACCESS DENIED');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// disallowed method
|
||||
exports['405'] = function (res, next, opts) {
|
||||
res.statusCode = 405;
|
||||
if (typeof next === "function") {
|
||||
next();
|
||||
}
|
||||
else {
|
||||
res.setHeader('allow', (opts && opts.allow) || 'GET, HEAD');
|
||||
res.end();
|
||||
}
|
||||
};
|
||||
|
||||
// not found
|
||||
exports['404'] = function (res, next) {
|
||||
res.statusCode = 404;
|
||||
if (typeof next === "function") {
|
||||
next();
|
||||
}
|
||||
else {
|
||||
if (res.writable) {
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
res.end('File not found. :(');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports['416'] = function (res, next) {
|
||||
res.statusCode = 416;
|
||||
if (typeof next === "function") {
|
||||
next();
|
||||
}
|
||||
else {
|
||||
if (res.writable) {
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
res.end('Requested range not satisfiable');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// flagrant error
|
||||
exports['500'] = function (res, next, opts) {
|
||||
res.statusCode = 500;
|
||||
res.setHeader('content-type', 'text/html');
|
||||
var error = String(opts.error.stack || opts.error || "No specified error"),
|
||||
html = [
|
||||
'<!doctype html>',
|
||||
'<html>',
|
||||
' <head>',
|
||||
' <meta charset="utf-8">',
|
||||
' <title>500 Internal Server Error</title>',
|
||||
' </head>',
|
||||
' <body>',
|
||||
' <p>',
|
||||
' ' + he.encode(error),
|
||||
' </p>',
|
||||
' </body>',
|
||||
'</html>'
|
||||
].join('\n') + '\n';
|
||||
res.end(html);
|
||||
};
|
||||
|
||||
// bad request
|
||||
exports['400'] = function (res, next, opts) {
|
||||
res.statusCode = 400;
|
||||
res.setHeader('content-type', 'text/html');
|
||||
var error = opts && opts.error ? String(opts.error) : 'Malformed request.',
|
||||
html = [
|
||||
'<!doctype html>',
|
||||
'<html>',
|
||||
' <head>',
|
||||
' <meta charset="utf-8">',
|
||||
' <title>400 Bad Request</title>',
|
||||
' </head>',
|
||||
' <body>',
|
||||
' <p>',
|
||||
' ' + he.encode(error),
|
||||
' </p>',
|
||||
' </body>',
|
||||
'</html>'
|
||||
].join('\n') + '\n';
|
||||
res.end(html);
|
||||
};
|
||||
111
www/node_modules/ecstatic/package.json
generated
vendored
Normal file
111
www/node_modules/ecstatic/package.json
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
{
|
||||
"raw": "ecstatic@^1.4.0",
|
||||
"scope": null,
|
||||
"escapedName": "ecstatic",
|
||||
"name": "ecstatic",
|
||||
"rawSpec": "^1.4.0",
|
||||
"spec": ">=1.4.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"/home/nau/MEGA/CODI/githubRepos/colspace/www/node_modules/http-server"
|
||||
]
|
||||
],
|
||||
"_from": "ecstatic@>=1.4.0 <2.0.0",
|
||||
"_id": "ecstatic@1.4.1",
|
||||
"_inCache": true,
|
||||
"_location": "/ecstatic",
|
||||
"_nodeVersion": "4.2.1",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-16-east.internal.npmjs.com",
|
||||
"tmp": "tmp/ecstatic-1.4.1.tgz_1462924279598_0.48026969679631293"
|
||||
},
|
||||
"_npmUser": {
|
||||
"name": "jfhbrook",
|
||||
"email": "josh.holbrook@gmail.com"
|
||||
},
|
||||
"_npmVersion": "2.14.16",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"raw": "ecstatic@^1.4.0",
|
||||
"scope": null,
|
||||
"escapedName": "ecstatic",
|
||||
"name": "ecstatic",
|
||||
"rawSpec": "^1.4.0",
|
||||
"spec": ">=1.4.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/http-server"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-1.4.1.tgz",
|
||||
"_shasum": "32cb7b6fa2e290d58668674d115e8f0c3d567d6a",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "ecstatic@^1.4.0",
|
||||
"_where": "/home/nau/MEGA/CODI/githubRepos/colspace/www/node_modules/http-server",
|
||||
"author": {
|
||||
"name": "Joshua Holbrook",
|
||||
"email": "josh@nodejitsu.com",
|
||||
"url": "http://jesusabdullah.net"
|
||||
},
|
||||
"bin": {
|
||||
"ecstatic": "./lib/ecstatic.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jfhbrook/node-ecstatic/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"he": "^0.5.0",
|
||||
"mime": "^1.2.11",
|
||||
"minimist": "^1.1.0",
|
||||
"url-join": "^1.0.0"
|
||||
},
|
||||
"description": "A simple static file server middleware that works with both Express and Flatiron",
|
||||
"devDependencies": {
|
||||
"eol": "^0.2.0",
|
||||
"express": "^4.12.3",
|
||||
"mkdirp": "^0.5.0",
|
||||
"request": "^2.49.0",
|
||||
"tap": "^5.7.0"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "32cb7b6fa2e290d58668674d115e8f0c3d567d6a",
|
||||
"tarball": "https://registry.npmjs.org/ecstatic/-/ecstatic-1.4.1.tgz"
|
||||
},
|
||||
"gitHead": "70751198635509a156ad1564296625fc753af89f",
|
||||
"homepage": "https://github.com/jfhbrook/node-ecstatic",
|
||||
"keywords": [
|
||||
"static",
|
||||
"web",
|
||||
"server",
|
||||
"files",
|
||||
"mime",
|
||||
"middleware"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./lib/ecstatic.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jesusabdullah",
|
||||
"email": "josh.holbrook@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "jfhbrook",
|
||||
"email": "josh.holbrook@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "ecstatic",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/jfhbrook/node-ecstatic.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"version": "1.4.1"
|
||||
}
|
||||
7
www/node_modules/ecstatic/test.js
generated
vendored
Normal file
7
www/node_modules/ecstatic/test.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
var fs = require('fs');
|
||||
|
||||
var stat = fs.statSync('./package.json'); // or some other file
|
||||
|
||||
console.log(stat.mtime);
|
||||
console.log('' + stat.mtime);
|
||||
console.log(JSON.stringify(stat.mtime));
|
||||
Reference in New Issue
Block a user