Set up new module structure

This commit is contained in:
logsol 2012-07-01 01:32:30 +02:00
parent 5f5178d2e8
commit 2e864f5293
534 changed files with 235854 additions and 1 deletions

20
node_modules/node-static/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
Copyright (c) 2010 Alexis Sellier
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.

141
node_modules/node-static/README.md generated vendored Normal file
View file

@ -0,0 +1,141 @@
node-static
===========
> a simple, *rfc 2616 compliant* file streaming module for [node](http://nodejs.org)
node-static has an in-memory file cache, making it highly efficient.
node-static understands and supports *conditional GET* and *HEAD* requests.
node-static was inspired by some of the other static-file serving modules out there,
such as node-paperboy and antinode.
synopsis
--------
var static = require('node-static');
//
// Create a node-static server instance to serve the './public' folder
//
var file = new(static.Server)('./public');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
//
// Serve files!
//
file.serve(request, response);
});
}).listen(8080);
API
---
### Creating a node-static Server #
Creating a file server instance is as simple as:
new static.Server();
This will serve files in the current directory. If you want to serve files in a specific
directory, pass it as the first argument:
new static.Server('./public');
You can also specify how long the client is supposed to cache the files node-static serves:
new static.Server('./public', { cache: 3600 });
This will set the `Cache-Control` header, telling clients to cache the file for an hour.
This is the default setting.
### Serving files under a directory #
To serve files under a directory, simply call the `serve` method on a `Server` instance, passing it
the HTTP request and response object:
var fileServer = new static.Server('./public');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
fileServer.serve(request, response);
});
}).listen(8080);
### Serving specific files #
If you want to serve a specific file, like an error page for example, use the `serveFile` method:
fileServer.serveFile('/error.html', 500, {}, request, response);
This will serve the `error.html` file, from under the file root directory, with a `500` status code.
For example, you could serve an error page, when the initial request wasn't found:
require('http').createServer(function (request, response) {
request.addListener('end', function () {
fileServer.serve(request, response, function (e, res) {
if (e && (e.status === 404)) { // If the file wasn't found
fileServer.serveFile('/not-found.html', 404, {}, request, response);
}
});
});
}).listen(8080);
More on intercepting errors bellow.
### Intercepting errors & Listening #
An optional callback can be passed as last argument, it will be called every time a file
has been served successfully, or if there was an error serving the file:
var fileServer = new static.Server('./public');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
fileServer.serve(request, response, function (err, result) {
if (err) { // There was an error serving the file
sys.error("Error serving " + request.url + " - " + err.message);
// Respond to the client
response.writeHead(err.status, err.headers);
response.end();
}
});
});
}).listen(8080);
Note that if you pass a callback, and there is an error serving the file, node-static
*will not* respond to the client. This gives you the opportunity to re-route the request,
or handle it differently.
For example, you may want to interpret a request as a static request, but if the file isn't found,
send it to an application.
If you only want to *listen* for errors, you can use *event listeners*:
fileServer.serve(request, response).addListener('error', function (err) {
sys.error("Error serving " + request.url + " - " + err.message);
});
With this method, you don't have to explicitly send the response back, in case of an error.
### Options when creating an instance of `Server` #
#### `cache` #
Sets the `Cache-Control` header.
example: `{ cache: 7200 }`
Passing a number will set the cache duration to that number of seconds.
Passing `false` will disable the `Cache-Control` header.
> Defaults to `3600`
#### `headers` #
Sets response headers.
example: `{ 'X-Hello': 'World!' }`
> defaults to `{}`

View file

