total5 0.0.1-2 → 0.0.1-21

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/controller.js CHANGED
@@ -11,17 +11,21 @@ const REG_MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Min
11
11
  const REG_ENCODINGCLEANER = /[;\s]charset=utf-8/g;
12
12
 
13
13
  const CHECK_DATA = { POST: 1, PUT: 1, PATCH: 1, DELETE: 1 };
14
- const CHECK_COMPRESSION = { 'text/plain': true, 'text/javascript': true, 'text/css': true, 'text/jsx': true, 'application/javascript': true, 'application/x-javascript': true, 'application/json': true, 'text/xml': true, 'image/svg+xml': true, 'text/x-markdown': true, 'text/html': true };
14
+ const CHECK_COMPRESSION = { 'text/plain': true, 'text/javascript': true, 'text/css': true, 'text/jsx': true, 'application/javascript': true, 'application/x-javascript': true, 'application/json': true, 'application/xml': true, 'text/xml': true, 'image/svg+xml': true, 'text/x-markdown': true, 'text/html': true };
15
15
  const CHECK_CHARSET = { 'text/plain': true, 'text/javascript': true, 'text/css': true, 'text/jsx': true, 'application/javascript': true, 'application/x-javascript': true, 'application/json': true, 'text/xml': true, 'text/x-markdown': true, 'text/html': true };
16
16
  const CHECK_NOCACHE = { zip: 1, rar: 1 };
17
17
 
18
18
  const GZIP_FILE = { memLevel: 9 };
19
19
  const GZIP_STREAM = { memLevel: 1 };
20
20
 
