megar 0.0.1
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.
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +11 -0
- data/CHANGELOG +5 -0
- data/Gemfile +4 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.rdoc +218 -0
- data/Rakefile +33 -0
- data/bin/megar +16 -0
- data/lib/extensions/math.rb +13 -0
- data/lib/js_ref_impl/_README +9 -0
- data/lib/js_ref_impl/base64_1.js +83 -0
- data/lib/js_ref_impl/crypto_5.js +1795 -0
- data/lib/js_ref_impl/download_8.js +867 -0
- data/lib/js_ref_impl/hex_1.js +76 -0
- data/lib/js_ref_impl/index_9.js +666 -0
- data/lib/js_ref_impl/js.manifest +115 -0
- data/lib/js_ref_impl/rsa_1.js +456 -0
- data/lib/js_ref_impl/sjcl_1.js +1 -0
- data/lib/js_ref_impl/upload_10.js +691 -0
- data/lib/megar.rb +11 -0
- data/lib/megar/catalog.rb +5 -0
- data/lib/megar/catalog/catalog_item.rb +90 -0
- data/lib/megar/catalog/file.rb +14 -0
- data/lib/megar/catalog/files.rb +13 -0
- data/lib/megar/catalog/folder.rb +20 -0
- data/lib/megar/catalog/folders.rb +28 -0
- data/lib/megar/connection.rb +84 -0
- data/lib/megar/crypto.rb +399 -0
- data/lib/megar/exception.rb +55 -0
- data/lib/megar/session.rb +157 -0
- data/lib/megar/shell.rb +87 -0
- data/lib/megar/version.rb +3 -0
- data/megar.gemspec +30 -0
- data/spec/fixtures/crypto_expectations/sample_user.json +109 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/crypto_expectations_helper.rb +44 -0
- data/spec/support/mocks_helper.rb +22 -0
- data/spec/unit/catalog/file_spec.rb +31 -0
- data/spec/unit/catalog/files_spec.rb +26 -0
- data/spec/unit/catalog/folder_spec.rb +28 -0
- data/spec/unit/catalog/folders_spec.rb +49 -0
- data/spec/unit/connection_spec.rb +50 -0
- data/spec/unit/crypto_spec.rb +476 -0
- data/spec/unit/exception_spec.rb +35 -0
- data/spec/unit/extensions/math_spec.rb +21 -0
- data/spec/unit/session_spec.rb +146 -0
- data/spec/unit/shell_spec.rb +18 -0
- metadata +238 -0
@@ -0,0 +1,867 @@
|
|
1
|
+
var dl_queue = [];
|
2
|
+
var dl_queue = [];
|
3
|
+
var dl_queue_num = 0;
|
4
|
+
var dl_retryinterval;
|
5
|
+
|
6
|
+
// 0 - FileSystem, 1 - Flash, 2 - Blob
|
7
|
+
var dl_method;
|
8
|
+
|
9
|
+
var dl_legacy_ie = (typeof XDomainRequest != 'undefined') && (typeof ArrayBuffer == 'undefined');
|
10
|
+
var dl_flash_connections;
|
11
|
+
var dl_flash_progress;
|
12
|
+
|
13
|
+
var dl_instance = 0;
|
14
|
+
|
15
|
+
var dl_blob;
|
16
|
+
|
17
|
+
var dl_key;
|
18
|
+
var dl_keyNonce;
|
19
|
+
var dl_macs;
|
20
|
+
var dl_aes;
|
21
|
+
|
22
|
+
var dl_filename;
|
23
|
+
var dl_filesize;
|
24
|
+
var dl_geturl;
|
25
|
+
var dl_bytesreceived = 0;
|
26
|
+
var dl_chunks;
|
27
|
+
var dl_chunksizes;
|
28
|
+
|
29
|
+
var downloading=false;
|
30
|
+
|
31
|
+
var dl_maxSlots = 4;
|
32
|
+
if (localStorage.dl_maxSlots) dl_maxSlots = localStorage.dl_maxSlots;
|
33
|
+
|
34
|
+
var dl_xhrs;
|
35
|
+
var dl_pos;
|
36
|
+
var dl_progress;
|
37
|
+
|
38
|
+
var dl_cipherq;
|
39
|
+
var dl_cipherqlen;
|
40
|
+
|
41
|
+
var dl_plainq;
|
42
|
+
var dl_plainqlen;
|
43
|
+
|
44
|
+
var dl_lastquotawarning;
|
45
|
+
|
46
|
+
var dl_maxWorkers = 4;
|
47
|
+
var dl_workers;
|
48
|
+
var dl_workerbusy;
|
49
|
+
|
50
|
+
var dl_write_position;
|
51
|
+
|
52
|
+
var dl_id;
|
53
|
+
|
54
|
+
function dl_dispatch_chain()
|
55
|
+
{
|
56
|
+
if (downloading)
|
57
|
+
{
|
58
|
+
dl_dispatch_read();
|
59
|
+
dl_dispatch_decryption();
|
60
|
+
dl_dispatch_write();
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
function dl_dispatch_decryption()
|
65
|
+
{
|
66
|
+
if (use_workers)
|
67
|
+
{
|
68
|
+
for (var id = dl_maxWorkers; id--; )
|
69
|
+
{
|
70
|
+
if (!dl_workerbusy[id]) break;
|
71
|
+
}
|
72
|
+
|
73
|
+
if (id >= 0)
|
74
|
+
{
|
75
|
+
for (var p in dl_cipherq)
|
76
|
+
{
|
77
|
+
dl_workerbusy[id] = 1;
|
78
|
+
|
79
|
+
if (typeof(dl_workers[id]) == "object")
|
80
|
+
{
|
81
|
+
dl_workers[id].terminate();
|
82
|
+
dl_workers[id] = null;
|
83
|
+
delete dl_workers[id];
|
84
|
+
}
|
85
|
+
|
86
|
+
dl_workers[id] = new Worker('decrypter.js');
|
87
|
+
dl_workers[id].postMessage = dl_workers[id].webkitPostMessage || dl_workers[id].postMessage;
|
88
|
+
dl_workers[id].id = id;
|
89
|
+
dl_workers[id].instance = dl_instance;
|
90
|
+
|
91
|
+
dl_workers[id].onmessage = function(e)
|
92
|
+
{
|
93
|
+
if (this.instance == dl_instance)
|
94
|
+
{
|
95
|
+
if (typeof(e.data) == "string")
|
96
|
+
{
|
97
|
+
if (e.data[0] == '[') dl_macs[this.dl_pos] = JSON.parse(e.data);
|
98
|
+
else if (d) console.log("WORKER" + this.id + ": '" + e.data + "'");
|
99
|
+
}
|
100
|
+
else
|
101
|
+
{
|
102
|
+
var databuf = new Uint8Array(e.data);
|
103
|
+
|
104
|
+
if (d) console.log("WORKER" + this.id + ": Received " + databuf.length + " decrypted bytes at " + this.dl_pos);
|
105
|
+
|
106
|
+
dl_plainq[this.dl_pos] = databuf;
|
107
|
+
dl_plainqlen++;
|
108
|
+
|
109
|
+
dl_workerbusy[this.id] = 0;
|
110
|
+
|
111
|
+
dl_dispatch_chain();
|
112
|
+
}
|
113
|
+
}
|
114
|
+
};
|
115
|
+
|
116
|
+
dl_workers[id].postMessage(dl_keyNonce);
|
117
|
+
|
118
|
+
if (d) console.log("WORKER" + id + ": Queueing " + dl_cipherq[p].length + " bytes at " + p);
|
119
|
+
|
120
|
+
dl_workers[id].dl_pos = parseInt(p);
|
121
|
+
dl_workers[id].postMessage(dl_workers[id].dl_pos/16);
|
122
|
+
dl_workers[id].postMessage(dl_cipherq[p]);
|
123
|
+
|
124
|
+
delete dl_cipherq[p];
|
125
|
+
dl_cipherqlen--;
|
126
|
+
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
else if (d) console.log("All worker threads are busy now.");
|
131
|
+
}
|
132
|
+
else
|
133
|
+
{
|
134
|
+
for (var p in dl_cipherq)
|
135
|
+
{
|
136
|
+
if (d) console.log("Decrypting pending block at " + p + " without workers...");
|
137
|
+
|
138
|
+
dl_macs[p] = decrypt_ab_ctr(dl_aes,dl_cipherq[p],[dl_key[4],dl_key[5]],p);
|
139
|
+
|
140
|
+
dl_plainq[p] = dl_cipherq[p];
|
141
|
+
delete dl_cipherq[p];
|
142
|
+
|
143
|
+
dl_cipherqlen--;
|
144
|
+
dl_plainqlen++;
|
145
|
+
|
146
|
+
break;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
function dl_resume(id)
|
152
|
+
{
|
153
|
+
if (downloading) dl_dispatch_chain();
|
154
|
+
else
|
155
|
+
{
|
156
|
+
if (id) for (var i = dl_queue.length; i--; ) if (id == dl_queue[i].id) dl_queue_num = i;
|
157
|
+
startdownload();
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
var test12;
|
162
|
+
|
163
|
+
function dl_dispatch_write()
|
164
|
+
{
|
165
|
+
if (dl_filesize == -1) return;
|
166
|
+
|
167
|
+
if (typeof dl_plainq[dl_write_position] != "object")
|
168
|
+
{
|
169
|
+
if (d) console.log("Plaintext at " + dl_write_position + " still missing: " + typeof dl_plainq[dl_write_position]);
|
170
|
+
dl_checklostchunk();
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
if (dl_method)
|
177
|
+
{
|
178
|
+
var p = dl_write_position;
|
179
|
+
|
180
|
+
dl_writedata(dl_plainq[p]);
|
181
|
+
|
182
|
+
dl_write_position += have_ab ? dl_plainq[p].length : dl_plainq[p].buffer.length;
|
183
|
+
|
184
|
+
delete dl_plainq[p];
|
185
|
+
dl_plainqlen--;
|
186
|
+
dl_dispatch_chain();
|
187
|
+
}
|
188
|
+
else
|
189
|
+
{
|
190
|
+
if (document.fileWriter.readyState == document.fileWriter.WRITING)
|
191
|
+
{
|
192
|
+
if (d) console.log("fileWriter is busy now. Please try again later.");
|
193
|
+
return;
|
194
|
+
}
|
195
|
+
|
196
|
+
if (d) console.log("Writing " + dl_plainq[dl_write_position].length + " bytes of file data at dl_pos " + dl_write_position + " real_position: " + document.fileWriter.position);
|
197
|
+
var blob = new Blob([dl_plainq[dl_write_position]]);
|
198
|
+
delete dl_plainq[dl_write_position];
|
199
|
+
|
200
|
+
document.fileWriter.instance = dl_instance;
|
201
|
+
|
202
|
+
document.fileWriter.onwriteend = function()
|
203
|
+
{
|
204
|
+
if (this.instance == dl_instance)
|
205
|
+
{
|
206
|
+
if (d) console.log("fileWriter: onwriteend, position: " + this.position);
|
207
|
+
dl_write_position = this.position;
|
208
|
+
dl_plainqlen--;
|
209
|
+
dl_dispatch_chain();
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
document.fileWriter.write(blob);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
var dl_timeout;
|
218
|
+
|
219
|
+
function dl_settimer(timeout,target)
|
220
|
+
{
|
221
|
+
if (d) console.log(timeout < 0 ? "Stopping timer" : "Starting timer " + timeout);
|
222
|
+
if (dl_timeout) clearTimeout(dl_timeout);
|
223
|
+
if (timeout >= 0) dl_timeout = setTimeout(target,timeout);
|
224
|
+
else dl_timeout = undefined;
|
225
|
+
}
|
226
|
+
|
227
|
+
// try to start download at dl_queue_num
|
228
|
+
// if that download is not available, loop through the whole dl_queue and try to start
|
229
|
+
// another one
|
230
|
+
function startdownload()
|
231
|
+
{
|
232
|
+
dl_settimer(-1);
|
233
|
+
|
234
|
+
if (downloading)
|
235
|
+
{
|
236
|
+
if (d) console.log("startdownload() called with active download");
|
237
|
+
return;
|
238
|
+
}
|
239
|
+
|
240
|
+
if (dl_queue_num >= dl_queue.length) dl_queue_num = dl_queue.length-1;
|
241
|
+
|
242
|
+
if (dl_queue_num < 0)
|
243
|
+
{
|
244
|
+
if (d) console.log("startdownload() called with dl_queue_num == -1");
|
245
|
+
return;
|
246
|
+
}
|
247
|
+
|
248
|
+
var dl_queue_num_start = dl_queue_num;
|
249
|
+
var t;
|
250
|
+
var retryin = -1;
|
251
|
+
|
252
|
+
for (;;)
|
253
|
+
{
|
254
|
+
if (dl_queue[dl_queue_num])
|
255
|
+
{
|
256
|
+
if (!dl_queue[dl_queue_num].retryafter) break;
|
257
|
+
|
258
|
+
if (!t) t = new Date().getTime();
|
259
|
+
|
260
|
+
if (t >= dl_queue[dl_queue_num].retryafter) break;
|
261
|
+
|
262
|
+
if (retryin < 0 || (dl_queue[dl_queue_num].retryafter-t < retryin))
|
263
|
+
{
|
264
|
+
retryin = dl_queue[dl_queue_num].retryafter-t;
|
265
|
+
if (retryin < 0) retryin = 0;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
dl_queue_num++;
|
270
|
+
|
271
|
+
if (dl_queue_num >= dl_queue.length)
|
272
|
+
{
|
273
|
+
if (d) console.log('Reached end of dl_queue, starting from 0');
|
274
|
+
dl_queue_num = 0;
|
275
|
+
}
|
276
|
+
|
277
|
+
if (dl_queue_num == dl_queue_num_start)
|
278
|
+
{
|
279
|
+
if (d) console.log('Looped through all downloads, nothing left');
|
280
|
+
dl_settimer(retryin,startdownload);
|
281
|
+
|
282
|
+
if (retryin < 0)
|
283
|
+
{
|
284
|
+
if (d) console.log('Nothing left to retry, clearing dl_queue');
|
285
|
+
dl_queue = [];
|
286
|
+
dl_queue_num = 0;
|
287
|
+
}
|
288
|
+
return;
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
downloading=true;
|
293
|
+
|
294
|
+
dl_key = dl_queue[dl_queue_num].key;
|
295
|
+
if (d) console.log("dl_key " + dl_key);
|
296
|
+
if (dl_queue[dl_queue_num].ph) dl_id = dl_queue[dl_queue_num].ph;
|
297
|
+
else dl_id = dl_queue[dl_queue_num].id;
|
298
|
+
|
299
|
+
dl_geturl = '';
|
300
|
+
|
301
|
+
dl_bytesreceived = 0;
|
302
|
+
dl_chunksizes = new Array;
|
303
|
+
|
304
|
+
dl_keyNonce = JSON.stringify([dl_key[0]^dl_key[4],dl_key[1]^dl_key[5],dl_key[2]^dl_key[6],dl_key[3]^dl_key[7],dl_key[4],dl_key[5]]);
|
305
|
+
|
306
|
+
dl_macs = {};
|
307
|
+
|
308
|
+
dl_filesize = -1;
|
309
|
+
|
310
|
+
dl_retryinterval = 1000;
|
311
|
+
|
312
|
+
dl_cipherq = [];
|
313
|
+
dl_cipherqlen = 0;
|
314
|
+
dl_plainq = [];
|
315
|
+
dl_plainqlen = 0;
|
316
|
+
dl_lastquotawarning = 0;
|
317
|
+
|
318
|
+
dl_pos = Array(dl_maxSlots);
|
319
|
+
dl_progress = Array(dl_maxSlots);
|
320
|
+
|
321
|
+
if (!dl_legacy_ie)
|
322
|
+
{
|
323
|
+
dl_xhrs = Array(dl_maxSlots);
|
324
|
+
|
325
|
+
for (var slot = dl_maxSlots; slot--; )
|
326
|
+
{
|
327
|
+
dl_xhrs[slot] = new XMLHttpRequest;
|
328
|
+
dl_xhrs[slot].slot = slot;
|
329
|
+
dl_pos[slot] = -1;
|
330
|
+
dl_progress[slot] = 0;
|
331
|
+
}
|
332
|
+
}
|
333
|
+
else
|
334
|
+
{
|
335
|
+
dl_flash_connections = 0;
|
336
|
+
dl_flash_progress = {};
|
337
|
+
}
|
338
|
+
|
339
|
+
if (use_workers)
|
340
|
+
{
|
341
|
+
dl_workers = new Array(dl_maxWorkers);
|
342
|
+
dl_workerbusy = new Array(dl_maxWorkers);
|
343
|
+
|
344
|
+
for (var id = dl_maxWorkers; id--; ) dl_workerbusy[id] = 0;
|
345
|
+
}
|
346
|
+
else dl_aes = new sjcl.cipher.aes([dl_key[0]^dl_key[4],dl_key[1]^dl_key[5],dl_key[2]^dl_key[6],dl_key[3]^dl_key[7]]);
|
347
|
+
|
348
|
+
dl_write_position = 0;
|
349
|
+
|
350
|
+
dl_getsourceurl(startdownload2);
|
351
|
+
}
|
352
|
+
|
353
|
+
function dl_renewsourceurl()
|
354
|
+
{
|
355
|
+
dl_getsourceurl(dl_renewsourceurl2);
|
356
|
+
}
|
357
|
+
|
358
|
+
function dl_getsourceurl(callback)
|
359
|
+
{
|
360
|
+
req = { a : 'g', g : 1, ssl : use_ssl };
|
361
|
+
|
362
|
+
if (dl_queue[dl_queue_num].ph) req.p = dl_queue[dl_queue_num].ph;
|
363
|
+
else if (dl_queue[dl_queue_num].id) req.n = dl_queue[dl_queue_num].id;
|
364
|
+
|
365
|
+
api_req([req],{ callback : callback });
|
366
|
+
}
|
367
|
+
|
368
|
+
function dl_renewsourceurl2(res,ctx)
|
369
|
+
{
|
370
|
+
if (typeof res == 'object')
|
371
|
+
{
|
372
|
+
if (typeof res[0] == 'number')
|
373
|
+
{
|
374
|
+
dl_reportstatus(dl_queue_num,res[0]);
|
375
|
+
}
|
376
|
+
else
|
377
|
+
{
|
378
|
+
if (dl_queue[dl_queue_num].g)
|
379
|
+
{
|
380
|
+
dl_geturl = dl_queue[dl_queue_num].g;
|
381
|
+
dl_dispatch_queue()
|
382
|
+
return;
|
383
|
+
}
|
384
|
+
else if (dl_queue[dl_queue_num].e) dl_reportstatus(dl_queue_num,dl_queue[dl_queue_num].e);
|
385
|
+
}
|
386
|
+
|
387
|
+
dl_queue_num++;
|
388
|
+
startdownload();
|
389
|
+
}
|
390
|
+
}
|
391
|
+
|
392
|
+
function dl_reportstatus(num,code)
|
393
|
+
{
|
394
|
+
if (dl_queue[num])
|
395
|
+
{
|
396
|
+
dl_queue[num].lasterror = code;
|
397
|
+
dl_queue[num].onDownloadError(dl_queue[num].id || dl_queue[num].ph,code);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
function startdownload2(res,ctx)
|
402
|
+
{
|
403
|
+
if (typeof res == 'object')
|
404
|
+
{
|
405
|
+
if (typeof res[0] == 'number')
|
406
|
+
{
|
407
|
+
dl_reportstatus(dl_queue_num,res[0]);
|
408
|
+
}
|
409
|
+
else
|
410
|
+
{
|
411
|
+
if (res[0].d)
|
412
|
+
{
|
413
|
+
dl_reportstatus(dl_queue_num,res[0].d ? 2 : 1);
|
414
|
+
dl_queue[dl_queue_num] = false;
|
415
|
+
}
|
416
|
+
else if (res[0].g)
|
417
|
+
{
|
418
|
+
var ab = base64_to_ab(res[0].at);
|
419
|
+
var o = dec_attr(ab,[dl_key[0]^dl_key[4],dl_key[1]^dl_key[5],dl_key[2]^dl_key[6],dl_key[3]^dl_key[7]]);
|
420
|
+
|
421
|
+
if (typeof o == 'object' && typeof o.n == 'string') return dl_setcredentials(res[0].g,res[0].s,o.n);
|
422
|
+
else dl_reportstatus(dl_queue_num,EKEY);
|
423
|
+
}
|
424
|
+
else dl_reportstatus(dl_queue_num,res[0].e);
|
425
|
+
}
|
426
|
+
}
|
427
|
+
else dl_reportstatus(dl_queue_num,EAGAIN);
|
428
|
+
|
429
|
+
downloading = false;
|
430
|
+
|
431
|
+
dl_queue_num++;
|
432
|
+
|
433
|
+
dl_retryinterval *= 1.2;
|
434
|
+
|
435
|
+
dl_settimer(dl_retryinterval,startdownload);
|
436
|
+
}
|
437
|
+
|
438
|
+
function dl_setcredentials(g,s,n)
|
439
|
+
{
|
440
|
+
var i;
|
441
|
+
var p;
|
442
|
+
var pp;
|
443
|
+
|
444
|
+
dl_geturl = g;
|
445
|
+
dl_filesize = s;
|
446
|
+
dl_filename = n;
|
447
|
+
|
448
|
+
dl_chunks = [];
|
449
|
+
|
450
|
+
p = pp = 0;
|
451
|
+
for (i = 1; i <= 8 && p < dl_filesize-i*131072; i++)
|
452
|
+
{
|
453
|
+
dl_chunksizes[p] = i*131072;
|
454
|
+
dl_chunks.push(p);
|
455
|
+
pp = p;
|
456
|
+
p += dl_chunksizes[p];
|
457
|
+
}
|
458
|
+
|
459
|
+
while (p < dl_filesize)
|
460
|
+
{
|
461
|
+
dl_chunksizes[p] = 1048576;
|
462
|
+
dl_chunks.push(p);
|
463
|
+
pp = p;
|
464
|
+
p += dl_chunksizes[p];
|
465
|
+
}
|
466
|
+
|
467
|
+
if (!(dl_chunksizes[pp] = dl_filesize-pp))
|
468
|
+
{
|
469
|
+
delete dl_chunksizes[pp];
|
470
|
+
delete dl_chunks[dl_chunks.length-1];
|
471
|
+
}
|
472
|
+
|
473
|
+
if (!dl_method) dl_createtmp();
|
474
|
+
else
|
475
|
+
{
|
476
|
+
if (dl_method == 2) dl_blob = new MSBlobBuilder();
|
477
|
+
else if (dl_method == 3)
|
478
|
+
{
|
479
|
+
// firefox extension:
|
480
|
+
|
481
|
+
ffe_createtmp();
|
482
|
+
|
483
|
+
}
|
484
|
+
dl_run();
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
function dl_run()
|
489
|
+
{
|
490
|
+
document.getElementById('dllink').download = dl_filename;
|
491
|
+
|
492
|
+
if (dl_filesize)
|
493
|
+
{
|
494
|
+
for (var slot = dl_maxSlots; slot--; ) dl_dispatch_read(slot);
|
495
|
+
dl_queue[dl_queue_num].onDownloadStart(dl_id,dl_filename,dl_filesize);
|
496
|
+
}
|
497
|
+
else dl_checklostchunk();
|
498
|
+
}
|
499
|
+
|
500
|
+
function dl_checklostchunk()
|
501
|
+
{
|
502
|
+
var i;
|
503
|
+
|
504
|
+
if (dl_write_position == dl_filesize)
|
505
|
+
{
|
506
|
+
dl_retryinterval = 1000;
|
507
|
+
|
508
|
+
if (dl_filesize)
|
509
|
+
{
|
510
|
+
var t = [];
|
511
|
+
|
512
|
+
for (p in dl_macs) t.push(p);
|
513
|
+
|
514
|
+
t.sort(function(a,b) { return parseInt(a)-parseInt(b) });
|
515
|
+
|
516
|
+
for (i = 0; i < t.length; i++) t[i] = dl_macs[t[i]];
|
517
|
+
|
518
|
+
var mac = condenseMacs(t,[dl_key[0]^dl_key[4],dl_key[1]^dl_key[5],dl_key[2]^dl_key[6],dl_key[3]^dl_key[7]]);
|
519
|
+
}
|
520
|
+
|
521
|
+
downloading = false;
|
522
|
+
|
523
|
+
if (dl_filesize && (dl_key[6] != (mac[0]^mac[1]) || dl_key[7] != (mac[2]^mac[3])))
|
524
|
+
{
|
525
|
+
dl_reportstatus(dl_queue_num,EKEY);
|
526
|
+
dl_queue[dl_queue_num] = false;
|
527
|
+
}
|
528
|
+
else
|
529
|
+
{
|
530
|
+
if (!dl_method)
|
531
|
+
{
|
532
|
+
dl_queue[dl_queue_num].onBeforeDownloadComplete();
|
533
|
+
document.getElementById('dllink').href = document.fileEntry.toURL();
|
534
|
+
if (document.getElementById('dllink').click) document.getElementById('dllink').click();
|
535
|
+
}
|
536
|
+
else if (dl_method == 1)
|
537
|
+
{
|
538
|
+
document.getElementById('dlswf_' + dl_id).flashdata(dl_id,'',dl_queue[dl_queue_num].n);
|
539
|
+
}
|
540
|
+
else if (dl_method == 2)
|
541
|
+
{
|
542
|
+
navigator.msSaveOrOpenBlob(dl_blob.getBlob(),dl_queue[dl_queue_num].n);
|
543
|
+
}
|
544
|
+
else if (dl_method == 3)
|
545
|
+
{
|
546
|
+
ffe_complete(dl_queue[dl_queue_num].n,dl_queue[dl_queue_num].p);
|
547
|
+
}
|
548
|
+
|
549
|
+
dl_queue[dl_queue_num].onDownloadComplete(dl_id);
|
550
|
+
dl_queue[dl_queue_num] = false;
|
551
|
+
dl_queue_num++;
|
552
|
+
|
553
|
+
// release all downloads waiting for quota
|
554
|
+
for (i = dl_queue.length; i--; ) if (dl_queue[i] && dl_queue[i].lasterror == EOVERQUOTA)
|
555
|
+
{
|
556
|
+
dl_reportstatus(i,0);
|
557
|
+
delete dl_queue[i].retryafter;
|
558
|
+
}
|
559
|
+
}
|
560
|
+
|
561
|
+
startdownload();
|
562
|
+
}
|
563
|
+
}
|
564
|
+
|
565
|
+
function dl_httperror(code)
|
566
|
+
{
|
567
|
+
if (code == 509)
|
568
|
+
{
|
569
|
+
var t = new Date().getTime();
|
570
|
+
|
571
|
+
if (!dl_lastquotawarning || t-dl_lastquotawarning > 55000)
|
572
|
+
{
|
573
|
+
dl_lastquotawarning = t;
|
574
|
+
dl_reportstatus(dl_queue_num,code == 509 ? EOVERQUOTA : ETOOMANYCONNECTIONS);
|
575
|
+
dl_settimer(60000,dl_dispatch_chain);
|
576
|
+
}
|
577
|
+
|
578
|
+
return;
|
579
|
+
}
|
580
|
+
|
581
|
+
dl_reportstatus(dl_queue_num,EAGAIN);
|
582
|
+
|
583
|
+
dl_retryinterval *= 1.2;
|
584
|
+
|
585
|
+
if (!dl_write_position)
|
586
|
+
{
|
587
|
+
dl_cancel();
|
588
|
+
dl_queue_num++;
|
589
|
+
dl_settimer(dl_retryinterval,startdownload);
|
590
|
+
}
|
591
|
+
else
|
592
|
+
{
|
593
|
+
if (d) console.log("Network error, retrying in " + Math.floor(dl_retryinterval) + " seconds...");
|
594
|
+
|
595
|
+
dl_settimer(dl_retryinterval,code == 509 ? dl_dispatch_chain : dl_renewsourceurl);
|
596
|
+
}
|
597
|
+
}
|
598
|
+
|
599
|
+
function flash_dlprogress(p,numbytes)
|
600
|
+
{
|
601
|
+
dl_flash_progress[p] = numbytes;
|
602
|
+
dl_updateprogress();
|
603
|
+
}
|
604
|
+
|
605
|
+
function dl_flashdldata(p,data,httpcode)
|
606
|
+
{
|
607
|
+
dl_flash_connections--;
|
608
|
+
|
609
|
+
if (data == 'ERROR' || httpcode != 200)
|
610
|
+
{
|
611
|
+
dl_chunks.unshift(p);
|
612
|
+
var t = new Date().getTime();
|
613
|
+
|
614
|
+
dl_httperror(httpcode);
|
615
|
+
|
616
|
+
return;
|
617
|
+
}
|
618
|
+
|
619
|
+
data = base64urldecode(data);
|
620
|
+
|
621
|
+
delete dl_flash_progress[p];
|
622
|
+
dl_bytesreceived += data.length;
|
623
|
+
|
624
|
+
dl_cipherq[p] = { buffer : data };
|
625
|
+
dl_cipherqlen++;
|
626
|
+
dl_updateprogress();
|
627
|
+
|
628
|
+
dl_dispatch_chain();
|
629
|
+
}
|
630
|
+
|
631
|
+
function dl_dispatch_read()
|
632
|
+
{
|
633
|
+
if (dl_cipherqlen+dl_plainqlen > dl_maxSlots+8) return;
|
634
|
+
|
635
|
+
if (!dl_chunks.length) return;
|
636
|
+
|
637
|
+
if (dl_legacy_ie)
|
638
|
+
{
|
639
|
+
if (dl_flash_connections > 6) return;
|
640
|
+
|
641
|
+
dl_flash_connections++;
|
642
|
+
|
643
|
+
var p = dl_chunks[0];
|
644
|
+
dl_chunks.splice(0,1);
|
645
|
+
flashdlchunk(p,dl_geturl + '/' + p + '-' + (p+dl_chunksizes[p]-1));
|
646
|
+
return;
|
647
|
+
}
|
648
|
+
|
649
|
+
for (var slot = dl_maxSlots; slot--; )
|
650
|
+
if (dl_pos[slot] == -1) break;
|
651
|
+
|
652
|
+
if (slot < 0) return;
|
653
|
+
|
654
|
+
dl_pos[slot] = dl_chunks[0];
|
655
|
+
dl_chunks.splice(0,1);
|
656
|
+
dl_xhrs[slot].instance = dl_instance;
|
657
|
+
|
658
|
+
if (d) console.log("Requesting chunk " + dl_pos[slot] + "/" + dl_chunksizes[dl_pos[slot]] + " on slot " + slot + ", " + dl_chunks.length + " remaining");
|
659
|
+
|
660
|
+
dl_xhrs[slot].onprogress = function(e)
|
661
|
+
{
|
662
|
+
if (this.instance == dl_instance)
|
663
|
+
{
|
664
|
+
if (!dl_lastquotawarning || new Date().getTime()-dl_lastquotawarning > 55000)
|
665
|
+
{
|
666
|
+
if (dl_pos[this.slot] >= 0)
|
667
|
+
{
|
668
|
+
dl_progress[this.slot] = e.loaded;
|
669
|
+
|
670
|
+
dl_updateprogress();
|
671
|
+
}
|
672
|
+
}
|
673
|
+
}
|
674
|
+
}
|
675
|
+
|
676
|
+
dl_xhrs[slot].onreadystatechange = function()
|
677
|
+
{
|
678
|
+
if (this.instance == dl_instance)
|
679
|
+
{
|
680
|
+
if (this.readyState == this.DONE)
|
681
|
+
{
|
682
|
+
if (dl_pos[this.slot] >= 0)
|
683
|
+
{
|
684
|
+
if (this.response != null)
|
685
|
+
{
|
686
|
+
var p = dl_pos[this.slot];
|
687
|
+
|
688
|
+
if (have_ab)
|
689
|
+
{
|
690
|
+
if (p >= 0)
|
691
|
+
{
|
692
|
+
if (navigator.appName != 'Opera') dl_bytesreceived += this.response.byteLength;
|
693
|
+
dl_cipherq[p] = new Uint8Array(this.response);
|
694
|
+
}
|
695
|
+
}
|
696
|
+
else
|
697
|
+
{
|
698
|
+
// non-IE
|
699
|
+
if (p >= 0)
|
700
|
+
{
|
701
|
+
dl_bytesreceived += this.response.length;
|
702
|
+
dl_cipherq[p] = { buffer : this.response };
|
703
|
+
}
|
704
|
+
}
|
705
|
+
|
706
|
+
dl_cipherqlen++;
|
707
|
+
if (navigator.appName != 'Opera') dl_progress[this.slot] = 0;
|
708
|
+
dl_updateprogress();
|
709
|
+
|
710
|
+
dl_pos[this.slot] = -1;
|
711
|
+
dl_dispatch_chain();
|
712
|
+
}
|
713
|
+
else
|
714
|
+
{
|
715
|
+
if (dl_pos[this.slot] != -1)
|
716
|
+
{
|
717
|
+
dl_chunks.unshift(dl_pos[this.slot]);
|
718
|
+
dl_pos[this.slot] = -1;
|
719
|
+
|
720
|
+
dl_httperror(this.status);
|
721
|
+
}
|
722
|
+
}
|
723
|
+
}
|
724
|
+
}
|
725
|
+
}
|
726
|
+
}
|
727
|
+
|
728
|
+
dl_xhrs[slot].open('POST', dl_geturl + '/' + dl_pos[slot] + '-' + (dl_pos[slot]+dl_chunksizes[dl_pos[slot]]-1), true);
|
729
|
+
dl_xhrs[slot].responseType = 'arraybuffer';
|
730
|
+
dl_xhrs[slot].send();
|
731
|
+
}
|
732
|
+
|
733
|
+
|
734
|
+
function dl_updateprogress()
|
735
|
+
{
|
736
|
+
var p = 0;
|
737
|
+
|
738
|
+
if (dl_legacy_ie) for (var pp in dl_flash_progress) p += dl_flash_progress[pp];
|
739
|
+
else for (var slot = dl_maxSlots; slot--; ) p += dl_progress[slot];
|
740
|
+
|
741
|
+
dl_queue[dl_queue_num].onDownloadProgress(dl_id, dl_bytesreceived + p, dl_filesize);
|
742
|
+
}
|
743
|
+
|
744
|
+
function dl_writedata(data)
|
745
|
+
{
|
746
|
+
if (dl_method == 1)
|
747
|
+
{
|
748
|
+
var j, k;
|
749
|
+
var len;
|
750
|
+
|
751
|
+
if (have_ab) len = data.length;
|
752
|
+
else len = data.buffer.length;
|
753
|
+
|
754
|
+
console.log(len);
|
755
|
+
|
756
|
+
if (have_ab) subdata = ab_to_base64(data);
|
757
|
+
else subdata = base64urlencode(data.buffer);
|
758
|
+
|
759
|
+
document.getElementById('dlswf_' + dl_id).flashdata(dl_id,subdata);
|
760
|
+
}
|
761
|
+
else if (dl_method == 3)
|
762
|
+
{
|
763
|
+
ffe_writechunk(ab_to_str(data),dl_write_position);
|
764
|
+
}
|
765
|
+
else
|
766
|
+
{
|
767
|
+
if (have_ab) dl_blob.append(dl_plainq[dl_write_position]);
|
768
|
+
else dl_blob.append(dl_plainq[dl_write_position].buffer);
|
769
|
+
}
|
770
|
+
}
|
771
|
+
|
772
|
+
function dl_cancel()
|
773
|
+
{
|
774
|
+
dl_settimer(-1);
|
775
|
+
dl_instance++;
|
776
|
+
dl_xhrs = dl_pos = dl_workers = dl_progress = dl_cipherq = dl_plainq = dl_progress = dl_chunks = dl_chunksizes = undefined;
|
777
|
+
downloading = false;
|
778
|
+
}
|
779
|
+
|
780
|
+
if (window.webkitRequestFileSystem)
|
781
|
+
{
|
782
|
+
function errorHandler(e) {
|
783
|
+
var msg = '';
|
784
|
+
|
785
|
+
switch (e.code) {
|
786
|
+
case FileError.QUOTA_EXCEEDED_ERR:
|
787
|
+
msg = 'QUOTA_EXCEEDED_ERR';
|
788
|
+
break;
|
789
|
+
case FileError.NOT_FOUND_ERR:
|
790
|
+
msg = 'NOT_FOUND_ERR';
|
791
|
+
break;
|
792
|
+
case FileError.SECURITY_ERR:
|
793
|
+
msg = 'SECURITY_ERR';
|
794
|
+
break;
|
795
|
+
case FileError.INVALID_MODIFICATION_ERR:
|
796
|
+
msg = 'INVALID_MODIFICATION_ERR';
|
797
|
+
break;
|
798
|
+
case FileError.INVALID_STATE_ERR:
|
799
|
+
msg = 'INVALID_STATE_ERR';
|
800
|
+
break;
|
801
|
+
default:
|
802
|
+
msg = 'Unknown Error';
|
803
|
+
break;
|
804
|
+
};
|
805
|
+
|
806
|
+
if (d) console.log('Error: ' + msg);
|
807
|
+
}
|
808
|
+
|
809
|
+
window.webkitStorageInfo.requestQuota(TEMPORARY , 1024*1024*1024*10, function(grantedBytes)
|
810
|
+
{
|
811
|
+
console.log('Storage space granted successfully');
|
812
|
+
}, function(e)
|
813
|
+
{
|
814
|
+
console.log('Error', e);
|
815
|
+
});
|
816
|
+
|
817
|
+
var dirid = "mega";
|
818
|
+
|
819
|
+
function dl_createtmp()
|
820
|
+
{
|
821
|
+
window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024*1024*10, dl_createtmpfile, errorHandler);
|
822
|
+
}
|
823
|
+
|
824
|
+
function dl_createtmpfile(fs)
|
825
|
+
{
|
826
|
+
document.fs = fs;
|
827
|
+
|
828
|
+
document.fs.root.getDirectory(dirid, {create: true}, function(dirEntry)
|
829
|
+
{
|
830
|
+
if (d) console.log('Directory "'+dirid+'" created')
|
831
|
+
document.dirEntry = dirEntry;
|
832
|
+
}, errorHandler);
|
833
|
+
|
834
|
+
if (d) console.log("Opening file for writing: " + dl_id);
|
835
|
+
fs.root.getFile(dirid + '/' + dl_id, {create: true}, function(fileEntry)
|
836
|
+
{
|
837
|
+
fileEntry.createWriter(function(fileWriter)
|
838
|
+
{
|
839
|
+
if (d) console.log('File "' + dirid + '/' + dl_id + '" created');
|
840
|
+
|
841
|
+
fileWriter.onerror = function(e)
|
842
|
+
{
|
843
|
+
if (d) console.log('Write failed: ' + e.toString());
|
844
|
+
};
|
845
|
+
|
846
|
+
document.fileWriter = fileWriter;
|
847
|
+
document.fileEntry = fileEntry;
|
848
|
+
|
849
|
+
dl_run();
|
850
|
+
}, errorHandler);
|
851
|
+
}, errorHandler);
|
852
|
+
}
|
853
|
+
|
854
|
+
dl_method = 0;
|
855
|
+
}
|
856
|
+
else if (navigator.msSaveOrOpenBlob)
|
857
|
+
{
|
858
|
+
dl_method = 2;
|
859
|
+
}
|
860
|
+
else
|
861
|
+
{
|
862
|
+
// Flash fallback
|
863
|
+
dl_method = 1;
|
864
|
+
}
|
865
|
+
|
866
|
+
|
867
|
+
|