@ -0,0 +1,43 @@
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Server Software: node-static/0.3.0
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /lib/node-static.js
Document Length: 6038 bytes
Concurrency Level: 20
Time taken for tests: 2.323 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 63190000 bytes
HTML transferred: 60380000 bytes
Requests per second: 4304.67 [#/sec] (mean)
Time per request: 4.646 [ms] (mean)
Time per request: 0.232 [ms] (mean, across all concurrent requests)
Transfer rate: 26563.66 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 3
Processing: 1 4 1.4 4 28
Waiting: 1 4 1.3 4 18
Total: 2 5 1.5 4 28
Percentage of the requests served within a certain time (ms)
50% 4
66% 5
75% 5
80% 5
90% 5
95% 6
98% 8
99% 9
100% 28 (longest request)

25
node_modules/node-static/examples/file-server.js generated vendored Normal file
View file

@ -0,0 +1,25 @@
var static = require('../lib/node-static');
//
// Create a node-static server to serve the current directory
//
var file = new(static.Server)('.', { cache: 7200, headers: {'X-Hello':'World!'} });
require('http').createServer(function (request, response) {
request.addListener('end', function () {
//
// Serve files!
//
file.serve(request, response, function (err, res) {
if (err) { // An error as occured
console.error("> Error serving " + request.url + " - " + err.message);
response.writeHead(err.status, err.headers);
response.end();
} else { // The file was served successfully
console.log("> " + request.url + " - " + res.message);
}
});
});
}).listen(8080);
console.log("> node-static is listening on http://127.0.0.1:8080");

252
node_modules/node-static/lib/node-static.js generated vendored Normal file
View file

@ -0,0 +1,252 @@
var fs = require('fs'),
events = require('events'),
buffer = require('buffer'),
http = require('http'),
url = require('url'),
path = require('path');
this.version = [0, 6, 0];
var mime = require('./node-static/mime');
var util = require('./node-static/util');
var serverInfo = 'node-static/' + this.version.join('.');
// In-memory file store
this.store = {};
this.indexStore = {};
this.Server = function (root, options) {
if (root && (typeof(root) === 'object')) { options = root, root = null }
this.root = path.resolve(root || '.');
this.options = options || {};
this.cache = 3600;
this.defaultHeaders = {};
this.options.headers = this.options.headers || {};
if ('cache' in this.options) {
if (typeof(this.options.cache) === 'number') {
this.cache = this.options.cache;
} else if (! this.options.cache) {
this.cache = false;
}
}
if (this.cache !== false) {
this.defaultHeaders['Cache-Control'] = 'max-age=' + this.cache;
}
this.defaultHeaders['Server'] = serverInfo;
for (var k in this.defaultHeaders) {
this.options.headers[k] = this.options.headers[k] ||
this.defaultHeaders[k];
}
};
this.Server.prototype.serveDir = function (pathname, req, res, finish) {
var htmlIndex = path.join(pathname, 'index.html'),
that = this;
fs.stat(htmlIndex, function (e, stat) {
if (!e) {
that.respond(null, 200, {}, [htmlIndex], stat, req, res, finish);
} else {
if (pathname in exports.store) {
streamFiles(exports.indexStore[pathname].files);
} else {
// Stream a directory of files as a single file.
fs.readFile(path.join(pathname, 'index.json'), function (e, contents) {
if (e) { return finish(404, {}) }
var index = JSON.parse(contents);
exports.indexStore[pathname] = index;
streamFiles(index.files);
});
}
}
});
function streamFiles(files) {
util.mstat(pathname, files, function (e, stat) {
that.respond(pathname, 200, {}, files, stat, req, res, finish);
});
}
};
this.Server.prototype.serveFile = function (pathname, status, headers, req, res) {
var that = this;
var promise = new(events.EventEmitter);
pathname = this.resolve(pathname);
fs.stat(pathname, function (e, stat) {
if (e) {
return promise.emit('error', e);
}
that.respond(null, status, headers, [pathname], stat, req, res, function (status, headers) {
that.finish(status, headers, req, res, promise);
});
});
return promise;
};
this.Server.prototype.finish = function (status, headers, req, res, promise, callback) {
var result = {
status: status,
headers: headers,
message: http.STATUS_CODES[status]
};
headers['Server'] = serverInfo;
if (!status || status >= 400) {
if (callback) {
callback(result);
} else {
if (promise.listeners('error').length > 0) {
promise.emit('error', result);
}
res.writeHead(status, headers);
res.end();
}
} else {
// Don't end the request here, if we're streaming;
// it's taken care of in `prototype.stream`.
if (status !== 200 || req.method !== 'GET') {
res.writeHead(status, headers);
res.end();
}
callback && callback(null, result);
promise.emit('success', result);
}
};
this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) {
var that = this,
promise = new(events.EventEmitter);
pathname = this.resolve(pathname);
// Only allow GET and HEAD requests
if (req.method !== 'GET' && req.method !== 'HEAD') {
finish(405, { 'Allow': 'GET, HEAD' });
return promise;
}
// Make sure we're not trying to access a
// file outside of the root.
if (pathname.indexOf(that.root) === 0) {
fs.stat(pathname, function (e, stat) {
if (e) {
finish(404, {});
} else if (stat.isFile()) { // Stream a single file.
that.respond(null, status, headers, [pathname], stat, req, res, finish);
} else if (stat.isDirectory()) { // Stream a directory of files.
that.serveDir(pathname, req, res, finish);
} else {
finish(400, {});
}
});
} else {
// Forbidden
finish(403, {});
}
return promise;
};
this.Server.prototype.resolve = function (pathname) {
return path.resolve(path.join(this.root, pathname));
};
this.Server.prototype.serve = function (req, res, callback) {
var that = this,
promise = new(events.EventEmitter);
var pathname = decodeURI(url.parse(req.url).pathname);
var finish = function (status, headers) {
that.finish(status, headers, req, res, promise, callback);
};
process.nextTick(function () {
that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) {
promise.emit('success', result);
}).on('error', function (err) {
promise.emit('error');
});
});
if (! callback) { return promise }
};
this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
var mtime = Date.parse(stat.mtime),
key = pathname || files[0],
headers = {};
// Copy default headers
for (var k in this.options.headers) { headers[k] = this.options.headers[k] }
headers['Etag'] = JSON.stringify([stat.ino, stat.size, mtime].join('-'));
headers['Date'] = new(Date)().toUTCString();
headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString();
// Conditional GET
// If the "If-Modified-Since" or "If-None-Match" headers
// match the conditions, send a 304 Not Modified.
if (req.headers['if-none-match'] === headers['Etag'] ||
Date.parse(req.headers['if-modified-since']) >= mtime) {
finish(304, headers);
} else if (req.method === 'HEAD') {
finish(200, headers);
} else {
var fileExtension = path.extname(files[0]).slice(1).toLowerCase();
headers['Content-Length'] = stat.size;
headers['Content-Type'] = mime.contentTypes[fileExtension] ||
'application/octet-stream';
for (var k in _headers) { headers[k] = _headers[k] }
res.writeHead(status, headers);
// If the file was cached and it's not older
// than what's on disk, serve the cached version.
if (this.cache && (key in exports.store) &&
exports.store[key].stat.mtime >= stat.mtime) {
res.end(exports.store[key].buffer);
finish(status, headers);
} else {
this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
if (e) { return finish(500, {}) }
exports.store[key] = {
stat: stat,
buffer: buffer,
timestamp: Date.now()
};
finish(status, headers);
});
}
}
};
this.Server.prototype.stream = function (pathname, files, buffer, res, callback) {
(function streamFile(files, offset) {
var file = files.shift();
if (file) {
file = file[0] === '/' ? file : path.join(pathname || '.', file);
// Stream the file to the client
fs.createReadStream(file, {
flags: 'r',
mode: 0666
}).on('data', function (chunk) {
chunk.copy(buffer, offset);
offset += chunk.length;
}).on('close', function () {
streamFile(files, offset);
}).on('error', function (err) {
callback(err);
console.error(err);
}).pipe(res, { end: false });
} else {
res.end();
callback(null, buffer, offset);
}
})(files.slice(0), 0);
};

