hfs 0.1.6 → 0.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE.txt +674 -0
  2. package/README.md +102 -8
  3. package/admin/assets/index.dcc78777.css +1 -0
  4. package/admin/assets/index.f056db34.js +282 -0
  5. package/admin/assets/sha512.3c0e384c.js +8 -0
  6. package/admin/index.html +17 -0
  7. package/admin/logo.svg +36 -0
  8. package/frontend/assets/index.55c710c2.js +85 -0
  9. package/frontend/assets/index.ee805a6c.css +1 -0
  10. package/frontend/assets/sha512.634b743e.js +8 -0
  11. package/frontend/fontello.css +77 -0
  12. package/frontend/fontello.woff2 +0 -0
  13. package/frontend/index.html +18 -0
  14. package/package.json +93 -28
  15. package/plugins/antibrute/plugin.js +38 -0
  16. package/plugins/download-counter/plugin.js +47 -0
  17. package/plugins/download-counter/public/hits.js +5 -0
  18. package/plugins/updater-disabled/plugin.js +44 -0
  19. package/plugins/vhosting/plugin.js +42 -0
  20. package/src/QuickZipStream.js +285 -0
  21. package/src/ThrottledStream.js +93 -0
  22. package/src/adminApis.js +169 -0
  23. package/src/api.accounts.js +59 -0
  24. package/src/api.auth.js +130 -0
  25. package/src/api.file_list.js +103 -0
  26. package/src/api.helpers.js +32 -0
  27. package/src/api.monitor.js +102 -0
  28. package/src/api.plugins.js +125 -0
  29. package/src/api.vfs.js +164 -0
  30. package/src/apiMiddleware.js +136 -0
  31. package/src/block.js +33 -0
  32. package/src/commands.js +105 -0
  33. package/src/config.js +172 -0
  34. package/src/connections.js +57 -0
  35. package/src/const.js +83 -0
  36. package/src/crypt.js +21 -0
  37. package/src/debounceAsync.js +48 -0
  38. package/src/events.js +9 -0
  39. package/src/frontEndApis.js +38 -0
  40. package/src/github.js +102 -0
  41. package/src/index.js +53 -0
  42. package/src/listen.js +226 -0
  43. package/src/log.js +137 -0
  44. package/src/middlewares.js +154 -0
  45. package/src/misc.js +160 -0
  46. package/src/pbkdf2.js +74 -0
  47. package/src/perm.js +176 -0
  48. package/src/plugins.js +338 -0
  49. package/src/serveFile.js +104 -0
  50. package/src/serveGuiFiles.js +113 -0
  51. package/src/sse.js +29 -0
  52. package/src/throttler.js +91 -0
  53. package/src/update.js +69 -0
  54. package/src/util-files.js +141 -0
  55. package/src/util-generators.js +30 -0
  56. package/src/util-http.js +30 -0
  57. package/src/vfs.js +227 -0
  58. package/src/watchLoad.js +73 -0
  59. package/src/zip.js +69 -0
  60. package/.npmignore +0 -19
  61. package/admin-server.js +0 -212
  62. package/cli.js +0 -33
  63. package/file-server.js +0 -100
  64. package/lib/common.js +0 -10
  65. package/lib/extending.js +0 -158
  66. package/lib/mime.js +0 -19
  67. package/lib/misc.js +0 -75
  68. package/lib/serving.js +0 -81
  69. package/lib/vfs.js +0 -403
  70. package/main.js +0 -24
  71. package/note.txt +0 -104
  72. package/speedtest.js +0 -21
  73. package/static/backend.css +0 -14
  74. package/static/backend.html +0 -32
  75. package/static/backend.js +0 -694
  76. package/static/extending.js +0 -187
  77. package/static/frontend.css +0 -29
  78. package/static/frontend.html +0 -23
  79. package/static/frontend.js +0 -230
  80. package/static/icons/files/archive.png +0 -0
  81. package/static/icons/files/audio.png +0 -0
  82. package/static/icons/files/file.png +0 -0
  83. package/static/icons/files/folder.png +0 -0
  84. package/static/icons/files/image.png +0 -0
  85. package/static/icons/files/link.png +0 -0
  86. package/static/icons/files/video.png +0 -0
  87. package/static/jquery.js +0 -4
  88. package/static/jquery.rule-1.0.2.js +0 -273
  89. package/static/misc.js +0 -194
  90. package/static/tpl.js +0 -17
  91. package/todo.txt +0 -25
