pixl-server-storage 3.0.12 → 3.0.16
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.
- package/engines/Couchbase.js +1 -1
- package/engines/Filesystem.js +1 -1
- package/engines/Redis.js +2 -4
- package/engines/RedisCluster.js +1 -3
- package/engines/S3.js +22 -19
- package/package.json +1 -1
- package/storage.js +6 -2
package/engines/Couchbase.js
CHANGED
|
@@ -256,7 +256,7 @@ module.exports = Class.create({
|
|
|
256
256
|
else if (!isNaN(start) && isNaN(end)) {
|
|
257
257
|
end = buf.length ? buf.length - 1 : 0;
|
|
258
258
|
}
|
|
259
|
-
if ((start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
259
|
+
if (isNaN(start) || isNaN(end) || (start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
260
260
|
download.destroy();
|
|
261
261
|
callback( new Error("Invalid byte range (" + start + '-' + end + ") for key: " + key + " (len: " + buf.length + ")"), null );
|
|
262
262
|
return;
|
package/engines/Filesystem.js
CHANGED
|
@@ -488,7 +488,7 @@ module.exports = Class.create({
|
|
|
488
488
|
else if (!isNaN(start) && isNaN(end)) {
|
|
489
489
|
end = stats.size ? stats.size - 1 : 0;
|
|
490
490
|
}
|
|
491
|
-
if ((start < 0) || (start >= stats.size) || (end < start) || (end >= stats.size)) {
|
|
491
|
+
if (isNaN(start) || isNaN(end) || (start < 0) || (start >= stats.size) || (end < start) || (end >= stats.size)) {
|
|
492
492
|
download.destroy();
|
|
493
493
|
callback( new Error("Invalid byte range (" + start + '-' + end + ") for key: " + key + " (len: " + stats.size + ")"), null );
|
|
494
494
|
return;
|
package/engines/Redis.js
CHANGED
|
@@ -39,10 +39,8 @@ module.exports = Class.create({
|
|
|
39
39
|
|
|
40
40
|
this.keyPrefix = (r_config.keyPrefix || '').replace(/^\//, '');
|
|
41
41
|
if (this.keyPrefix && !this.keyPrefix.match(/\/$/)) this.keyPrefix += '/';
|
|
42
|
-
delete r_config.keyPrefix;
|
|
43
42
|
|
|
44
43
|
this.keyTemplate = (r_config.keyTemplate || '').replace(/^\//, '').replace(/\/$/, '');
|
|
45
|
-
delete r_config.keyTemplate;
|
|
46
44
|
|
|
47
45
|
r_config.return_buffers = true;
|
|
48
46
|
r_config.retry_strategy = function(opts) {
|
|
@@ -50,7 +48,7 @@ module.exports = Class.create({
|
|
|
50
48
|
return Math.min(opts.attempt * 100, 3000);
|
|
51
49
|
};
|
|
52
50
|
|
|
53
|
-
this.redis = Redis.createClient(r_config);
|
|
51
|
+
this.redis = Redis.createClient( Tools.copyHashRemoveKeys(r_config, { keyPrefix:1, keyTemplate:1 }) );
|
|
54
52
|
|
|
55
53
|
this.redis.on('error', function(err) {
|
|
56
54
|
if (!self.storage.started) return callback(err);
|
|
@@ -260,7 +258,7 @@ module.exports = Class.create({
|
|
|
260
258
|
else if (!isNaN(start) && isNaN(end)) {
|
|
261
259
|
end = buf.length ? buf.length - 1 : 0;
|
|
262
260
|
}
|
|
263
|
-
if ((start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
261
|
+
if (isNaN(start) || isNaN(end) || (start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
264
262
|
download.destroy();
|
|
265
263
|
callback( new Error("Invalid byte range (" + start + '-' + end + ") for key: " + key + " (len: " + buf.length + ")"), null );
|
|
266
264
|
return;
|
package/engines/RedisCluster.js
CHANGED
|
@@ -44,10 +44,8 @@ module.exports = Class.create({
|
|
|
44
44
|
|
|
45
45
|
this.keyPrefix = (r_config.keyPrefix || '').replace(/^\//, '');
|
|
46
46
|
if (this.keyPrefix && !this.keyPrefix.match(/\/$/)) this.keyPrefix += '/';
|
|
47
|
-
delete r_config.keyPrefix;
|
|
48
47
|
|
|
49
48
|
this.keyTemplate = (r_config.keyTemplate || '').replace(/^\//, '').replace(/\/$/, '');
|
|
50
|
-
delete r_config.keyTemplate;
|
|
51
49
|
|
|
52
50
|
r_config.clusterOpts.clusterRetryStrategy = function(attempts) {
|
|
53
51
|
if (attempts > r_config.connectRetries) return false;
|
|
@@ -277,7 +275,7 @@ module.exports = Class.create({
|
|
|
277
275
|
else if (!isNaN(start) && isNaN(end)) {
|
|
278
276
|
end = buf.length ? buf.length - 1 : 0;
|
|
279
277
|
}
|
|
280
|
-
if ((start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
278
|
+
if (isNaN(start) || isNaN(end) || (start < 0) || (start >= buf.length) || (end < start) || (end >= buf.length)) {
|
|
281
279
|
download.destroy();
|
|
282
280
|
callback( new Error("Invalid byte range (" + start + '-' + end + ") for key: " + key + " (len: " + buf.length + ")"), null );
|
|
283
281
|
return;
|
package/engines/S3.js
CHANGED
|
@@ -37,13 +37,9 @@ module.exports = Class.create({
|
|
|
37
37
|
|
|
38
38
|
this.keyPrefix = (s3_config.keyPrefix || '').replace(/^\//, '');
|
|
39
39
|
if (this.keyPrefix && !this.keyPrefix.match(/\/$/)) this.keyPrefix += '/';
|
|
40
|
-
delete s3_config.keyPrefix;
|
|
41
40
|
|
|
42
41
|
this.keyTemplate = (s3_config.keyTemplate || '').replace(/^\//, '').replace(/\/$/, '');
|
|
43
|
-
delete s3_config.keyTemplate;
|
|
44
|
-
|
|
45
42
|
this.fileExtensions = !!s3_config.fileExtensions;
|
|
46
|
-
delete s3_config.fileExtensions;
|
|
47
43
|
|
|
48
44
|
if (this.debugLevel(10)) {
|
|
49
45
|
// S3 has a logger API but it's extremely verbose -- restrict to level 10 only
|
|
@@ -70,7 +66,7 @@ module.exports = Class.create({
|
|
|
70
66
|
delete s3_config.cache;
|
|
71
67
|
|
|
72
68
|
AWS.config.update( aws_config );
|
|
73
|
-
this.s3 = new AWS.S3( s3_config );
|
|
69
|
+
this.s3 = new AWS.S3( Tools.copyHashRemoveKeys(s3_config, { keyPrefix:1, keyTemplate:1, fileExtensions:1, cache:1 }) );
|
|
74
70
|
},
|
|
75
71
|
|
|
76
72
|
prepKey: function(key) {
|
|
@@ -131,7 +127,7 @@ module.exports = Class.create({
|
|
|
131
127
|
if (done) return; else done = true;
|
|
132
128
|
|
|
133
129
|
if (err) {
|
|
134
|
-
self.logError('s3', "Failed to store object: " + key + ": " + err.message);
|
|
130
|
+
self.logError('s3', "Failed to store object: " + key + ": " + (err.message || err), err);
|
|
135
131
|
}
|
|
136
132
|
else self.logDebug(9, "Store complete: " + key);
|
|
137
133
|
|
|
@@ -162,7 +158,7 @@ module.exports = Class.create({
|
|
|
162
158
|
if (done) return; else done = true;
|
|
163
159
|
|
|
164
160
|
if (err) {
|
|
165
|
-
self.logError('s3', "Failed to store stream: " + key + ": " + err.message);
|
|
161
|
+
self.logError('s3', "Failed to store stream: " + key + ": " + (err.message || err), err);
|
|
166
162
|
}
|
|
167
163
|
else self.logDebug(9, "Stream store complete: " + key);
|
|
168
164
|
|
|
@@ -197,8 +193,8 @@ module.exports = Class.create({
|
|
|
197
193
|
if (done) return; else done = true;
|
|
198
194
|
|
|
199
195
|
if (err) {
|
|
200
|
-
if (err.code != 'NoSuchKey') {
|
|
201
|
-
self.logError('s3', "Failed to head key: " + key + ": " + err.message);
|
|
196
|
+
if ((err.code != 'NoSuchKey') && (err.code != 'NotFound')) {
|
|
197
|
+
self.logError('s3', "Failed to head key: " + key + ": " + (err.message || err), err);
|
|
202
198
|
}
|
|
203
199
|
callback( err, null );
|
|
204
200
|
return;
|
|
@@ -253,7 +249,7 @@ module.exports = Class.create({
|
|
|
253
249
|
}
|
|
254
250
|
else {
|
|
255
251
|
// some other error
|
|
256
|
-
self.logError('s3', "Failed to fetch key: " + key + ": " + err.message);
|
|
252
|
+
self.logError('s3', "Failed to fetch key: " + key + ": " + (err.message || err), err);
|
|
257
253
|
}
|
|
258
254
|
callback( err, null );
|
|
259
255
|
return;
|
|
@@ -298,7 +294,7 @@ module.exports = Class.create({
|
|
|
298
294
|
var proceed = false;
|
|
299
295
|
|
|
300
296
|
download.on('error', function(err) {
|
|
301
|
-
if (proceed) self.logError('s3', "Failed to download key: " + key + ": " + err.message);
|
|
297
|
+
if (proceed) self.logError('s3', "Failed to download key: " + key + ": " + (err.message || err), err);
|
|
302
298
|
});
|
|
303
299
|
download.once('end', function() {
|
|
304
300
|
self.logDebug(9, "S3 stream download complete: " + key);
|
|
@@ -313,8 +309,8 @@ module.exports = Class.create({
|
|
|
313
309
|
if (done) return; else done = true;
|
|
314
310
|
|
|
315
311
|
if (err) {
|
|
316
|
-
if (err.code != 'NoSuchKey') {
|
|
317
|
-
self.logError('s3', "Failed to head key: " + key + ": " + err.message);
|
|
312
|
+
if ((err.code != 'NoSuchKey') && (err.code != 'NotFound')) {
|
|
313
|
+
self.logError('s3', "Failed to head key: " + key + ": " + (err.message || err), err);
|
|
318
314
|
}
|
|
319
315
|
download.destroy();
|
|
320
316
|
callback( err, null );
|
|
@@ -338,11 +334,18 @@ module.exports = Class.create({
|
|
|
338
334
|
this.logDebug(9, "Fetching ranged S3 stream: " + key, { start, end });
|
|
339
335
|
|
|
340
336
|
var params = { Key: this.extKey(key, orig_key) };
|
|
341
|
-
|
|
337
|
+
|
|
338
|
+
// convert start/end to HTTP range header string
|
|
339
|
+
var range = "bytes=";
|
|
340
|
+
if (!isNaN(start)) range += start;
|
|
341
|
+
range += '-';
|
|
342
|
+
if (!isNaN(end)) range += end;
|
|
343
|
+
|
|
344
|
+
var download = self.s3.getObject( Tools.mergeHashes(params, { Range: range }) ).createReadStream();
|
|
342
345
|
var proceed = false;
|
|
343
346
|
|
|
344
347
|
download.on('error', function(err) {
|
|
345
|
-
if (proceed) self.logError('s3', "Failed to download key: " + key + ": " + err.message);
|
|
348
|
+
if (proceed) self.logError('s3', "Failed to download key: " + key + ": " + (err.message || err), err);
|
|
346
349
|
});
|
|
347
350
|
download.once('end', function() {
|
|
348
351
|
self.logDebug(9, "S3 stream download complete: " + key);
|
|
@@ -357,8 +360,8 @@ module.exports = Class.create({
|
|
|
357
360
|
if (done) return; else done = true;
|
|
358
361
|
|
|
359
362
|
if (err) {
|
|
360
|
-
if (err.code != 'NoSuchKey') {
|
|
361
|
-
self.logError('s3', "Failed to head key: " + key + ": " + err.message);
|
|
363
|
+
if ((err.code != 'NoSuchKey') && (err.code != 'NotFound')) {
|
|
364
|
+
self.logError('s3', "Failed to head key: " + key + ": " + (err.message || err), err);
|
|
362
365
|
}
|
|
363
366
|
download.destroy();
|
|
364
367
|
callback( err, null );
|
|
@@ -373,7 +376,7 @@ module.exports = Class.create({
|
|
|
373
376
|
else if (!isNaN(start) && isNaN(end)) {
|
|
374
377
|
end = data.ContentLength ? data.ContentLength - 1 : 0;
|
|
375
378
|
}
|
|
376
|
-
if ((start < 0) || (start >= data.ContentLength) || (end < start) || (end >= data.ContentLength)) {
|
|
379
|
+
if (isNaN(start) || isNaN(end) || (start < 0) || (start >= data.ContentLength) || (end < start) || (end >= data.ContentLength)) {
|
|
377
380
|
download.destroy();
|
|
378
381
|
callback( new Error("Invalid byte range (" + start + '-' + end + ") for key: " + key + " (len: " + data.ContentLength + ")"), null );
|
|
379
382
|
return;
|
|
@@ -401,7 +404,7 @@ module.exports = Class.create({
|
|
|
401
404
|
if (done) return; else done = true;
|
|
402
405
|
|
|
403
406
|
if (err) {
|
|
404
|
-
self.logError('s3', "Failed to delete object: " + key + ": " + err.message);
|
|
407
|
+
self.logError('s3', "Failed to delete object: " + key + ": " + (err.message || err), err);
|
|
405
408
|
}
|
|
406
409
|
else self.logDebug(9, "Delete complete: " + key);
|
|
407
410
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixl-server-storage",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.16",
|
|
4
4
|
"description": "A key/value/list storage component for the pixl-server framework.",
|
|
5
5
|
"author": "Joseph Huckaby <jhuckaby@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/jhuckaby/pixl-server-storage",
|
package/storage.js
CHANGED
|
@@ -34,7 +34,8 @@ module.exports = Class.create({
|
|
|
34
34
|
},
|
|
35
35
|
max_recent_events: 0,
|
|
36
36
|
cache_key_match: '',
|
|
37
|
-
expiration_updates: false
|
|
37
|
+
expiration_updates: false,
|
|
38
|
+
lower_case_keys: true
|
|
38
39
|
},
|
|
39
40
|
|
|
40
41
|
locks: null,
|
|
@@ -130,6 +131,7 @@ module.exports = Class.create({
|
|
|
130
131
|
this.logEventTypes = this.config.get('log_event_types');
|
|
131
132
|
this.maxRecentEvents = this.config.get('max_recent_events');
|
|
132
133
|
this.expHash = this.config.get('expiration_updates');
|
|
134
|
+
this.lowerKeys = this.config.get('lower_case_keys');
|
|
133
135
|
|
|
134
136
|
this.cacheKeyRegex = null;
|
|
135
137
|
if (this.config.get('cache_key_match')) {
|
|
@@ -139,7 +141,9 @@ module.exports = Class.create({
|
|
|
139
141
|
|
|
140
142
|
normalizeKey: function(key) {
|
|
141
143
|
// downconvert unicode, lower-case, alphanum-dash-dot-slash only, strip leading and trailing slashes
|
|
142
|
-
|
|
144
|
+
key = '' + key;
|
|
145
|
+
if (this.lowerKeys) key = key.toLowerCase();
|
|
146
|
+
return unidecode(key).replace(/[^\w\-\.\/]+/g, '').replace(/\/+/g, '/').replace(/^\//, '').replace(/\/$/, '');
|
|
143
147
|
},
|
|
144
148
|
|
|
145
149
|
isBinaryKey: function(key) {
|