140
node_modules/node-static/lib/node-static/mime.js generated vendored Normal file
View file

@ -0,0 +1,140 @@
this.contentTypes = {
"aiff": "audio/x-aiff",
"arj": "application/x-arj-compressed",
"asf": "video/x-ms-asf",
"asx": "video/x-ms-asx",
"au": "audio/ulaw",
"avi": "video/x-msvideo",
"bcpio": "application/x-bcpio",
"ccad": "application/clariscad",
"cod": "application/vnd.rim.cod",
"com": "application/x-msdos-program",
"cpio": "application/x-cpio",
"cpt": "application/mac-compactpro",
"csh": "application/x-csh",
"css": "text/css",
"deb": "application/x-debian-package",
"dl": "video/dl",
"doc": "application/msword",
"drw": "application/drafting",
"dvi": "application/x-dvi",
"dwg": "application/acad",
"dxf": "application/dxf",
"dxr": "application/x-director",
"etx": "text/x-setext",
"ez": "application/andrew-inset",
"fli": "video/x-fli",
"flv": "video/x-flv",
"gif": "image/gif",
"gl": "video/gl",
"gtar": "application/x-gtar",
"gz": "application/x-gzip",
"hdf": "application/x-hdf",
"hqx": "application/mac-binhex40",
"htm": "text/html",
"html": "text/html",
"ice": "x-conference/x-cooltalk",
"ico": "image/x-icon",
"ief": "image/ief",
"igs": "model/iges",
"ips": "application/x-ipscript",
"ipx": "application/x-ipix",
"jad": "text/vnd.sun.j2me.app-descriptor",
"jar": "application/java-archive",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"js": "text/javascript",
"json": "application/json",
"latex": "application/x-latex",
"less": "text/css",
"lsp": "application/x-lisp",
"lzh": "application/octet-stream",
"m": "text/plain",
"m3u": "audio/x-mpegurl",
"man": "application/x-troff-man",
"manifest": "text/cache-manifest",
"me": "application/x-troff-me",
"midi": "audio/midi",
"mif": "application/x-mif",
"mime": "www/mime",
"movie": "video/x-sgi-movie",
"mp4": "video/mp4",
"mpg": "video/mpeg",
"mpga": "audio/mpeg",
"ms": "application/x-troff-ms",
"nc": "application/x-netcdf",
"oda": "application/oda",
"ogm": "application/ogg",
"pbm": "image/x-portable-bitmap",
"pdf": "application/pdf",
"pgm": "image/x-portable-graymap",
"pgn": "application/x-chess-pgn",
"pgp": "application/pgp",
"pm": "application/x-perl",
"png": "image/png",
"pnm": "image/x-portable-anymap",
"ppm": "image/x-portable-pixmap",
"ppz": "application/vnd.ms-powerpoint",
"pre": "application/x-freelance",
"prt": "application/pro_eng",
"ps": "application/postscript",
"qt": "video/quicktime",
"ra": "audio/x-realaudio",
"rar": "application/x-rar-compressed",
"ras": "image/x-cmu-raster",
"rgb": "image/x-rgb",
"rm": "audio/x-pn-realaudio",
"rpm": "audio/x-pn-realaudio-plugin",
"rtf": "text/rtf",
"rtx": "text/richtext",
"scm": "application/x-lotusscreencam",
"set": "application/set",
"sgml": "text/sgml",
"sh": "application/x-sh",
"shar": "application/x-shar",
"silo": "model/mesh",
"sit": "application/x-stuffit",
"skt": "application/x-koan",
"smil": "application/smil",
"snd": "audio/basic",
"sol": "application/solids",
"spl": "application/x-futuresplash",
"src": "application/x-wais-source",
"stl": "application/SLA",
"stp": "application/STEP",
"sv4cpio": "application/x-sv4cpio",
"sv4crc": "application/x-sv4crc",
"svg": "image/svg+xml",
"swf": "application/x-shockwave-flash",
"tar": "application/x-tar",
"tcl": "application/x-tcl",
"tex": "application/x-tex",
"texinfo": "application/x-texinfo",
"tgz": "application/x-tar-gz",
"tiff": "image/tiff",
"tr": "application/x-troff",
"tsi": "audio/TSP-audio",
"tsp": "application/dsptype",
"tsv": "text/tab-separated-values",
"txt": "text/plain",
"unv": "application/i-deas",
"ustar": "application/x-ustar",
"vcd": "application/x-cdlink",
"vda": "application/vda",
"vivo": "video/vnd.vivo",
"vrm": "x-world/x-vrml",
"wav": "audio/x-wav",
"wax": "audio/x-ms-wax",
"wma": "audio/x-ms-wma",
"wmv": "video/x-ms-wmv",
"wmx": "video/x-ms-wmx",
"wrl": "model/vrml",
"wvx": "video/x-ms-wvx",
"xbm": "image/x-xbitmap",
"xlw": "application/vnd.ms-excel",
"xml": "text/xml",
"xpm": "image/x-xpixmap",
"xwd": "image/x-xwindowdump",
"xyz": "chemical/x-pdb",
"zip": "application/zip"
};