21
+ const NOCACHE = 'private, no-cache, no-store, max-age=0';
22
+
21
23
  function Controller(req, res) {
22
24
 
23
25
  var ctrl = this;
24
26
 
27
+ req.controller = ctrl;
28
+
25
29
  ctrl.req = req;
26
30
  ctrl.res = res;
27
31
  ctrl.method = ctrl.req.method;
@@ -36,6 +40,7 @@ function Controller(req, res) {
36
40
  ctrl.url = ctrl.uri.key;
37
41
  ctrl.released = false;
38
42
  ctrl.downloaded = false;
43
+ ctrl.protocol = req.connection.encrypted || (req.headers['x-forwarded-protocol'] || req.headers['x-forwarded-proto']) === 'https' ? 'https' : 'http';
39
44
 
40
45
  for (let path of ctrl.split)
41
46
  ctrl.split2.push(path.toLowerCase());
@@ -57,7 +62,7 @@ function Controller(req, res) {
57
62
 
58
63
  ctrl.response = {
59
64
  status: 200,
60
- cache: DEBUG,
65
+ cache: global.DEBUG != true,
61
66
  minify: true,
62
67
  // minifyjson: false
63
68
  // encrypt: false
@@ -120,6 +125,10 @@ Controller.prototype = {
120
125
  return this.headers['x-requested-with'] === 'XMLHttpRequest';
121
126
  },
122
127
 
128
+ get extension() {
129
+ return this.ext;
130
+ },
131
+
123
132
  get ua() {
124
133
  if (this.$ua != null)
125
134
  return this.$ua;
@@ -153,8 +162,32 @@ Controller.prototype = {
153
162
 
154
163
  };
155
164
 
165
+ Controller.prototype.callback = function(err, value) {
166
+
167
+ var ctrl = this;
168
+
169
+ if (arguments.length == 0) {
170
+ return function(err, response) {
171
+ if (err)
172
+ ctrl.invalid(err);
173
+ else
174
+ ctrl.json(response);
175
+ };
176
+ }
177
+
178
+ if (err)
179
+ ctrl.invalid(err);
180
+ else {
181
+ if (value === undefined)
182
+ ctrl.success();
183
+ else
184
+ ctrl.json(value);
185
+ }
186
+
187
+ };
188
+
156
189
  Controller.prototype.csrf = function() {
157
- return DEF.onCSRFcreate(this);
190
+ return F.def.onCSRFcreate(this);
158
191
  };
159
192
 
160
193
  Controller.prototype.redirect = function(value, permanent) {
@@ -177,9 +210,8 @@ Controller.prototype.html = function(value) {
177
210
 
178
211
  ctrl.response.headers['content-type'] = 'text/html';
179
212
 
180
- if (value != null) {
213
+ if (value != null)
181
214
  ctrl.response.value = ctrl.response.minify && F.config.$minifyhtml ? F.TMinificators.html(value) : value;
182
- }
183
215
 
184
216
  ctrl.flush();
185
217
  F.stats.response.html++;
@@ -208,7 +240,7 @@ Controller.prototype.json = function(value, beautify, replacer) {
208
240
 
209
241
  var response = ctrl.response;
210
242
  response.headers['content-type'] = 'application/json';
211
- response.headers['cache-control'] = 'private, no-cache, no-store, max-age=0';
243
+ response.headers['cache-control'] = NOCACHE;
212
244
  response.headers.vary = 'Accept-Encoding, Last-Modified, User-Agent';
213
245
  response.headers.expires = '-1';
214
246
  response.value = JSON.stringify(value, beautify ? '\t' : null, replacer);
@@ -224,7 +256,7 @@ Controller.prototype.jsonstring = function(value) {
224
256
 
225
257
  var response = ctrl.response;
226
258
  response.headers['content-type'] = 'application/json';
227
- response.headers['cache-control'] = 'private, no-cache, no-store, max-age=0';
259
+ response.headers['cache-control'] = NOCACHE;
228
260
  response.headers.vary = 'Accept-Encoding, Last-Modified, User-Agent';
229
261
  response.headers.expires = '-1';
230
262
  response.value = value;
@@ -262,7 +294,7 @@ Controller.prototype.invalid = function(value) {
262
294
  }
263
295
 
264
296
  response.headers['content-type'] = 'application/json';
265
- response.headers['cache-control'] = 'private, no-cache, no-store, max-age=0';
297
+ response.headers['cache-control'] = NOCACHE;
266
298
  response.headers.vary = 'Accept-Encoding, Last-Modified, User-Agent';
267
299
  response.value = JSON.stringify(err.output(ctrl.language));
268
300
  response.status = err.status === 408 ? 503 : err.status;
@@ -347,7 +379,7 @@ Controller.prototype.fallback = function(code, err) {
347
379
  ctrl.response.status = 503;
348
380
  if (!view) {
349
381
  F.temporary.views.$pause = view = new F.TViewEngine.View();
350
- view.compiled = F.TViewEngine.compile('$pause', F.Fs.readFileSync(F.Path.join(F.config.$nodemodules, 'total5/pause.html'), 'utf8'), false);
382
+ view.compiled = F.TViewEngine.compile('$pause', F.Fs.readFileSync(F.Path.join(F.config.$total5, 'pause.html'), 'utf8'), false);
351
383
  }
352
384
  view.model = F.paused;
353
385
  } else {
@@ -355,7 +387,7 @@ Controller.prototype.fallback = function(code, err) {
355
387
  view = F.temporary.views.$error;
356
388
  if (!view) {
357
389
  F.temporary.views.$error = view = new F.TViewEngine.View();
358
- view.compiled = F.TViewEngine.compile('$error', F.Fs.readFileSync(F.Path.join(F.config.$nodemodules, 'total5/error.html'), 'utf8'), false);
390
+ view.compiled = F.TViewEngine.compile('$error', F.Fs.readFileSync(F.Path.join(F.config.$total5, 'error.html'), 'utf8'), false);
359
391
  }
360
392
  view.model = { code: code, status: F.TUtils.httpstatus(code), error: err ? (DEBUG ? err.toString() : '') : '' };
361
393
  }
@@ -566,6 +598,16 @@ Controller.prototype.proxy = function(opt) {
566
598
 
567
599
  };
568
600
 
601
+ Controller.prototype.done = function(arg) {
602
+ var ctrl = this;
603
+ return function(err, response) {
604
+ if (err)
605
+ ctrl.invalid(err);
606
+ else
607
+ ctrl.json(DEF.onSuccess(arg === true ? response : arg));
608
+ };
609
+ };
610
+
569
611
  Controller.prototype.success = function(value) {
570
612
  F.TUtils.success.value = value;
571
613
  this.json(F.TUtils.success);
@@ -735,20 +777,21 @@ Controller.prototype.free = function() {
735
777
  ctrl.payload = null;
736
778
 
737
779
  // Potential problem
738
- ctrl.body = null;
739
- ctrl.params = null;
740
- ctrl.query = null;
780
+ // ctrl.body = null;
781
+ // ctrl.params = null;
782
+ // ctrl.query = null;
741
783
 
742
784
  if (ctrl.preventclearfiles != true)
743
785
  ctrl.clear();
744
786
 
745
787
  // Clear resources
788
+ ctrl.req.controller = null;
746
789
 
747
790
  };
748
791
 
749
792
  Controller.prototype.hostname = function(path) {
750
793
  var ctrl = this;
751
- return ctrl.headers.host + ctrl.uri.pathname + (path ? path : '');
794
+ return ctrl.protocol + '://' + ctrl.headers.host + (path ? path : '');
752
795
  };
753
796
 
754
797
  Controller.prototype.$route = function() {
@@ -860,16 +903,33 @@ function readfile(filename, callback) {
860
903
  });
861
904
  }
862
905
 
863
- function notmodified(ctrl, date) {
906
+ Controller.prototype.notmodified = function(date) {
907
+ var ctrl = this;
864
908
  if (ctrl.headers['if-modified-since'] === date) {
865
909
  ctrl.response.status = 304;
866
- ctrl.response.headers['cache-control'] = 'public, max-age=11111111';
910
+ ctrl.response.headers['cache-control'] = 'public, must-revalidate, max-age=' + F.config.$httpmaxage; // 5 min.
867
911
  ctrl.response.headers['last-modified'] = date;
868
912
  ctrl.flush();
869
913
  F.stats.response.notmodified++;
870
914
  return true;
871
915
  }
872
- }
916
+ };
917
+
918
+ Controller.prototype.httpcache = function(date) {
919
+ var ctrl = this;
920
+
921
+ if (date instanceof Date)
922
+ date = date.toUTCString();
923
+
924
+ if (!ctrl.response.headers.expires)
925
+ ctrl.response.headers.expires = F.config.$httpexpire;
926
+
927
+ if (!ctrl.response.headers['cache-control'])
928
+ ctrl.response.headers['cache-control'] = 'public, must-revalidate, max-age=' + F.config.$httpmaxage; // 5 minute cache for revalidate (304)
929
+
930
+ ctrl.response.headers['last-modified'] = date;
931
+ ctrl.response.headers.etag = '858' + F.config.$httpetag;
932
+ };
873
933
 
874
934
  function multipart(ctrl) {
875
935
 
@@ -890,7 +950,7 @@ function multipart(ctrl) {
890
950
  }
891
951
 
892
952
  var boundary = type.substring(index + 9, end);
893
- var parser = F.TUtils.multipartparser(boundary, ctrl, function(err, meta) {
953
+ var parser = F.TUtils.multipartparser(boundary, ctrl.req, function(err, meta) {
894
954
 
895
955
  F.stats.performance.download += meta.size / 1024 / 1024;
896
956
 
@@ -909,6 +969,7 @@ function multipart(ctrl) {
909
969
  if (index !== -1)
910
970
  file.filename = file.filename.substring(index + 1);
911
971
 
972
+ file.ext = F.TUtils.getExtension(file.filename);
912
973
  ctrl.files.push(file);
913
974
  }
914
975
 
@@ -936,9 +997,10 @@ function multipart(ctrl) {
936
997
  }
937
998
 
938
999
  function authorize(ctrl) {
939
- if (DEF.onAuthorize) {
1000
+ if (F.def.onAuthorize) {
940
1001
  var opt = new F.TBuilders.Options(ctrl);
941
1002
  opt.TYPE = 'auth'; // important
1003
+ opt.query = ctrl.query;
942
1004
  opt.next = opt.callback;
943
1005
  opt.$callback = function(err, user) {
944
1006
  let auth = user ? 1 : 2;
@@ -953,7 +1015,7 @@ function authorize(ctrl) {
953
1015
  ctrl.fallback(401);
954
1016
  }
955
1017
  };
956
- DEF.onAuthorize(opt);
1018
+ F.def.onAuthorize(opt);
957
1019
  } else
958
1020
  execute(ctrl);
959
1021
  }
@@ -967,16 +1029,34 @@ function execute(ctrl) {
967
1029
  ctrl.params[param.name] = value;
968
1030
  }
969
1031
 
1032
+ if (!ctrl.language && F.def.onLocalize)
1033
+ ctrl.language = F.def.onLocalize(ctrl);
1034
+
970
1035
  if (ctrl.route.middleware.length) {
971
1036
  middleware(ctrl);
972
1037
  } else {
973
1038
  if (ctrl.route.api) {
974
1039
  let body = ctrl.body;
975
1040
  if (body && typeof(body) === 'object' && body.schema && typeof(body.schema) === 'string') {
1041
+
1042
+ let index = body.schema.indexOf('?');
1043
+ let query = null;
1044
+
1045
+ if (index !== -1) {
1046
+ query = body.schema.substring(index + 1);
1047
+ body.schema = body.schema.substring(0, index);
1048
+ }
1049
+
976
1050
  let schema = body.schema.split('/');
977
1051
  let endpoint = ctrl.route.api[schema[0]];
978
- let params = {};
979
1052
  if (endpoint) {
1053
+
1054
+ if ((endpoint.auth === 1 && ctrl.user == null) || (endpoint.auth === 2 && ctrl.user)) {
1055
+ ctrl.fallback(401);
1056
+ return;
1057
+ }
1058
+
1059
+ let params = {};
980
1060
  if (endpoint.params) {
981
1061
  for (let m of endpoint.params)
982
1062
  params[m.name] = schema[m.index] || '';
@@ -984,7 +1064,8 @@ function execute(ctrl) {
984
1064
  body = body.data;
985
1065
  if (!body || typeof(body) === 'object') {
986
1066
  ctrl.params = params;
987
- F.action(endpoint.actions, body || EMPTYOBJECT, ctrl).autorespond();
1067
+ ctrl.query = query ? query.parseEncoded() : {};
1068
+ F.action(endpoint.actions, body || {}, ctrl).autorespond();
988
1069
  return;
989
1070
  }
990
1071
  }
@@ -994,6 +1075,10 @@ function execute(ctrl) {
994
1075
  if (ctrl.route.actions) {
995
1076
  F.action(ctrl.route.actions, ctrl.body, ctrl).autorespond();
996
1077
  } else {
1078
+ if (ctrl.route.view) {
1079
+ ctrl.view(ctrl.route.view);
1080
+ return;
1081
+ }
997
1082
  let action = ctrl.route.action;
998
1083
  if (!action)
999
1084
  action = auto_view;
@@ -1004,7 +1089,7 @@ function execute(ctrl) {
1004
1089
  }
1005
1090
 
1006
1091
  function auto_view(ctrl) {
1007
- ctrl.view(ctrl.split[0] || 'index', ctrl.body);
1092
+ ctrl.view(ctrl.split[0] || 'index');
1008
1093
  }
1009
1094
 
1010
1095
  function send_html(ctrl, path) {
@@ -1023,17 +1108,24 @@ function send_html(ctrl, path) {
1023
1108
  readfile(path, function(err, output) {
1024
1109
 
1025
1110
  if (err) {
1026
- F.temporary.notfound[ctrl.uri.key] = 1;
1111
+
1112
+ if (!DEBUG)
1113
+ F.temporary.notfound[ctrl.uri.key] = 1;
1114
+
1027
1115
  ctrl.fallback(404);
1028
1116
  return;
1029
1117
  }
1030
1118
 
1119
+ if (!ctrl.language && F.def.onLocalize)
1120
+ ctrl.language = F.def.onLocalize(ctrl);
1121
+
1031
1122
  output.body = F.translate(ctrl.language, output.body);
1032
1123
 
1033
1124
  if (ctrl.response.minify && F.config.$minifyhtml)
1034
1125
  output.body = F.TMinificators.html(output.body);
1035
1126
 
1036
1127
  if (DEBUG) {
1128
+ ctrl.response.headers['cache-control'] = NOCACHE;
1037
1129
  ctrl.response.headers['last-modified'] = output.date;
1038
1130
  ctrl.response.headers['content-type'] = 'text/html';
1039
1131
  ctrl.response.value = output.body;
@@ -1069,7 +1161,10 @@ function send_css(ctrl, path) {
1069
1161
  readfile(path, function(err, output) {
1070
1162
 
1071
1163
  if (err) {
1072
- F.temporary.notfound[ctrl.uri.key] = 1;
1164
+
1165
+ if (!DEBUG)
1166
+ F.temporary.notfound[ctrl.uri.key] = 1;
1167
+
1073
1168
  ctrl.fallback(404);
1074
1169
  return;
1075
1170
  }
@@ -1078,6 +1173,7 @@ function send_css(ctrl, path) {
1078
1173
  output.body = F.TMinificators.css(output.body);
1079
1174
 
1080
1175
  if (DEBUG) {
1176
+ ctrl.response.headers['cache-control'] = NOCACHE;
1081
1177
  ctrl.response.headers['last-modified'] = output.date;
1082
1178
  ctrl.response.headers['content-type'] = 'text/css';
1083
1179
  ctrl.response.value = output.body;
@@ -1113,7 +1209,10 @@ function send_js(ctrl, path) {
1113
1209
  readfile(path, function(err, output) {
1114
1210
 
1115
1211
  if (err) {
1116
- F.temporary.notfound[ctrl.uri.key] = 1;
1212
+
1213
+ if (!DEBUG)
1214
+ F.temporary.notfound[ctrl.uri.key] = 1;
1215
+
1117
1216
  ctrl.fallback(404);
1118
1217
  return;
1119
1218
  }
@@ -1122,6 +1221,7 @@ function send_js(ctrl, path) {
1122
1221
  output.body = F.TMinificators.js(output.body);
1123
1222
 
1124
1223
  if (DEBUG) {
1224
+ ctrl.response.headers['cache-control'] = NOCACHE;
1125
1225
  ctrl.response.headers['last-modified'] = output.date;
1126
1226
  ctrl.response.headers['content-type'] = 'text/javascript';
1127
1227
  ctrl.response.value = output.body;
@@ -1152,7 +1252,7 @@ function send_file(ctrl, path, ext) {
1152
1252
  var cache = F.temporary.tmp[ctrl.uri.key];
1153
1253
 
1154
1254
  // HTTP Cache
1155
- if (ctrl.response.cache && cache && notmodified(ctrl, cache.date))
1255
+ if (ctrl.response.cache && cache && ctrl.notmodified(cache.date))
1156
1256
  return;
1157
1257
 
1158
1258
  var accept = ctrl.headers['accept-encoding'];
@@ -1165,18 +1265,24 @@ function send_file(ctrl, path, ext) {
1165
1265
 
1166
1266
  if (err) {
1167
1267
 
1168
- if (ctrl.response.cache)
1268
+ if (!DEBUG && ctrl.response.cache)
1169
1269
  F.temporary.notfound[ctrl.uri.key] = true;
1170
1270
 
1171
1271
  ctrl.fallback(404);
1172
1272
  return;
1173
1273
  }
1174
1274
 
1175
- if (httpcache)
1176
- ctrl.response.headers.expires = F.config.$httpexpire;
1177
- else if (ctrl.response.headers.expires)
1275
+ if (httpcache) {
1276
+ if (!ctrl.response.headers.expires)
1277
+ ctrl.response.headers.expires = F.config.$httpexpire;
1278
+ if (!ctrl.response.headers['cache-control'])
1279
+ ctrl.response.headers['cache-control'] = 'public, must-revalidate, max-age=' + F.config.$httpmaxage; // 5 minute cache for revalidate (304)
1280
+ } else if (ctrl.response.headers.expires)
1178
1281
  delete ctrl.response.headers.expires;
1179
1282
 
1283
+ if (!httpcache)
1284
+ ctrl.response.headers['cache-control'] = NOCACHE;
1285
+
1180
1286
  if (!cache)
1181
1287
  cache = { date: stats.mtime.toUTCString(), size: stats.size };
1182
1288
 
@@ -1273,6 +1379,9 @@ function HttpFile(meta) {
1273
1379
  }
1274
1380
 
1275
1381
  HttpFile.prototype = {
1382
+ get extension() {
1383
+ return this.ext;
1384
+ },
1276
1385
  get isImage() {
1277
1386
  return this.type.indexOf('image/') !== -1;
1278
1387
  },
@@ -1313,7 +1422,7 @@ HttpFile.prototype.$move = function(filename, callback) {
1313
1422
  } else {
1314
1423
  if (!err) {
1315
1424
  self.path = filename;
1316
- self.rem = false;
1425
+ self.removable = false;
1317
1426
  }
1318
1427
  callback && callback(err);
1319
1428
  }
package/filestorage.js CHANGED
@@ -7,6 +7,7 @@
7
7
  const IMAGES = { jpg: 1, png: 1, gif: 1, svg: 1, jpeg: 1, heic: 1, heif: 1, webp: 1, tiff: 1, bmp: 1 };
8
8
  const HEADERSIZE = 2000;
9
9
  const MKDIR = { recursive: true };
10
+ const READDIR = { withFileTypes: true };
10
11
  const GZIP_FILE = { memLevel: 9 };
11
12
 
12
13
  const REG_RANGE = /bytes=/;
@@ -94,14 +95,14 @@ FP.readjson = function(id, callback) {
94
95
  });
95
96
  };
96
97
 
97
- FP.save = FP.insert = function(id, name, filename, callback, custom, expire, headers) {
98
+ FP.save = FP.insert = function(id, name, filename, custom, callback, expire, headers) {
98
99
  var self = this;
99
100
 
100
- if (callback && typeof(callback) !== 'function') {
101
+ if (typeof(custom) === 'function') {
101
102
  headers = expire;
102
- expire = custom;
103
- custom = callback;
104
- callback = null;
103
+ expire = callback;
104
+ callback = custom;
105
+ custom = null;
105
106
  }
106
107
 
107
108
  if (callback)
@@ -435,7 +436,7 @@ FP._readbuffer = function(id, callback) {
435
436
  FP.browse = function(callback) {
436
437
  var db = NOSQL(this.logger).find();
437
438
  if (callback)
438
- db.$callback = callback;
439
+ db.main.callback = callback;
439
440
  return db;
440
441
  };
441
442
 
@@ -743,11 +744,11 @@ FP._clear = function(callback) {
743
744
  return self;
744
745
  };
745
746
 
746
- FP.stream = function(onfile, callback, workers) {
747
+ FP.stream = function(onfile, callback, workers = 2) {
747
748
 
748
749
  var self = this;
749
750
 
750
- F.Fs.readdir(self.directory, function(err, response) {
751
+ F.Fs.readdir(self.directory, READDIR, function(err, response) {
751
752
 
752
753
  if (err) {
753
754
  callback();
@@ -758,15 +759,33 @@ FP.stream = function(onfile, callback, workers) {
758
759
 
759
760
  response.wait(function(item, next) {
760
761
 
761
- if (item.length !== 4) {
762
+ if (!item.isDirectory()) {
763
+ next();
764
+ return;
765
+ }
766
+
767
+ if (item.name.length !== 4) {
762
768
  next();
763
769
  return;
764
770
  }
765
771
 
766
- F.Fs.readdir(F.Path.join(self.directory, item), function(err, files) {
772
+ F.Fs.readdir(F.Path.join(self.directory, item.name), READDIR, function(err, files) {
767
773
  if (files instanceof Array) {
768
774
  files.wait(function(item, next) {
769
- var id = item.substring(0, item.lastIndexOf('.'));
775
+
776
+ if (!item.isFile()) {
777
+ next();
778
+ return;
779
+ }
780
+
781
+ let index = item.name.lastIndexOf('.');
782
+
783
+ if (item.name.substring(index) !== '.file') {
784
+ next();
785
+ return;
786
+ }
787
+
788
+ let id = item.name.substring(0, index);
770
789
  self.read(id, function(err, meta) {
771
790
  if (meta) {
772
791
  meta.id = id;
@@ -976,14 +995,8 @@ FP.http = function(ctrl, opt) {
976
995
  var date = obj.date ? obj.date.toUTCString() : '';
977
996
  var response = ctrl.response;
978
997
 
979
- if (!opt.download && ctrl.headers['if-modified-since'] === date) {
980
- response.status = 304;
981
- response.headers['cache-control'] = 'public, max-age=11111111';
982
- response.headers['last-modified'] = date;
983
- ctrl.flush();
984
- F.stats.response.notmodified++;
998
+ if (!opt.download && date && ctrl.notmodified(date))
985
999
  return;
986
- }
987
1000
 
988
1001
  // Resized image?
989
1002
  if (!DEBUG && F.temporary.path[ctrl.uri.key]) {
@@ -1047,7 +1060,10 @@ FP.http = function(ctrl, opt) {
1047
1060
 
1048
1061
  response.status = 206;
1049
1062
  response.headers['accept-ranges'] = 'bytes';
1050
- response.headers['cache-control'] = DEBUG ? 'private, no-cache, no-store, max-age=0' : 'public, max-age=11111111';
1063
+
1064
+ if (!opt.download && !DEBUG && date)
1065
+ ctrl.httpcache(date);
1066
+
1051
1067
  response.headers['content-length'] = length;
1052
1068
  response.headers['content-range'] = 'bytes ' + beg + '-' + end + '/' + obj.size;
1053
1069
  response.headers['content-type'] = obj.type;
@@ -1060,6 +1076,10 @@ FP.http = function(ctrl, opt) {
1060
1076
 
1061
1077
  } else {
1062
1078
  var stream = F.Fs.createReadStream(filename, { start: HEADERSIZE });
1079
+
1080
+ if (!opt.download && !DEBUG && date)
1081
+ ctrl.httpcache(date);
1082
+
1063
1083
  ctrl.stream(obj.type, stream);
1064
1084
  }
1065
1085
  }