package/admin-server.js DELETED
@@ -1,212 +0,0 @@
1
- /**
2
- * @fileOverview This serves the back-end GUI and all it needs to perform server-side actions.
3
- * @author Massimo Melina <a@rejetto.com>
4
- */
5
- var http = require('http');
6
- var socket_io = require('socket.io');
7
- var serving = require('./lib/serving');
8
-
9
- exports.start = function(listenOn) {
10
- srv.listen(listenOn.port, listenOn.ip, function(){
11
- dbg('listening on port '+listenOn.port);
12
- });
13
- }
14
-
15
- var srv = http.createServer(function(httpReq,httpRes){
16
- if (!serving.parseUrl(httpReq)) return;
17
-
18
- /*
19
- var peer = httpReq.socket.address(); // bug: currently peer.port is our listening port, while we want to show the port of the socket serving the connection
20
- dbg('serving '+peer.address+':'+peer.port+' '+httpReq.url);
21
- */
22
-
23
- if (serving.serveStatic(httpReq, httpRes)) return; // access to the special 'static' folder
24
- if (httpReq.uri == '/') {
25
- serving.serveFile('static/backend.html', httpRes);
26
- return;
27
- }
28
- serve404(httpRes); // we serve nothing else
29
- });
30
-
31
- srv.on('error', function(err){
32
- switch (err.code) {
33
- case 'EADDRINUSE':
34
- return dbg('port '+listenOn.port+' busy');
35
- }
36
- });
37
-
38
- /* converts FileNode to an object that's ready to be streamed to the back-end.
39
- @param {number} depth specifies how many levels of children should be included in the structure.
40
- @param {function} cb is necessary if you specify a depth that's more than zero
41
- @return the object representing the FileNode if no depth is specified. Otherwise the returning turns into
42
- an async fashion and you need to specify a callback to retrieve the result.
43
- */
44
- function nodeToObject(fnode, depth, cb) {
45
- assert(!cb || typeof cb == 'function', 'cb');
46
- if (!fnode) {
47
- if (cb) cb(false);
48
- return false;
49
- }
50
- assert(fnode instanceof vfsLib.FileNode, 'fnode');
51
-
52
- var res = ceLib.extenduptolevel({name:fnode.name}, fnode, 1); // make a copy of the whole object without recurring, and overwriting the getter 'name'
53
- delete res._parent; // this makes a circular reference
54
- delete res.children; // in case we want the true listing, not just the children
55
- delete res.customName;
56
- // save bandwidth by not sending some empty properties
57
- if (res.deletedItems
58
- && !res.deletedItems.length) {
59
- delete res.deletedItems;
60
- }
61
- if (!res.resource) {
62
- delete res.resource;
63
- }
64
- // depth is not required, or not possible, our job ends here
65
- if (!depth
66
- || !fnode.isFolder()) {
67
- if (cb) cb(res);
68
- return res;
69
- }
70
- // this is necessarily an async procedure: require a callback
71
- assert(cb, 'cb');
72
- // recur on children
73
- fnode.dir(function(items){
74
- res.children = [];
75
- async.forEach(items.getProperties(), function(e, doneThis){
76
- nodeToObject(e, depth-1, function(obj){
77
- res.children.push(obj);
78
- doneThis();
79
- });
80
- }, cb.bind(this,res));
81
- });
82
- } // nodeToObject
83
-
84
- /*
85
- SET UP SOCKET.IO
86
- */
87
-
88
- var io = exports.io = socket_io.listen(srv);
89
- serving.setupSocketIO(io);
90
- io.sockets.on('connection', function(socket){
91
-
92
- socket.on('vfs.get', function onGet(data, cb) {
93
- if (serving.ioError(!data ? data
94
- : typeof data.uri != 'string' ? 'uri'
95
- : null, cb)) return;
96
-
97
- vfs.fromUrl(data.uri, function(fnode) {
98
- nodeToObject(fnode, data.depth, cb);
99
- });
100
- });
101
-
102
- // set properties of a vfs item
103
- socket.on('vfs.set', function onSet(data, cb){
104
- // assertions
105
- if (serving.ioError(!data ? 'data'
106
- : typeof data.uri != 'string' ? 'uri'
107
- : null, cb)) return;
108
-
109
- vfs.fromUrl(data.uri, function(fnode) {
110
- if (!fnode) {
111
- serving.ioError('not found');
112
- return;
113
- }
114
- if (data.name) {
115
- if (serving.ioError(typeof data.name != 'string' ? 'name' : null, cb)) return;
116
- fnode.name = data.name;
117
- serving.ioOk(cb);
118
- }
119
- else if (data.resource) {
120
- if (serving.ioError(typeof data.resource != 'string' ? 'resource' : null, cb)) return;
121
- fnode.set(data.resource, serving.ioOk.bind(this,cb));
122
- }
123
- notifyVfsChange(socket, fnode.getURI().excludeTrailing('/'));
124
- });
125
- });
126
-
127
- // add an item to the vfs
128
- socket.on('vfs.add', function onAdd(data, cb){
129
- // assertions
130
- if (serving.ioError(!data ? 'data'
131
- : typeof data.uri !== 'string' ? 'uri'
132
- : typeof data.resource !== 'string' ? 'resource'
133
- : null, cb)) return;
134
-
135
- vfs.fromUrl(data.uri, function(fnode) {
136
- if (!fnode) {
137
- serving.ioError('uri not found', cb);
138
- return;
139
- }
140
- var already = fnode.getChildByName(path.basename(data.resource)); // check if it already exists
141
- if (already) {
142
- serving.ioError('already exists', cb);
143
- return;
144
- }
145
- fnode.add(data.resource, function(newNode){
146
- serving.ioOk(cb, {item:nodeToObject(newNode)});
147
- notifyVfsChange(socket, data.uri);
148
- });
149
- });
150
- });
151
-
152
- // delete item, make it non-existent in the VFS
153
- socket.on('vfs.delete', function onRemove(data, cb){
154
- // assertions
155
- if (serving.ioError(!data ? 'data'
156
- : typeof data.uri !== 'string' ? 'uri'
157
- : null, cb)) return;
158
-
159
- vfs.fromUrl(data.uri, function(fnode){
160
- if (!fnode) {
161
- serving.ioError('uri not found', cb)
162
- return;
163
- }
164
- fnode.getFolder(function(folder){
165
- fnode.delete();
166
- // if we just deleted a dynamic item, the GUI may need an extra refresh
167
- serving.ioOk(cb, {
168
- dynamicItem: fnode.isTemp() && path.basename(fnode.resource)+(fnode.isFolder() ? '/' : ''), // trailing slash to denote folders
169
- folderDeletedCount: folder.deletedItems ? folder.deletedItems.length : 0
170
- });
171
- notifyVfsChange(socket, folder.getURI());
172
- });
173
- });
174
- });
175
-
176
- // restore a temp item that was deleted
177
- socket.on('vfs.restore', function onRestore(data, cb){
178
- // assertions
179
- if (serving.ioError(!data ? 'data'
180
- : typeof data.uri !== 'string' ? 'uri'
181
- : typeof data.resource !== 'string' ? 'resource'
182
- : null, cb)) return;
183
-
184
- vfs.fromUrl(data.uri, function(fnode){
185
- if (!fnode) {
186
- serving.ioError('uri not found', cb)
187
- return;
188
- }
189
- if (!fnode.restoreDeleted(data.resource)) {
190
- serving.ioError('failed');
191
- return;
192
- }
193
- fnode.createFileNodeFromRelativeUri(data.resource, function(child){
194
- serving.ioOk(cb, {item:child});
195
- notifyVfsChange(socket, fnode.getURI());
196
- });
197
- });
198
- });
199
-
200
- socket.on('info.get', function onInfo(data, cb){
201
- serving.ioOk(cb, {caseSensitiveFileNames:misc.caseSensitiveFileNames});
202
- });
203
-
204
- });
205
-
206
- notifyVfsChange = function(socket, uri) {
207
- dbg('vfs.changed');
208
- [socket.broadcast, require('./file-server').io.sockets].forEach(function(o){
209
- o.emit('vfs.changed', {uri:uri});
210
- });
211
- }; // notifyVfsChange
212
-
package/cli.js DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * @fileOverview command line interface to the server
3
- * @author Massimo Melina <a@rejetto.com>
4
- */
5
- require('./lib/common');
6
- var socket_io = require('socket.io-client');
7
-
8
- // read arguments
9
- var v = process.argv;
10
- if (v.length < 3) { // quick help
11
- log('Usage: node '+path.basename(v[1])+' <path>');
12
- return;
13
- }
14
- var fpath = v[2];
15
- var under = v.length < 4 ? '/' : v[3];
16
-
17
- // connect to admin-server
18
- var socket = socket_io.connect('http://localhost:88');
19
- socket.on('connect', function () {
20
- // ask to add this file
21
- socket.emit('vfs.add', {uri:under, resource:fpath, depth:1}, function(data){
22
- if (!data) {
23
- log('communication error');
24
- process.exit(1);
25
- }
26
- if (!data.ok) {
27
- log('error: '+(data.error || 'generic'));
28
- process.exit(2);
29
- }
30
- socket.disconnect();
31
- process.exit(0);
32
- });
33
- });
package/file-server.js DELETED
@@ -1,100 +0,0 @@
1
- /**
2
- * @fileOverview This serves the front-end GUI and all it needs to perform server-side actions.
3
- * @author Massimo Melina <a@rejetto.com>
4
- */
5
- var http = require('http');
6
- var socket_io = require('socket.io');
7
- var serving = require('./lib/serving');
8
-
9
- exports.start = function(listenOn) {
10
- listeningOn = listenOn;
11
- srv.listen(listenOn.port, listenOn.ip, function onListen(){
12
- dbg('listening on port '+listenOn.port);
13
- });
14
- };
15
-
16
- /*
17
- SET UP THE HTTP SERVER
18
- */
19
-
20
- var listeningOn; // keep track of the tcp coordinates we are currently accepting requests
21
-
22
- var srv = http.createServer(function(httpReq,httpRes){
23
- if (!serving.parseUrl(httpReq)) return;
24
-
25
- var peer = httpReq.socket.address();
26
- dbg('serving '+peer.address+':'+peer.port+' '+httpReq.url);
27
-
28
- serving.serveStatic(httpReq, httpRes)
29
- || serveFromVFS(httpReq, httpRes);
30
-
31
- });
32
-
33
- srv.on('error', function(err){
34
- switch (err.code) {
35
- case 'EADDRINUSE':
36
- return dbg('port '+listeningOn.port+' busy');
37
- }
38
- });
39
-
40
- /*
41
- SET UP SOCKET.IO
42
- */
43
-
44
- var io = exports.io = socket_io.listen(srv);
45
- serving.setupSocketIO(io);
46
- io.sockets.on('connection', function(socket){
47
- //** sequences like these may be better with Step(). Try
48
- socket.on('get list', function onGetList(data, cb){
49
- vfs.fromUrl(data.path, function(fnode) {
50
- getReplyForFolder(fnode, serving.ioOk.bind(this,cb));
51
- });
52
- });
53
- });
54
-
55
- //////////////////////////////
56
-
57
- function getReplyForFolder(folder, cb) {
58
- if (!folder) {
59
- return cb({error:'not found'});
60
- }
61
- folder.dir(function(items){
62
- assert(items, 'items');
63
- // convert items to a simpler format
64
- items.forEach(function(f,name){
65
- // we'll use short key names to save bandwidth on common fieldnames.
66
- var it = items[name] = {};
67
- // type
68
- it.t = f.itemKind.replace('virtual ',''); // this is a quick and dirty method to get value as file|folder|link
69
- // size
70
- if (f.isOnDisk())
71
- it.s = f.stats.size;
72
- });//forEach
73
-
74
- cb({items:items});
75
- });//dir
76
- } // getReplyForFolder
77
-
78
- function serveFromVFS(httpReq, httpRes) {
79
- vfs.fromUrl(httpReq.uri, function urlCB(node){
80
- if (!node) {
81
- httpRes.writeHead(404);
82
- return httpRes.end();
83
- }
84
-
85
- if (node.isFile()) {
86
- return serving.serveFile(node.resource, httpRes, node.stats.size);
87
- }
88
-
89
- assert(node.isFolder(), 'must be folder');
90
- // force trailing slash
91
- if (httpReq.url.substr(-1) != '/') {
92
- httpRes.writeHead(301, {
93
- 'Location': httpReq.url+'/'
94
- });
95
- return httpRes.end();
96
- }
97
-
98
- serving.serveFile('static/frontend.html', httpRes)
99
- });
100
- } // serveFromVFS
package/lib/common.js DELETED
@@ -1,10 +0,0 @@
1
- require('./extending');
2
- GLOBAL.path = require('path');
3
- GLOBAL.util = require('util');
4
- GLOBAL.os = require('os');
5
- GLOBAL.fs = require('fs');
6
- GLOBAL.assert = require('assert');
7
- GLOBAL.ceLib = require('cloneextend');
8
- GLOBAL.misc = require('./misc');
9
- GLOBAL.vfsLib = require('./vfs');
10
- GLOBAL.async = require('async');
package/lib/extending.js DELETED
@@ -1,158 +0,0 @@
1
- ///////// EXTENDING FUNCTION
2
-
3
- /** as function.bind(), but additional parameters are prepended instead of appended
4
- * @return {function} proxied function
5
- */
6
- Function.prototype.prebind = function(){
7
- var args = Array.prototype.slice.call(arguments);
8
- var scope = args.shift();
9
- var fun = this;
10
- return function(){
11
- var moreArgs = Array.prototype.slice.call(arguments);
12
- fun.apply(scope, moreArgs.concat(args));
13
- };
14
- };
15
-
16
- ///////// EXTENDING STRING
17
-
18
- /* return a new string filling "this" with arguments' values.
19
- The filling is done in place of strings in this form {key} or this other form {key|parameter}.
20
- If first argument is an object, then "key" is used as field name (i.e. property) of the object.
21
- Otherwise "key" should be a number, and it's the argument's index (zero-based).
22
- As stated before, keys can have a parameter. If such parameter is in the form \d*-\d* then these numbers
23
- denote a range of characters to extract (i.e. a substring). Otherwise the parameter is a property name for
24
- the value (that must be an object or an array in this case).
25
- */
26
- String.prototype.format = function() {
27
- var args = arguments;
28
- if (typeof args[0] == 'object')
29
- args = args[0];
30
- return this.replace(/\{([-_ a-z0-9]+)(\|([^}]+))?\}/gi, function(){
31
- var ret = args[arguments[1]];
32
- var par = arguments[3];
33
- if (par) {
34
- var v = /(\d*)-(\d*)/.exec(par); // is it in the "range" form?
35
- if (v) ret = ret.substring(v[1]-1 || 0, v[2] || ret.length); // extract the substring in range
36
- else ret = ret[par]; // get property
37
- }
38
- return ret;
39
- });
40
- };
41
-
42
- String.prototype.repeat = function(n) {
43
- var r = '';
44
- for (var i=0; i<n; i++) r += this;
45
- return r;
46
- };
47
-
48
- String.prototype.count = function(sub) {
49
- return this.split(sub).length-1;
50
- };
51
-
52
- String.prototype.ss = function(from, to) {
53
- return this.substring(from<0 ? this.length-from : from, to<0 ? this.length+to : to);
54
- };
55
-
56
- String.prototype.pad = function(lngt, filler) {
57
- return (filler || ' ').repeat(Math.max(0,lngt - this.length)) + this;
58
- };
59
-
60
- String.prototype.escapeRegExp = function() {
61
- return this.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
62
- };
63
-
64
- String.prototype.startsBy = function(sub, caseInsensitive) {
65
- return 0 <= this.search(new RegExp('^'+sub.escapeRegExp(), caseInsensitive ? 'i' : ''));
66
- };
67
-
68
- String.prototype.endsBy = function(sub, caseInsensitive) {
69
- return 0 <= this.search(new RegExp(sub.escapeRegExp()+'$', caseInsensitive ? 'i' : ''));
70
- };
71
-
72
- String.prototype.includeLeading = function(sub) { return this.startsBy(sub) ? this : sub+this };
73
- String.prototype.includeTrailing = function(sub) { return this.endsBy(sub) ? this : this+sub };
74
- // if in the following function the casting to string is not made, the resulting typeof is 'object' instead of 'string' (causing problems in some cases, e.g. using path.join)
75
- String.prototype.excludeLeading = function(sub) { return this.startsBy(sub) ? this.slice(sub.length) : ''+this };
76
- String.prototype.excludeTrailing = function(sub) { return this.endsBy(sub) ? this.slice(0,-sub.length) : ''+this };
77
-
78
- // handy shortcuts
79
- String.prototype.low = String.prototype.toLowerCase;
80
- String.prototype.up = String.prototype.toUpperCase;
81
-
82
- // case insensitive test
83
- String.prototype.same = function(s){
84
- return typeof s === 'string'
85
- && this.length === s.length
86
- && this.low() === s.low()
87
- }; // String.same
88
-
89
- String.prototype.in = function(s) {
90
- switch (typeof s) {
91
- case 'array':
92
- case 'string': return s.indexOf(this) >= 0;
93
- default: return false;
94
- }
95
- }; // String.in
96
-
97
- ///////// EXTENDING OBJECT
98
-
99
- function extendObject(key, value) {
100
- Object.defineProperty(Object.prototype, key, {
101
- enumerable: false,
102
- value: value
103
- });
104
- } // extendObject
105
-
106
- extendObject('getKeyOf', function(value) {
107
- for (var i in this)
108
- if (this.hasOwnProperty(i)
109
- && this[i] === value)
110
- return i;
111
- return null;
112
- }); // Object.getKeyOf
113
-
114
- extendObject('forEach', function(cb) {
115
- for (var i in this)
116
- if (this.hasOwnProperty(i))
117
- cb.call(this, this[i], i);
118
- }); // Object.forEach
119
-
120
- extendObject('isIn', function(vals) {
121
- if (arguments.length == 1) {
122
- return Array.isArray(vals)
123
- ? vals.indexOf(this) >= 0
124
- : vals.keyOf(this) !== null;
125
- }
126
- for (var i in arguments)
127
- if (arguments[i] == this)
128
- return true;
129
- return false;
130
- }); // Object.isIn
131
-
132
- extendObject('extend', function(from) {
133
- var props = Object.getOwnPropertyNames(from);
134
- var dest = this;
135
- props.forEach(function(name) {
136
- var setter = dest.__lookupSetter__(name);
137
- if (setter) {
138
- setter.call(dest, from[name]);
139
- }
140
- else if (name in dest) {
141
- var destination = Object.getOwnPropertyDescriptor(from, name);
142
- Object.defineProperty(dest, name, destination);
143
- }
144
- else {
145
- dest[name] = from[name];
146
- }
147
- });
148
- return this;
149
- }); // Object.extend
150
-
151
-
152
- extendObject('getProperties', function(){
153
- var res = [];
154
- for (var i in this)
155
- if (this.hasOwnProperty(i))
156
- res.push(this[i]);
157
- return res;
158
- }); // Object.getProperties
package/lib/mime.js DELETED
@@ -1,19 +0,0 @@
1
- var types = exports.types = {
2
- 'jpg,jpeg': 'image/jpeg',
3
- 'gif': 'image/gif',
4
- 'png': 'image/png',
5
- 'css': 'text/css',
6
- 'js' : 'text/javascript',
7
- 'avi': 'video/avi',
8
- 'html': 'text/html',
9
- };
10
-
11
- exports.fromFile = function(file){
12
- var ext = path.extname(file).substr(1).low();
13
- for (var w in types) {
14
- if (w.split(',').indexOf(ext) >= 0) {
15
- return types[w];
16
- }
17
- }
18
- return false;
19
- }; // fromFile
package/lib/misc.js DELETED
@@ -1,75 +0,0 @@
1
- //// PROJECT-WIDE FUNCTIONS
2
-
3
- ceLib = require('cloneextend');
4
-
5
- ////// FIRST, UTILITIES WE WANT TO BE GLOBAL
6
-
7
- GLOBAL.ABCifB = function(a,b,c) { return b ? ''+a+b+(c||'') : ''; }
8
-
9
- // like console.log but better: outputs multiple parameters and returns first one, so you can concatenate
10
- GLOBAL.log = function() {
11
- var last;
12
- for (var k in arguments) {
13
- console.log(last = arguments[k]);
14
- }
15
- return last;
16
- }; // log
17
-
18
- // outputs to console and to a file (that's cleared at first writing). If 2 parameters are supplied, the first is a label to the data.
19
- GLOBAL.dbg = function(/*pre, */s) {
20
- var pre = '';
21
- if (arguments.length === 2) {
22
- pre = arguments[0]+': ';
23
- s = arguments[1];
24
- }
25
- var self = arguments.callee;
26
- if (!self.once) {
27
- self.once = 1;
28
- self.fn = 'dbg.txt';
29
- try { fs.unlinkSync(self.fn); } // this happens only once, who cares if it's blocking
30
- catch(err) {}
31
- }
32
- var stream = fs.createWriteStream(self.fn, {flags:'a'});
33
- stream.write(pre+s+"\n");
34
- stream.end();
35
- console.log('DBG) ', pre, s);
36
- return s;
37
- }; // dbg
38
-
39
- // used as a weaker assert() that doesn't stop execution
40
- GLOBAL.warning = function(condition, message){ if (!condition) dbg('Condition not met',message) };
41
-
42
- /*
43
- meant to implement Enum's. You can pass every value as a separate parameter, or as a single parameter with space as a separator.
44
- It returns an object with enum's values as keys, and coupled values are a "nicer".
45
- */
46
- GLOBAL.Enum = function() {
47
- var a = (arguments.length === 1) ? arguments[0].split(' ') : arguments;
48
- var res = {};
49
- for (var i=0,l=a.length; i<l; ++i) {
50
- res[a[i]] = a[i].toLowerCase().replace('_',' '); // valore descrittivo, utile per eventuali output
51
- }
52
- return res;
53
- }; // Enum
54
-
55
- // type-independent size calculation (currently accepting array's and object's)
56
- GLOBAL.sizeOf = function(o) {
57
- if (util.isArray(o))
58
- return o.length;
59
- return Object.keys(o).length;
60
- }; // sizeOf
61
-
62
- exports.clone = ceLib.clone;
63
- //exports.extend = ceLib.extend.bind(ceLib); we are currently using {}.extend instead of this
64
-
65
- exports.isWindows = os.platform() === 'win32';
66
- exports.caseSensitiveFileNames = !exports.isWindows;
67
-
68
- exports.sameFileName = function(a,b) {
69
- return exports.caseSensitiveFileNames ? a === b : a && a.same(b);
70
- }; // sameFileName
71
-
72
- exports.round = function(v, decimals) {
73
- decimals = Math.pow(10, decimals||0);
74
- return Math.round(v*decimals)/decimals;
75
- } // round
package/lib/serving.js DELETED
@@ -1,81 +0,0 @@
1
- require('./common');
2
- var mime = require('./mime');
3
- var url = require('url');
4
-
5
- exports.serveFile = serveFile = function(file, httpRes, size, mime_) {
6
- fs.exists(file, function(exists) {
7
- if (!exists) {
8
- serve404(httpRes);
9
- return;
10
- }
11
- var stream = fs.createReadStream(file);
12
- var headers = {
13
- 'Content-Type': mime_ || mime.fromFile(file) || 'application/octet-stream'
14
- };
15
- if (size) {
16
- headers['Content-Length'] = size;
17
- }
18
- httpRes.writeHead(200, headers);
19
- stream.pipe(httpRes);
20
- });
21
- }; // serveFile
22
-
23
- exports.serve404 = serve404 = function(httpRes) {
24
- httpRes.writeHead(404);
25
- httpRes.end();
26
- } // serve404
27
-
28
- exports.serveStatic = function(httpReq, httpRes) {
29
- if (httpReq.uri.substr(0,3) === '/~/') {
30
- serveFile('static'+httpReq.uri.substr(2), httpRes);
31
- return true;
32
- }
33
- return false;
34
- }; // serveStatic
35
-
36
- exports.parseUrl = function(httpReq) {
37
- httpReq.parsedUrl = url.parse(httpReq.url, true);
38
- with (httpReq.parsedUrl) pathname = decodeURI(pathname);
39
- httpReq.uri = httpReq.parsedUrl.pathname; // a shortcut, since this is often accessed
40
-
41
- // check for directory crossing
42
- if (httpReq.uri.indexOf('..') >= 0) {
43
- httpRes.writeHead(500);
44
- httpRes.end('Xdir');
45
- return false;
46
- }
47
-
48
- return true;
49
- }; // parseUrl
50
-
51
- // a standardized way to report an assertions' errors over socket.io
52
- exports.ioError = function(message, cb, more) {
53
- if (!cb) return;
54
- assert(typeof cb === 'function', 'cb');
55
- if (message) {
56
- if (cb) cb({ok:false, error:message}.extend(more||{}));
57
- return true;
58
- }
59
- return false;
60
- }; // ioError
61
-
62
- exports.ioOk = ioOk = function(cb, more) {
63
- if (!cb) return;
64
- assert(typeof cb === 'function', 'cb');
65
- cb({ok:true}.extend(more||{}));
66
- }; // ioOk
67
-
68
- exports.setupSocketIO = function(io) {
69
- io.enable('browser client minification'); // send minified client
70
- io.enable('browser client etag'); // apply etag caching logic based on version number
71
- io.enable('browser client gzip'); // gzip the file
72
- io.set('log level', 1); // reduce logging
73
- // this next command is giving a warning. Disabled for now.
74
- /*io.set('transports', [ // enable all transports (optional if you want flashsocket)
75
- 'websocket'
76
- , 'flashsocket'
77
- , 'htmlfile'
78
- , 'xhr-polling'
79
- , 'jsonp-polling'
80
- ]);*/
81
- }; // setupSocketIO