30
node_modules/node-static/lib/node-static/util.js generated vendored Normal file
View file

@ -0,0 +1,30 @@
var fs = require('fs'),
path = require('path');
this.mstat = function (dir, files, callback) {
(function mstat(files, stats) {
var file = files.shift();
if (file) {
fs.stat(path.join(dir, file), function (e, stat) {
if (e) {
callback(e);
} else {
mstat(files, stats.concat([stat]));
}
});
} else {
callback(null, {
size: stats.reduce(function (total, stat) {
return total + stat.size;
}, 0),
mtime: stats.reduce(function (latest, stat) {
return latest > stat.mtime ? latest : stat.mtime;
}, 0),
ino: stats.reduce(function (total, stat) {
return total + stat.ino;
}, 0)
});
}
})(files.slice(0), []);
};

43
node_modules/node-static/package.json generated vendored Normal file
View file

@ -0,0 +1,43 @@
{
"name": "node-static",
"description": "simple, compliant file streaming module for node",
"url": "http://github.com/cloudhead/node-static",
"keywords": [
"http",
"static",
"file",
"server"
],
"author": {
"name": "Alexis Sellier",
"email": "self@cloudhead.net"
},
"contributors": [
{
"name": "Pablo Cantero",
"email": "pablo@pablocantero.com"
}
],
"repository": {
"type": "git",
"url": "git://github.com/cloudhead/node-static.git"
},
"main": "./lib/node-static",
"license": "MIT",
"dependencies": {},
"version": "0.6.0",
"engines": {
"node": ">= 0.4.1"
},
"_id": "node-static@0.6.0",
"devDependencies": {},
"optionalDependencies": {},
"_engineSupported": true,
"_npmVersion": "1.1.9",
"_nodeVersion": "v0.6.13",
"_defaultsLoaded": true,
"dist": {
"shasum": "25024f29b5177b69afdbde315fcebdf9563ce072"
},
"_from": "node-static@>= 0.6.0"
}